Format der LevelDB-Dateien im Knotenverzeichnis? Probleme beim Abrufen von Inhalten mit der Python-Leveldb-API

Ich bin daran interessiert, die Daten in zu untersuchen ~/.ethereum/nodes, von denen ich glaube, dass sie frühere Verbindungsversuche und Informationen über die Knoten enthalten. (Ist das richtig?) Aber ich stecke fest und versuche, die Daten aus dieser Datenbank zu ziehen.

Hier mein bisheriger Versuch:

import leveldb

db = leveldb.LevelDB("./nodes")
# I don't know the format so I will iterate a few keys
keys = list()
for k in db.RangeIter():
    if len(keys) > 10:
        break
    keys.append(k)

print(keys[0][0])

Was mir ein Byte-Array gibt, mit dem ich nicht weiß, was ich damit anfangen soll:

>>> bytearray(b'n:\x00\x00\x07\xf2\x91\xff\xcd\xba%\x8f%\xf8b\xfe\x1b3\xda\x10\xfa,\xb7>\x93\x82_X\r5\xdfG\xae\x8b\xd6-\x9d6\rB\x84$\xb8+\x07\x18<\x8d\xed\xca\x93\xa4\x0bt\x84\xa7\x14\xaf\xc8B\x1a\xb3\xb7(K\x00:discover:lastping')

Tut mir leid, wenn dies eher eine Python- als eine Ethereum-Frage ist, aber ich vermute, dass es hilfreich wäre, die Struktur der Daten zu kennen, und ich kann sie anscheinend nirgendwo finden.

UPDATE: Ich sollte klarstellen, womit ich arbeite:

keys[0]ist ein Eintrag in der nodesDatenbank und ist ein Tupel:

( bytearray(b'n:\x00\x00\x07\xf2\x91\xff\xcd\xba%\x8f%\xf8b\xfe\x1b3\xda\x10\xfa,\xb7>\x93\x82_X\r5\xdfG\xae\x8b\xd6-\x9d6\rB\x84$\xb8+\x07\x18<\x8d\xed\xca\x93\xa4\x0bt\x84\xa7\x14\xaf\xc8B\x1a\xb3\xb7(K\x00:discover:lastping'), bytearray(b'\x90\xa7\xae\xef\n') )

Wobei der erste Gegenstand der Schlüssel ist. Die Ausführung rlp.decodeauf einem der beiden Elemente gibt einen Fehler zurück:

import rlp

rlp.decode(bytes(keys[0][0]))
>>> DecodingError: RLP string ends with 83 superfluous bytes

rlp.decode(bytes(keys[0][1]))
>>> DecodingError: RLP string ends with -12 superfluous bytes

Ich bin sehr verwirrt, weil es so aussieht, als würde es von Geth RLP codiert werden, also verstehe ich nicht, warum es nicht decodiert werden kann.

Antworten (1)

Der Inhalt der Datenbank ist blobifiziert, also müssen Sie ihn de-blobbifizieren, um etwas Menschenlesbares zu erhalten.

Das Layout finden Sie unter database.go:

// Schema layout for the node database
var (
    nodeDBVersionKey = []byte("version") // Version of the database to flush if changes
    nodeDBItemPrefix = []byte("n:")      // Identifier to prefix node entries with

    nodeDBDiscoverRoot      = ":discover"
    nodeDBDiscoverPing      = nodeDBDiscoverRoot + ":lastping"
    nodeDBDiscoverPong      = nodeDBDiscoverRoot + ":lastpong"
    nodeDBDiscoverFindFails = nodeDBDiscoverRoot + ":findfail"
)

Wenn Sie diese Datei durchsehen, sehen Sie das RLP -Paket (Recursive length prefix), das für die Codierung/Decodierung verwendet wird, dessen Python-Version hier zu finden ist .

Danke für den Hinweis. Ich habe immer noch Probleme, den Index zu "de-blobbifizieren": rlp.decode(b'\x90\xa7\xae\xef\n')-->DecodingError: RLP string ends with -12 superfluous bytes.
Hmm, es ist möglich, dass Sie der Dekodierungsfunktion als zweites (De-) Serialisierungsargument übergeben müssen, damit sie weiß, um welchen Typ es sich handelt. (So ​​scheint es der Go-Code zu tun.) Sehen Sie sich "Sedes-Objekte" in der Python-Dokumentation an: github.com/ethereum/pyrlp/blob/develop/docs/tutorial.rst
Diese Prüfung kommt eigentlich vor der Sedes-Prüfung: github.com/ethereum/pyrlp/blob/develop/rlp/codec.py#L211