Bitcoin Core 30.99.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
19namespace 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
29static constexpr uint8_t DB_BLOCK_HASH{'s'};
30static constexpr uint8_t DB_BLOCK_HEIGHT{'t'};
31
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
55struct 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
71template <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
95template <typename DBVal>
96static 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
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:72
void Write(const K &key, const V &value)
Definition: dbwrapper.h:96
bool GetValue(V &value)
Definition: dbwrapper.h:164
bool GetKey(K &key)
Definition: dbwrapper.h:154
void Seek(const K &key)
Definition: dbwrapper.h:145
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:207
256-bit opaque blob.
Definition: uint256.h:195
#define LogError(...)
Definition: logging.h:393
static bool LookUpOne(const CDBWrapper &db, const interfaces::BlockRef &block, DBVal &result)
Definition: db_key.h:96
static constexpr uint8_t DB_BLOCK_HASH
Definition: db_key.h:29
static constexpr uint8_t DB_BLOCK_HEIGHT
Definition: db_key.h:30
static bool CopyHeightIndexToHashIndex(CDBIterator &db_it, CDBBatch &batch, const std::string &index_name, int height)
Definition: db_key.h:72
const char * prefix
Definition: rest.cpp:1142
uint8_t ser_readdata8(Stream &s)
Definition: serialize.h:78
void ser_writedata32be(Stream &s, uint32_t obj)
Definition: serialize.h:68
void ser_writedata8(Stream &s, uint8_t obj)
Definition: serialize.h:54
uint32_t ser_readdata32be(Stream &s)
Definition: serialize.h:96
#define READWRITE(...)
Definition: serialize.h:145
DBHashKey(const uint256 &hash_in)
Definition: db_key.h:58
SERIALIZE_METHODS(DBHashKey, obj)
Definition: db_key.h:60
DBHeightKey(int height_in)
Definition: db_key.h:35
void Unserialize(Stream &s)
Definition: db_key.h:45
void Serialize(Stream &s) const
Definition: db_key.h:38
Hash/height pair to help track and identify blocks.
Definition: types.h:13
uint256 hash
Definition: types.h:14