Как хранятся блоки и попытки

Новичок здесь!

Я до сих пор не уверен, понял ли я, как физически хранятся некоторые структуры Ethereum (при условии реализации Geth)

  • State Trie: только одна попытка Merkle Patricia вне сети хранится с использованием LevelDB;

  • Trie Storage: одна Trie Merkle Patricia Trie на учетную запись; хранится вне сети вместе с State Trie с использованием LevelDB;

  • Попытки транзакций: физически не сохраняются; Merkle Patricia Trie создается «на лету», когда это необходимо, с использованием списка блочных транзакций;

  • Квитанции Трие: не знаю;

  • Блоки: дерево состояний и попытки хранения хранятся в файлах .ldb (LevelDB), но где я могу найти файлы блоков и в каком формате они хранятся?

Ответы (1)

Формат базы данных geth низкого уровня:

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).

Чтобы получить данные, вы должны рекурсивно построить дерево из этих данных. Зная хэш корня состояния, вы можете найти корень состояния, а затем вы знаете хэши дочерних элементов корня состояния, поэтому вы знаете дочерние элементы, чтобы вы могли добраться до листьев.

В зависимости от опции geth --gcmode archive|fast|light(вы также можете указать, сколько блоков вы хотите запомнить), geth сохраняет или не сохраняет некоторые попытки.

Различными попытками являются мировое дерево состояний (ссылки на учетные записи), попытки хранения (данные учетных записей) и попытки получения (для получения транзакций).

Чтобы получить значение «образец значения» из дерева (например, адрес контракта). Вам нужно пройти 32 длины вниз по дереву в зависимости от длины 32 символов sha3 («выборочное значение»).

Чтобы лучше понять, какие данные хранятся в БД и как делаются попытки, посмотрите на эти изображения:

введите описание изображения здесь

введите описание изображения здесь

Интересно, но для меня все еще не ясно, сохраняются ли попытки транзакций или они создаются на лету, когда это необходимо. Также, где хранятся данные о попытках получения? Хранятся ли они в LevelDB? Они хранятся внутри блоков? Блоки тоже хранятся в LevelDB? Если нет, то где я могу найти файлы?
Попытки хранятся в БД в формате узлов дерева. Когда Geth нужно использовать trie, он создает его рекурсивно и сохраняет в кэше оперативной памяти, пока вы не выключите geth. Например, при запросе данных от geth с помощью web3 api. Транзакции также хранятся в формате массива в теле блока. Таким образом, в случае транзакции вам не нужно строить дерево, чтобы получить tx указанного блока. Все, что показано на картинке, находится в LevelDB. Если режим архива включен. Итак, резюмирующий ответ: создается на лету, когда это необходимо, и кэшируется в оперативной памяти, да, да, да (указывает на это хэшем), да.
Хорошо, а как насчет обновления State Trie... переопределяются ли значения узлов или новые узлы сохраняются с новыми значениями?
Вероятность двух разных данных, дающих одинаковые хэши, настолько мала, что geth предполагает, что этого никогда не происходит. Таким образом, разные состояния мира могут сосуществовать в одном и том же формате в одном db, потому что узлы ссылаются на их хэш. Общие узлы хранятся, конечно, уникально.
@EtherswornCanonist, LevelDB — это база данных с парами ключ-> значение. Все хранится как hash, keyа соответствующая структура данных - как value. Вот и все. Зачем вам копаться в структуре базы данных, просто используйте функции эфириума, чтобы получить нужные вам данные.