Bitcoin Core  31.0.0
P2P Digital Currency
db_key.h
Go to the documentation of this file.
1 // Copyright (c) 2025-present The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef BITCOIN_INDEX_DB_KEY_H
6 #define BITCOIN_INDEX_DB_KEY_H
7 
8 #include <dbwrapper.h>
9 #include <interfaces/types.h>
10 #include <logging.h>
11 #include <serialize.h>
12 #include <uint256.h>
13 
14 #include <cstdint>
15 #include <ios>
16 #include <string>
17 #include <utility>
18 
19 namespace index_util {
20 /*
21  * This file includes the logic for the db keys used by blockfilterindex and coinstatsindex.
22  * Index data is usually indexed by height, but in case of a reorg, entries of blocks no
23  * longer in the main chain will be copied to a hash index by which they can still be queried.
24  * Keys for the height index have the type [DB_BLOCK_HEIGHT, uint32 (BE)]. The height is represented
25  * as big-endian so that sequential reads of filters by height are fast.
26  * Keys for the hash index have the type [DB_BLOCK_HASH, uint256].
27  */
28 
29 static constexpr uint8_t DB_BLOCK_HASH{'s'};
30 static constexpr uint8_t DB_BLOCK_HEIGHT{'t'};
31 
32 struct DBHeightKey {
33  int height;
34 
35  explicit DBHeightKey(int height_in) : height(height_in) {}
36 
37  template<typename Stream>
38  void Serialize(Stream& s) const
39  {
42  }
43 
44  template<typename Stream>
45  void Unserialize(Stream& s)
46  {
47  const uint8_t prefix{ser_readdata8(s)};
48  if (prefix != DB_BLOCK_HEIGHT) {
49  throw std::ios_base::failure("Invalid format for index DB height key");
50  }
52  }
53 };
54 
55 struct DBHashKey {
57 
58  explicit DBHashKey(const uint256& hash_in) : hash(hash_in) {}
59 
61  uint8_t prefix{DB_BLOCK_HASH};
63  if (prefix != DB_BLOCK_HASH) {
64  throw std::ios_base::failure("Invalid format for index DB hash key");
65  }
66 
67  READWRITE(obj.hash);
68  }
69 };
70 
71 template <typename DBVal>
72 [[nodiscard]] static bool CopyHeightIndexToHashIndex(CDBIterator& db_it, CDBBatch& batch,
73  const std::string& index_name, int height)
74 {
75  DBHeightKey key(height);
76  db_it.Seek(key);
77 
78  if (!db_it.GetKey(key) || key.height != height) {
79  LogError("unexpected key in %s: expected (%c, %d)",
80  index_name, DB_BLOCK_HEIGHT, height);
81  return false;
82  }
83 
84  std::pair<uint256, DBVal> value;
85  if (!db_it.GetValue(value)) {
86  LogError("unable to read value in %s at key (%c, %d)",
87  index_name, DB_BLOCK_HEIGHT, height);
88  return false;
89  }
90 
91  batch.Write(DBHashKey(value.first), value.second);
92  return true;
93 }
94 
95 template <typename DBVal>
96 static bool LookUpOne(const CDBWrapper& db, const interfaces::BlockRef& block, DBVal& result)
97 {
98  // First check if the result is stored under the height index and the value
99  // there matches the block hash. This should be the case if the block is on
100  // the active chain.
101  std::pair<uint256, DBVal> read_out;
102  if (!db.Read(DBHeightKey(block.height), read_out)) {
103  return false;
104  }
105  if (read_out.first == block.hash) {
106  result = std::move(read_out.second);
107  return true;
108  }
109 
110  // If value at the height index corresponds to an different block, the
111  // result will be stored in the hash index.
112  return db.Read(DBHashKey(block.hash), result);
113 }
114 } // namespace index_util
115 
116 #endif // BITCOIN_INDEX_DB_KEY_H
bool GetKey(K &key)
Definition: dbwrapper.h:154
void Unserialize(Stream &s)
Definition: db_key.h:45
void Serialize(Stream &s) const
Definition: db_key.h:38
static bool CopyHeightIndexToHashIndex(CDBIterator &db_it, CDBBatch &batch, const std::string &index_name, int height)
Definition: db_key.h:72
uint8_t ser_readdata8(Stream &s)
Definition: serialize.h:78
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:71
const char * prefix
Definition: rest.cpp:1141
Hash/height pair to help track and identify blocks.
Definition: types.h:13
static bool LookUpOne(const CDBWrapper &db, const interfaces::BlockRef &block, DBVal &result)
Definition: db_key.h:96
bool GetValue(V &value)
Definition: dbwrapper.h:164
void Write(const K &key, const V &value)
Definition: dbwrapper.h:96
void ser_writedata32be(Stream &s, uint32_t obj)
Definition: serialize.h:68
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:207
256-bit opaque blob.
Definition: uint256.h:195
auto result
Definition: common-types.h:74
static constexpr uint8_t DB_BLOCK_HEIGHT
Definition: db_key.h:30
SERIALIZE_METHODS(DBHashKey, obj)
Definition: db_key.h:60
uint32_t ser_readdata32be(Stream &s)
Definition: serialize.h:96
void Seek(const K &key)
Definition: dbwrapper.h:145
uint256 hash
Definition: types.h:14
#define READWRITE(...)
Definition: serialize.h:145
static constexpr uint8_t DB_BLOCK_HASH
Definition: db_key.h:29
DBHashKey(const uint256 &hash_in)
Definition: db_key.h:58
void ser_writedata8(Stream &s, uint8_t obj)
Definition: serialize.h:54
DBHeightKey(int height_in)
Definition: db_key.h:35
#define LogError(...)
Definition: log.h:97