Wie die Blöcke und Versuche gespeichert werden

Neuling hier!

Ich bin mir immer noch nicht sicher, ob ich verstanden habe, wie einige Strukturen von Ethereum physisch gespeichert werden (unter der Annahme einer Geth-Implementierung).

  • State Trie: nur ein Off-Chain-Merkle-Patricia-Tries, der mit LevelDB gespeichert wird;

  • Storage Trie: ein Merkle Patricia Trie pro Account; Off-Chain zusammen mit dem State Trie unter Verwendung von LevelDB gespeichert;

  • Transaktionsversuche: nicht wirklich physisch gespeichert; ein Merkle Patricia Trie wird bei Bedarf unter Verwendung der Blocktransaktionsliste im laufenden Betrieb erstellt;

  • Quittungen Trie: keine Ahnung;

  • Blöcke: Zustandsversuche und Speicherversuche werden in .ldb-Dateien (LevelDB) gespeichert, aber wo finde ich die Blockdateien und in welchem ​​Format werden sie gespeichert?

Antworten (1)

Low-Level-Geth-Datenbankformat ist:

var databaseVerisionKey = new Buffer("DatabaseVersion"); // databaseVerisionKey tracks the current database version.
var headHeaderKey = new Buffer("LastHeader"); // headHeaderKey tracks the latest know header's hash.
var headBlockKey = new Buffer("LastBlock"); // headBlockKey tracks the latest know full block's hash.
var headFastBlockKey = new Buffer("LastFast"); // headFastBlockKey tracks the latest known incomplete block's hash duirng fast sync.
var fastTrieProgressKey = new Buffer("TrieSync"); // fastTrieProgressKey tracks the number of trie entries imported during fast sync.

// Data item prefixes (use single byte to avoid mixing data types, avoid `i`, used for indexes).
var headerPrefix = new Buffer("h"); // headerPrefix + num (uint64 big endian) + hash -> header
var headerTDSuffix = new Buffer("t"); // headerPrefix + num (uint64 big endian) + hash + headerTDSuffix -> td
var headerHashSuffix = new Buffer("n"); // headerPrefix + num (uint64 big endian) + headerHashSuffix -> hash
var headerNumberPrefix = new Buffer("H"); // headerNumberPrefix + hash -> num (uint64 big endian)
var blockBodyPrefix = new Buffer("b"); // blockBodyPrefix + num (uint64 big endian) + hash -> block body
var blockReceiptsPrefix = new Buffer("r"); // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts
var txLookupPrefix = new Buffer("l"); // txLookupPrefix + hash -> transaction/receipt lookup metadata
var bloomBitsPrefix = new Buffer("B"); // bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -> bloom bits
var preimagePrefix = new Buffer("secure-key-");      // preimagePrefix + hash -> preimage
var configPrefix = new Buffer("ethereum-config-"); // config prefix for the db
var BloomBitsIndexPrefix = new Buffer("iB"); // BloomBitsIndexPrefix is the data table of a chain indexer to track its progress // Chain index prefixes (use `i` + single byte to avoid mixing data types).

Um Daten zu erhalten, müssen Sie rekursiv Bäume aus diesen Daten erstellen. Wenn Sie den Hash der Zustandswurzel kennen, können Sie die Zustandswurzel finden, und dann kennen Sie die Hashes der Kinder der Zustandswurzel, also kennen Sie die Kinder, damit Sie zu den Blättern gelangen können.

Abhängig von der Geth-Option --gcmode archive|fast|light(Sie können auch angeben, wie viele Blöcke Sie sich merken möchten), speichert Geth oder unternimmt einige Versuche.

Verschiedene Versuche sind World State Tree (Links zu Konten), Speicherversuche (Kontodaten) und Empfangsversuche (für Transaktionsbelege).

Um den Wert "Beispielwert" aus dem Baum (z. B. Vertragsadresse) zu erhalten. Sie müssen 32 Längen im Baum nach unten gehen, abhängig von der Länge von 32 Zeichen sha3 ("Beispielwert").

Um besser zu verstehen, welche Daten in db gespeichert sind und wie versucht wird, schauen Sie sich diese Bilder an:

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Interessant, aber für mich immer noch nicht klar, ob Transaktionsversuche bestehen bleiben oder bei Bedarf spontan erstellt werden. Auch wo die Receipts Tries Daten gespeichert werden? Sind sie in der LevelDB gespeichert? Werden sie in den Blöcken gespeichert? Werden die Blöcke auch in LevelDB gespeichert? Wenn nicht, wo finde ich die Dateien?
Versuche werden in db im Format von Trie-Knoten gespeichert. Wenn Geth einen Versuch verwenden muss, baut es ihn rekursiv auf und speichert ihn im RAM-Cache, bis Sie Geth ausschalten. Zum Beispiel beim Anfordern von Daten von Geth mit der Web3-API. Transaktionen werden auch im Array-Format im Blockkörper gespeichert. Im Transaktionsfall müssen Sie also keinen Baum erstellen, um tx des angegebenen Blocks zu erhalten. Alles, was auf dem Bild gezeigt wird, ist in LevelDB. Wenn der Archivmodus aktiviert ist. Die zusammenfassende Antwort lautet also: Bei Bedarf im laufenden Betrieb erstellt und im RAM zwischengespeichert, ja, ja, ja (zeigt per Hash darauf), ja.
Ok, und was ist, wenn der State Trie aktualisiert wird ... werden die Knotenwerte überschrieben oder neue Knoten mit den neuen Werten gespeichert?
Zwei unterschiedliche Daten, die denselben Hash ergeben, haben eine so geringe Wahrscheinlichkeit, dass Geth davon ausgeht, dass dies nie passiert. So können verschiedene Weltstaaten im selben Format in einer Datenbank koegsieren, da Knoten durch ihren Hash referenziert werden. Gemeinsame Knoten werden natürlich eindeutig gespeichert.
@EtherswornCanonist, LevelDB ist eine Schlüssel->Wert-Paar-Datenbank. Alles wird als hashdie gespeichert keyund die entsprechende Datenstruktur ist die value. Warum müssten Sie sich in die Struktur der Datenbank einarbeiten, verwenden Sie einfach die Funktionen, die Ethereum hat, um die Daten zu erhalten, die Sie benötigen.