从LevelDB数据库获取所有密钥

时间:2013-06-10 14:35:49

标签: haskell leveldb

我正在编写一个脚本来收集所有比特币块的哈希值。程序bitcoind,如果更改某个设置,则存储LevelDB数据库中所有块的元数据。每组元数据的关键是块的散列,它通常用作它的标识符。本质上,我试图从每个块中获取元数据的特定部分(事务ID)。我正在写的脚本是在Haskell中,尽管我可以在必要时总是执行shell命令。总而言之,我不确定最简单的方法是找到所有块哈希(键),然后调用bitcoind来获取每个块的元数据。如果有任何方法可以直接从LevelDB数据库中获取每个值,那么也可以。什么是最简单有效的方法?

1 个答案:

答案 0 :(得分:4)

我不知道如何用haskell完成这项工作,但使用C ++最有效的方法是使用leveldb :: Iterator和iterate over the entire key range

0x00000000 -> 0xFFFFFFFF(32位密钥)
0x0000000000000000 -> 0xFFFFFFFFFFFFFFFF(64位密钥)

来自the example

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

The example表示当您迭代键并且可以加载值时:

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

由于您不关心该值,您可以跳过查询it->value()的部分,只需收集所需的密钥(在这种情况下全部都是这些),您应该很好。我不担心不必要地加载值的性能损失。

然而,这里需要注意的一件大事:比特币运行时你不能这样做!!!

之所以如此,是因为在任何给定时间只能打开一个级别DB的实例,并且bitcoind很可能已经将db实例打开,试图打开另一个实例(即使只是为了阅读)会导致错误。您可以获取数据库和iterate the snapshots tho的快照。快照允许您保证比特币的最小停机时间。

最后,如果您无法承担bitcoind客户端的任何停机时间,那么您可能需要在bitcoind或leveldb周围编写一个包装器。你必须在某处引入一定程度的抽象。

bitcoind周围的包装:

  1. 在制作快照时关闭比特币。
  2. 在完成快照之前,暂停任何比特请求。
  3. 再次开始比特币。
  4. leveldb周围的包装:

    db级别的包装器有点困难,你必须保持对数据库实例的控制,你必须实际进入并修改bitcoind代码,然后构建bitcoind并运行它。

相关问题