Каковы ключи, используемые в блочном блоке DB (то есть, какие пары ключ: значение)?

Мне интересно, могу ли я использовать node.js и levelup для непосредственного доступа к копии базы данных blockchain.

Но из того, что я вижу, мне нужно знать имя ключа (ов), прежде чем я смогу получить какие-либо данные, поскольку это используется в методе get levelup.

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

Во-первых, каковы ключи в парах значений ключа, а во-вторых, возможно ли просто выбрать первые записи n?

32 голоса | спросил T9b 27 J0000006Europe/Moscow 2014, 03:04:11

2 ответа


41

Bitcoind с 0.8 поддерживает две базы данных, индекс блока (в $ DATADIR /blocks /index) и цепочку состояний (в $ DATADIR /chainstate). Индекс блока поддерживает информацию для каждого блока и где он хранится на диске. Состояние цепи поддерживает информацию о результирующем состоянии проверки в результате известной в настоящее время цепи.

Внутри индексного блока используются пары ключ /значение:

  • 'b' + 32-байтовый блочный хэш -> запись индекса блока. В каждом магазине записей:
    • Заголовок блока.
    • Высота.
    • Количество транзакций.
    • В какой степени этот блок проверен.
    • В каком файле и где в этом файле хранятся данные блока.
    • В каком файле и где в этом файле хранятся данные отмены.
  • 'f' + 4-байтовый номер файла -> запись информации о файле. Каждая запись хранит:
    • Количество блоков, хранящихся в блочном файле с этим номером.
    • Размер файла блока с этим номером ($ DATADIR /blocks /blkNNNNN.dat).
    • Размер файла отмены с этим номером ($ DATADIR /blocks /revNNNNN.dat).
    • Самая низкая и самая высокая высота блоков, хранящихся в блочном файле с этим номером.
    • Самая низкая и самая высокая отметка времени, хранящаяся в блочном файле с этим номером.
  • 'l' -> 4-байтовый номер файла: последний номер файла блока.
  • 'R' -> 1-байтовый логический ('1', если true): мы находимся в процессе переиндексации.
  • 'F' + 1-байтовая длина имени флага + строка имени флага -> 1 байт boolean ('1', если true, '0', если false): различные флаги, которые могут быть включены или выключены. Определенные флаги включают:
    • 'txindex': включен ли индекс транзакции.
  • 't' + 32-байтовый хэш транзакций -> запись индекса транзакции. Они являются необязательными и существуют только в том случае, если включен «txindex» (см. Выше). Каждая запись хранит:
    • Какой номер файла блока хранится в транзакции.
    • Какое смещение в этот файл хранится в блоке, в котором транзакция является частью.
    • Смещение от начала этого блока до положения, в котором хранится эта транзакция.

Внутри базы данных состояния цепочки сохраняются следующие пары ключ /значение:

  • 'c' + 32-байтовый хэш транзакции -> запись неизмененной транзакции для этой транзакции. Эти записи присутствуют только для транзакций, у которых есть хотя бы один неизрасходованный результат. Каждая запись хранится:
    • Версия транзакции.
    • Является ли транзакция коинбазой или нет.
    • Какой блок высоты содержит транзакцию.
    • Какие выходные данные этой транзакции неизрасходованы.
    • ScriptPubKey и сумма для тех неизрасходованных выходов.
  • 'B' -> 32-байтовый хеш-блок: хэш-код блока, до которого база данных представляет неизрасходованные транзакционные выходы.

Последняя версия bitcoind (добавьте совместимость версий) использует obfuscation значение в паре ключей /значений. Поэтому вам нужно XOR с ключом обфускации, чтобы получить реальную ценность.

Я не буду вдаваться в конкретные сведения о сериализации конкретных записей. Они часто специально предназначены для компактности на диске и не предназначены для использования в других приложениях (LevelDB не поддерживает одновременный доступ из нескольких приложений). Существует несколько методов RPC для запроса данных из баз данных (getblock, gettxoutsetinfo, gettxout) без прямого доступа.

Как вы можете видеть, в этой базе данных хранятся только заголовки. Фактические блоки и транзакции хранятся в блочных файлах, которые не являются базами данных, а просто сырые файлы только для приложений, которые содержат блоки в сетевом формате.

Что касается вашего второго вопроса: что такое n? Если вы просто хотите получить доступ к некоторым записям, убедитесь, что они перебирают ключи и останавливаются, когда вы достаточно читаете.

ответил Pieter Wuille 11 J000000Friday14 2014, 00:08:19
3

ОК. Я знаю, что не должен отвечать на свой вопрос, но ... в отсутствие ответа на этот вопрос я немного охотился.

Github предоставил ответ в файле, найденном в репозитории bitcoin-leveldb .

Путь к текстовому файлу, содержащему информацию leveldb->doc->table_format.txt

Короче говоря, нет такой легко описываемой таблицы, как структура. Есть несколько, я бы назвал их «вложенными» структурами в базе данных, включая тот факт, что база данных физически хранит данные в отдельных логических файлах.

Вот содержимое этого файла table_format.txt на этом посту.

Формат файла

  <beginning_of_file>
  [data block 1]
  [data block 2]
  ...
  [data block N]
  [meta block 1]
  ...
  [meta block K]
  [metaindex block]
  [index block]
  [Footer]        (fixed size; starts at file_size - sizeof(Footer))
  <end_of_file>

The file contains internal pointers.  Each such pointer is called
a BlockHandle and contains the following information:
  offset:       varint64
  size:         varint64
See https://developers.google.com/protocol-buffers/docs/encoding#varints
for an explanation of varint64 format.

(1) The sequence of key/value pairs in the file are stored in sorted
order and partitioned into a sequence of data blocks.  These blocks
come one after another at the beginning of the file.  Each data block
is formatted according to the code in block_builder.cc, and then
optionally compressed.

(2) After the data blocks we store a bunch of meta blocks.  The
supported meta block types are described below.  More meta block types
may be added in the future.  Each meta block is again formatted using
block_builder.cc and then optionally compressed.

(3) A "metaindex" block.  It contains one entry for every other meta
block where the key is the name of the meta block and the value is a
BlockHandle pointing to that meta block.

(4) An "index" block.  This block contains one entry per data block,
where the key is a string >= last key in that data block and before
the first key in the successive data block.  The value is the
BlockHandle for the data block.

(6) At the very end of the file is a fixed length footer that contains
the BlockHandle of the metaindex and index blocks as well as a magic number.
       metaindex_handle: char[p];    // Block handle for metaindex
       index_handle:     char[q];    // Block handle for index
       padding:          char[40-p-q]; // zeroed bytes to make fixed length
                                       // (40==2*BlockHandle::kMaxEncodedLength)
       magic:            fixed64;    // == 0xdb4775248b80fb57 (little-endian)

"фильтр" Мета-блок

If a "FilterPolicy" was specified when the database was opened, a
filter block is stored in each table.  The "metaindex" block contains
an entry that maps from "filter.<N>" to the BlockHandle for the filter
block where "<N>" is the string returned by the filter policy's
"Name()" method.

The filter block stores a sequence of filters, where filter i contains
the output of FilterPolicy::CreateFilter() on all keys that are stored
in a block whose file offset falls within the range

    [ i*base ... (i+1)*base-1 ]

Currently, "base" is 2KB.  So for example, if blocks X and Y start in
the range [ 0KB .. 2KB-1 ], all of the keys in X and Y will be
converted to a filter by calling FilterPolicy::CreateFilter(), and the
resulting filter will be stored as the first filter in the filter
block.

The filter block is formatted as follows:

     [filter 0]
     [filter 1]
     [filter 2]
     ...
     [filter N-1]

     [offset of filter 0]                  : 4 bytes
     [offset of filter 1]                  : 4 bytes
     [offset of filter 2]                  : 4 bytes
     ...
     [offset of filter N-1]                : 4 bytes

     [offset of beginning of offset array] : 4 bytes
     lg(base)                              : 1 byte

The offset array at the end of the filter block allows efficient
mapping from a data block offset to the corresponding filter.

"статистика" Мета-блок

This meta block contains a bunch of stats.  The key is the name
of the statistic.  The value contains the statistic.
TODO(postrelease): record following stats.
  data size
  index size
  key size (uncompressed)
  value size (uncompressed)
  number of entries
  number of data blocks
ответил T9b 9 J000000Wednesday14 2014, 01:32:29

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132