1111#include < flatfile.h>
1212#include < hash.h>
1313#include < index/base.h>
14+ #include < index/db_key.h>
1415#include < interfaces/chain.h>
1516#include < interfaces/types.h>
1617#include < logging.h>
2526
2627#include < cerrno>
2728#include < exception>
28- #include < ios>
2929#include < map>
3030#include < optional>
3131#include < span>
4646 * disk location of the next block filter to be written (represented as a FlatFilePos) is stored
4747 * under the DB_FILTER_POS key.
4848 *
49- * Keys for the height index have the type [DB_BLOCK_HEIGHT, uint32 (BE)]. The height is represented
50- * as big-endian so that sequential reads of filters by height are fast.
51- * Keys for the hash index have the type [DB_BLOCK_HASH, uint256].
49+ * The logic for keys is shared with other indexes, see index/db_key.h.
5250 */
53- constexpr uint8_t DB_BLOCK_HASH{' s' };
54- constexpr uint8_t DB_BLOCK_HEIGHT{' t' };
5551constexpr uint8_t DB_FILTER_POS{' P' };
5652
5753constexpr unsigned int MAX_FLTR_FILE_SIZE = 0x1000000 ; // 16 MiB
@@ -74,45 +70,6 @@ struct DBVal {
7470 SERIALIZE_METHODS (DBVal, obj) { READWRITE (obj.hash , obj.header , obj.pos ); }
7571};
7672
77- struct DBHeightKey {
78- int height;
79-
80- explicit DBHeightKey (int height_in) : height(height_in) {}
81-
82- template <typename Stream>
83- void Serialize (Stream& s) const
84- {
85- ser_writedata8 (s, DB_BLOCK_HEIGHT);
86- ser_writedata32be (s, height);
87- }
88-
89- template <typename Stream>
90- void Unserialize (Stream& s)
91- {
92- const uint8_t prefix{ser_readdata8 (s)};
93- if (prefix != DB_BLOCK_HEIGHT) {
94- throw std::ios_base::failure (" Invalid format for block filter index DB height key" );
95- }
96- height = ser_readdata32be (s);
97- }
98- };
99-
100- struct DBHashKey {
101- uint256 hash;
102-
103- explicit DBHashKey (const uint256& hash_in) : hash(hash_in) {}
104-
105- SERIALIZE_METHODS (DBHashKey, obj) {
106- uint8_t prefix{DB_BLOCK_HASH};
107- READWRITE (prefix);
108- if (prefix != DB_BLOCK_HASH) {
109- throw std::ios_base::failure (" Invalid format for block filter index DB hash key" );
110- }
111-
112- READWRITE (obj.hash );
113- }
114- };
115-
11673}; // namespace
11774
11875static std::map<BlockFilterType, BlockFilterIndex> g_filter_indexes;
@@ -278,7 +235,7 @@ size_t BlockFilterIndex::WriteFilterToDisk(FlatFilePos& pos, const BlockFilter&
278235std::optional<uint256> BlockFilterIndex::ReadFilterHeader (int height, const uint256& expected_block_hash)
279236{
280237 std::pair<uint256, DBVal> read_out;
281- if (!m_db->Read (DBHeightKey (height), read_out)) {
238+ if (!m_db->Read (index_util:: DBHeightKey (height), read_out)) {
282239 return std::nullopt ;
283240 }
284241
@@ -311,35 +268,12 @@ bool BlockFilterIndex::Write(const BlockFilter& filter, uint32_t block_height, c
311268 value.second .header = filter_header;
312269 value.second .pos = m_next_filter_pos;
313270
314- m_db->Write (DBHeightKey (block_height), value);
271+ m_db->Write (index_util:: DBHeightKey (block_height), value);
315272
316273 m_next_filter_pos.nPos += bytes_written;
317274 return true ;
318275}
319276
320- [[nodiscard]] static bool CopyHeightIndexToHashIndex (CDBIterator& db_it, CDBBatch& batch,
321- const std::string& index_name, int height)
322- {
323- DBHeightKey key (height);
324- db_it.Seek (key);
325-
326- if (!db_it.GetKey (key) || key.height != height) {
327- LogError (" unexpected key in %s: expected (%c, %d)" ,
328- index_name, DB_BLOCK_HEIGHT, height);
329- return false ;
330- }
331-
332- std::pair<uint256, DBVal> value;
333- if (!db_it.GetValue (value)) {
334- LogError (" unable to read value in %s at key (%c, %d)" ,
335- index_name, DB_BLOCK_HEIGHT, height);
336- return false ;
337- }
338-
339- batch.Write (DBHashKey (value.first ), std::move (value.second ));
340- return true ;
341- }
342-
343277bool BlockFilterIndex::CustomRemove (const interfaces::BlockInfo& block)
344278{
345279 CDBBatch batch (*m_db);
@@ -348,7 +282,7 @@ bool BlockFilterIndex::CustomRemove(const interfaces::BlockInfo& block)
348282 // During a reorg, we need to copy block filter that is getting disconnected from the
349283 // height index to the hash index so we can still find it when the height index entry
350284 // is overwritten.
351- if (!CopyHeightIndexToHashIndex (*db_it, batch, m_name, block.height )) {
285+ if (!index_util:: CopyHeightIndexToHashIndex<DBVal> (*db_it, batch, m_name, block.height )) {
352286 return false ;
353287 }
354288
@@ -363,24 +297,6 @@ bool BlockFilterIndex::CustomRemove(const interfaces::BlockInfo& block)
363297 return true ;
364298}
365299
366- static bool LookupOne (const CDBWrapper& db, const CBlockIndex* block_index, DBVal& result)
367- {
368- // First check if the result is stored under the height index and the value there matches the
369- // block hash. This should be the case if the block is on the active chain.
370- std::pair<uint256, DBVal> read_out;
371- if (!db.Read (DBHeightKey (block_index->nHeight ), read_out)) {
372- return false ;
373- }
374- if (read_out.first == block_index->GetBlockHash ()) {
375- result = std::move (read_out.second );
376- return true ;
377- }
378-
379- // If value at the height index corresponds to an different block, the result will be stored in
380- // the hash index.
381- return db.Read (DBHashKey (block_index->GetBlockHash ()), result);
382- }
383-
384300static bool LookupRange (CDBWrapper& db, const std::string& index_name, int start_height,
385301 const CBlockIndex* stop_index, std::vector<DBVal>& results)
386302{
@@ -397,9 +313,9 @@ static bool LookupRange(CDBWrapper& db, const std::string& index_name, int start
397313 size_t results_size = static_cast <size_t >(stop_index->nHeight - start_height + 1 );
398314 std::vector<std::pair<uint256, DBVal>> values (results_size);
399315
400- DBHeightKey key (start_height);
316+ index_util:: DBHeightKey key (start_height);
401317 std::unique_ptr<CDBIterator> db_it (db.NewIterator ());
402- db_it->Seek (DBHeightKey (start_height));
318+ db_it->Seek (index_util:: DBHeightKey (start_height));
403319 for (int height = start_height; height <= stop_index->nHeight ; ++height) {
404320 if (!db_it->Valid () || !db_it->GetKey (key) || key.height != height) {
405321 return false ;
@@ -408,7 +324,7 @@ static bool LookupRange(CDBWrapper& db, const std::string& index_name, int start
408324 size_t i = static_cast <size_t >(height - start_height);
409325 if (!db_it->GetValue (values[i])) {
410326 LogError (" unable to read value in %s at key (%c, %d)" ,
411- index_name, DB_BLOCK_HEIGHT, height);
327+ index_name, index_util:: DB_BLOCK_HEIGHT, height);
412328 return false ;
413329 }
414330
@@ -430,9 +346,9 @@ static bool LookupRange(CDBWrapper& db, const std::string& index_name, int start
430346 continue ;
431347 }
432348
433- if (!db.Read (DBHashKey (block_hash), results[i])) {
349+ if (!db.Read (index_util:: DBHashKey (block_hash), results[i])) {
434350 LogError (" unable to read value in %s at key (%c, %s)" ,
435- index_name, DB_BLOCK_HASH, block_hash.ToString ());
351+ index_name, index_util:: DB_BLOCK_HASH, block_hash.ToString ());
436352 return false ;
437353 }
438354 }
@@ -443,7 +359,7 @@ static bool LookupRange(CDBWrapper& db, const std::string& index_name, int start
443359bool BlockFilterIndex::LookupFilter (const CBlockIndex* block_index, BlockFilter& filter_out) const
444360{
445361 DBVal entry;
446- if (!LookupOne (*m_db, block_index, entry)) {
362+ if (!index_util::LookUpOne (*m_db, { block_index-> GetBlockHash (), block_index-> nHeight } , entry)) {
447363 return false ;
448364 }
449365
@@ -466,7 +382,7 @@ bool BlockFilterIndex::LookupFilterHeader(const CBlockIndex* block_index, uint25
466382 }
467383
468384 DBVal entry;
469- if (!LookupOne (*m_db, block_index, entry)) {
385+ if (!index_util::LookUpOne (*m_db, { block_index-> GetBlockHash (), block_index-> nHeight } , entry)) {
470386 return false ;
471387 }
472388
0 commit comments