Получить все ключи из базы данных LevelDB

Я пишу скрипт для сбора хэшей всех блоков биткойнов. Программа bitcoind при изменении определенной настройки сохраняет метаданные для всех блоков в базе данных LevelDB. Ключом каждого набора метаданных является хэш блока, который обычно используется в качестве его идентификатора. По сути, я пытаюсь получить определенную часть метаданных (идентификаторы транзакций) из каждого блока. Сценарий, который я пишу, написан на Haskell, хотя при необходимости я всегда могу выполнить команду оболочки. Говоря в общих чертах, я не уверен, что самый простой способ сделать это — найти все хэши (ключи) блоков, а затем вызвать биткойн, чтобы получить метаданные для каждого из них. Если есть способ просто получить каждое значение из базы данных LevelDB напрямую, это тоже сработает. Какой самый простой и эффективный способ сделать это?


person Mike    schedule 10.06.2013    source источник


Ответы (1)


Я точно не знаю, как это можно сделать с помощью haskell, но наиболее эффективный способ сделать это с помощью C++ — использовать leveldb::Iterator и перебрать весь диапазон ключей:

0x00000000 -> 0xFFFFFFFF (32-битные ключи)
0x0000000000000000 -> 0xFFFFFFFFFFFFFFFF (64-битные ключи)

Из примера:

leveldb::Slice start = ...; // 0x00000000
leveldb::Slice end = ...; // 0xFFFFFFFFFFFFFFFF

Пример показывает, что при повторении ключей и значения могут быть загружены:

leveldb::Slice key = it->key();
leveldb::Slice value = it->value();

Поскольку вас не волнует значение, вы можете просто пропустить часть, где вы запрашиваете it->value(), просто соберите нужные вам ключи (в данном случае все), и все будет хорошо. Я бы не стал беспокоиться о снижении производительности из-за ненужной загрузки значений.

Однако здесь следует отметить одну важную вещь: вы не можете делать это во время работы bitcoind!!!

Причина, по которой это так, заключается в том, что в любой момент времени может быть открыт только один активный экземпляр уровня БД, и биткойн, скорее всего, уже держит экземпляр БД открытым, попытка открыть другой экземпляр (даже просто для чтения) приведет к ошибка. Вы можете получить снимки базы данных и итерировать снимки. Снапшот позволяет гарантировать минимальное время простоя bitcoind.

Наконец, если вы не можете позволить себе простои вашего клиента bitcoind, вам может понадобиться написать оболочку для bitcoind или leveldb. Вам нужно будет где-то ввести уровень абстракции.

Обертка вокруг bitcoind:

  1. Отключает биткойн, пока вы делаете снимок.
  2. Буферизирует любые запросы к bitcoind, пока вы не закончите со снимком.
  3. Запускает биткойн снова.

Обертка для leveldb:

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

person Kiril    schedule 10.06.2013