すべてのビットコイン ブロックのハッシュを収集するスクリプトを作成しています。プログラム bitcoind は、特定の設定が変更された場合、すべてのブロックのメタデータを LevelDB データベースに保存します。メタデータの各セットのキーはブロックのハッシュであり、通常はブロックの識別子として使用されます。基本的に、各ブロックからメタデータ (トランザクション ID) の特定の部分を取得しようとしています。私が書いているスクリプトは Haskell ですが、必要に応じていつでもシェル コマンドを実行できます。私の問題を大まかに言えば、これを行う最も簡単な方法が、すべてのブロック ハッシュ (キー) を見つけてから、bitcoind を呼び出してそれぞれのメタデータを取得することかどうかはわかりません。LevelDB データベースからすべての値を直接取得する方法があれば、それも同様に機能します。これを行う最も簡単で効率的な方法は何ですか?
2 に答える
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()
必要なキー (この場合はすべて) を収集するだけで問題ありません。不必要に値をロードすることによるパフォーマンスへの影響については心配しません。
ただし、ここで注意すべき重要な点が 1 つあります。ビットコインの実行中はこれを行うことはできません!!!
これが当てはまる理由は、ある時点で開かれているレベル DB のライブ インスタンスは 1 つだけであり、bitcoind はすでに db インスタンスを開いたままにしている可能性が高く、別のインスタンスを開こうとすると (読み取りのためであっても)、エラー。データベースのスナップショットを取得し、スナップショットを繰り返すことができます。スナップショットを使用すると、ビットコインのダウンタイムを最小限に抑えることができます。
最後に、bitcoind クライアントのダウンタイムを許容できない場合は、bitcoind または leveldb のいずれかにラッパーを記述する必要があるかもしれません。どこかに抽象化のレベルを導入する必要があります。
ビットコインのラッパー:
- スナップショットの作成中にビットコインをシャットダウンします。
- スナップショットが完了するまで、bitcoind へのリクエストをバッファリングします。
- ビットコインを再開します。
leveldb のラッパー:
レベル db のラッパーはもう少し難しく、データベース インスタンスの制御を維持する必要があり、実際に行って bitcoind コードを変更し、bitcoind をビルドして実行する必要があります。