Coverage Report

Created: 2026-09-15 16:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/bitcoin/src/dbwrapper.h
Line
Count
Source
1
// Copyright (c) 2012-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_DBWRAPPER_H
6
#define BITCOIN_DBWRAPPER_H
7
8
#include <attributes.h>
9
#include <serialize.h>
10
#include <span.h>
11
#include <streams.h>
12
#include <util/byte_units.h>
13
#include <util/check.h>
14
#include <util/expected.h>
15
#include <util/fs.h>
16
#include <util/obfuscation.h>
17
18
#include <cstddef>
19
#include <cstdint>
20
#include <exception>
21
#include <memory>
22
#include <optional>
23
#include <span>
24
#include <stdexcept>
25
#include <string>
26
27
namespace leveldb {
28
class Env;
29
} // namespace leveldb
30
31
inline constexpr size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
32
inline constexpr size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;
33
inline constexpr size_t DBWRAPPER_MAX_FILE_SIZE{32_MiB};
34
35
//! User-controlled performance and debug options.
36
struct DBOptions {
37
    //! Compact database on startup.
38
    bool force_compact = false;
39
};
40
41
//! Application-specific storage settings.
42
struct DBParams {
43
    //! Location in the filesystem where leveldb data will be stored.
44
    fs::path path;
45
    //! Configures various leveldb cache settings.
46
    uint64_t cache_bytes;
47
    //! If true, use leveldb's memory environment.
48
    bool memory_only = false;
49
    //! If true, remove all existing data.
50
    bool wipe_data = false;
51
    //! If true, store data obfuscated via simple XOR. If false, XOR with a
52
    //! zero'd byte array.
53
    bool obfuscate = false;
54
    //! If true, build a LevelDB bloom filter to accelerate point lookups.
55
    bool bloom_filter = true;
56
    //! Passed-through options.
57
    DBOptions options{};
58
    //! If non-null, use this as the leveldb::Env instead of the default.
59
    //! Caller retains ownership.
60
    leveldb::Env* testing_env = nullptr;
61
    //! Maximum LevelDB SST file size. Larger values reduce the frequency
62
    //! of compactions but increase their duration.
63
    size_t max_file_size = DBWRAPPER_MAX_FILE_SIZE;
64
};
65
66
class dbwrapper_error : public std::runtime_error
67
{
68
public:
69
0
    explicit dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {}
70
};
71
72
class CDBWrapper;
73
74
/** These should be considered an implementation detail of the specific database.
75
 */
76
namespace dbwrapper_private {
77
78
/** Work around circular dependency, as well as for testing in dbwrapper_tests.
79
 * Database obfuscation should be considered an implementation detail of the
80
 * specific database.
81
 */
82
const Obfuscation& GetObfuscation(const CDBWrapper&);
83
}; // namespace dbwrapper_private
84
85
bool DestroyDB(const std::string& path_str);
86
87
/** Batch of changes queued to be written to a CDBWrapper */
88
class CDBBatch
89
{
90
    friend class CDBWrapper;
91
92
private:
93
    const CDBWrapper &parent;
94
95
    struct WriteBatchImpl;
96
    const std::unique_ptr<WriteBatchImpl> m_impl_batch;
97
98
    DataStream m_key_scratch{};
99
    DataStream m_value_scratch{};
100
101
    void WriteImpl(std::span<const std::byte> key, DataStream& value);
102
    void EraseImpl(std::span<const std::byte> key);
103
104
public:
105
    /**
106
     * @param[in] _parent   CDBWrapper that this batch is to be submitted to
107
     */
108
    explicit CDBBatch(const CDBWrapper& _parent);
109
    ~CDBBatch();
110
    void Clear();
111
112
    template <typename K, typename V>
113
    void Write(const K& key, const V& value)
114
0
    {
115
0
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
116
0
        m_key_scratch << key;
117
0
        m_value_scratch << value;
118
0
        WriteImpl(m_key_scratch, m_value_scratch);
119
0
    }
Unexecuted instantiation: _ZN8CDBBatch5WriteItSt6vectorIhSaIhEEEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE11ObfuscationEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteIhhEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteISt4pairIhiEN6kernel14CBlockFileInfoEEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteIhiEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteISt4pairIh7uint256E15CDiskBlockIndexEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteISt4pairIhNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEhEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteIhSt6vectorI7uint256SaIS2_EEEEvRKT_RKT0_
Unexecuted instantiation: txdb.cpp:_ZN8CDBBatch5WriteIN12_GLOBAL__N_19CoinEntryE4CoinEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteIh7uint256EEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteIh13CBlockLocatorEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteIh11FlatFilePosEEvRKT_RKT0_
Unexecuted instantiation: blockfilterindex.cpp:_ZN8CDBBatch5WriteIN10index_util11DBHeightKeyESt4pairI7uint256N12_GLOBAL__N_15DBValEEEEvRKT_RKT0_
Unexecuted instantiation: blockfilterindex.cpp:_ZN8CDBBatch5WriteIN10index_util9DBHashKeyEN12_GLOBAL__N_15DBValEEEvRKT_RKT0_
Unexecuted instantiation: coinstatsindex.cpp:_ZN8CDBBatch5WriteIN10index_util11DBHeightKeyESt4pairI7uint256N12_GLOBAL__N_15DBValEEEEvRKT_RKT0_
Unexecuted instantiation: coinstatsindex.cpp:_ZN8CDBBatch5WriteIN10index_util9DBHashKeyEN12_GLOBAL__N_15DBValEEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteIh10MuHash3072EEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairImmEEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13CBlockLocatorEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteIN7txindex12BlockHashKeyEjEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteIN7txindex11BlockSeqKeyE7uint256EEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteIN7txindex5DBKeyESt5arrayISt4byteLm0EEEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteIA12_cSt4pairImmEEEvRKT_RKT0_
Unexecuted instantiation: _ZN8CDBBatch5WriteI5DBKeySt4spanIKSt4byteLm18446744073709551615EEEEvRKT_RKT0_
120
121
    template <typename K>
122
    void Erase(const K& key)
123
0
    {
124
0
        ScopedDataStreamUsage scoped_key{m_key_scratch};
125
0
        m_key_scratch << key;
126
0
        EraseImpl(m_key_scratch);
127
0
    }
Unexecuted instantiation: _ZN8CDBBatch5EraseItEEvRKT_
Unexecuted instantiation: _ZN8CDBBatch5EraseIhEEvRKT_
Unexecuted instantiation: txdb.cpp:_ZN8CDBBatch5EraseIN12_GLOBAL__N_19CoinEntryEEEvRKT_
Unexecuted instantiation: _ZN8CDBBatch5EraseI5DBKeyEEvRKT_
128
129
    size_t ApproximateSize() const;
130
};
131
132
class CDBIterator
133
{
134
public:
135
    struct IteratorImpl;
136
137
private:
138
    const CDBWrapper &parent;
139
    const std::unique_ptr<IteratorImpl> m_impl_iter;
140
    DataStream m_scratch{};
141
142
    void SeekImpl(std::span<const std::byte> key);
143
    std::span<const std::byte> GetKeyImpl() const;
144
    std::span<const std::byte> GetValueImpl() const;
145
146
public:
147
148
    /**
149
     * @param[in] _parent          Parent CDBWrapper instance.
150
     * @param[in] _piter           The original leveldb iterator.
151
     */
152
    CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter);
153
    ~CDBIterator();
154
155
    bool Valid() const;
156
157
    void SeekToFirst();
158
159
0
    template<typename K> void Seek(const K& key) {
160
0
        ScopedDataStreamUsage scoped_scratch{m_scratch};
161
0
        m_scratch << key;
162
0
        SeekImpl(m_scratch);
163
0
    }
Unexecuted instantiation: _ZN11CDBIterator4SeekItEEvRKT_
Unexecuted instantiation: _ZN11CDBIterator4SeekISt4pairIh7uint256EEEvRKT_
Unexecuted instantiation: _ZN11CDBIterator4SeekIhEEvRKT_
Unexecuted instantiation: _ZN11CDBIterator4SeekIN10index_util11DBHeightKeyEEEvRKT_
Unexecuted instantiation: _ZN11CDBIterator4SeekIN7txindex5DBKeyEEEvRKT_
Unexecuted instantiation: _ZN11CDBIterator4SeekISt4pairIhmEEEvRKT_
164
165
    void Next();
166
167
0
    template<typename K> bool GetKey(K& key) {
168
0
        try {
169
0
            SpanReader ssKey{GetKeyImpl()};
170
0
            ssKey >> key;
171
0
        } catch (const std::exception&) {
172
0
            return false;
173
0
        }
174
0
        return true;
175
0
    }
Unexecuted instantiation: _ZN11CDBIterator6GetKeyINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRT_
Unexecuted instantiation: _ZN11CDBIterator6GetKeyItEEbRT_
Unexecuted instantiation: _ZN11CDBIterator6GetKeyISt4pairIh7uint256EEEbRT_
Unexecuted instantiation: txdb.cpp:_ZN11CDBIterator6GetKeyIN12_GLOBAL__N_19CoinEntryEEEbRT_
Unexecuted instantiation: _ZN11CDBIterator6GetKeyIN10index_util11DBHeightKeyEEEbRT_
Unexecuted instantiation: _ZN11CDBIterator6GetKeyIN7txindex5DBKeyEEEbRT_
Unexecuted instantiation: _ZN11CDBIterator6GetKeyI5DBKeyEEbRT_
176
177
0
    template<typename V> bool GetValue(V& value) {
178
0
        try {
179
0
            ScopedDataStreamUsage scoped_scratch{m_scratch};
180
0
            m_scratch.write(GetValueImpl());
181
0
            dbwrapper_private::GetObfuscation(parent)(m_scratch);
182
0
            m_scratch >> value;
183
0
        } catch (const std::exception&) {
184
0
            return false;
185
0
        }
186
0
        return true;
187
0
    }
Unexecuted instantiation: _ZN11CDBIterator8GetValueISt6vectorIhSaIhEEEEbRT_
Unexecuted instantiation: _ZN11CDBIterator8GetValueI15CDiskBlockIndexEEbRT_
Unexecuted instantiation: _ZN11CDBIterator8GetValueI4CoinEEbRT_
Unexecuted instantiation: blockfilterindex.cpp:_ZN11CDBIterator8GetValueISt4pairI7uint256N12_GLOBAL__N_15DBValEEEEbRT_
Unexecuted instantiation: coinstatsindex.cpp:_ZN11CDBIterator8GetValueISt4pairI7uint256N12_GLOBAL__N_15DBValEEEEbRT_
188
};
189
190
struct LevelDBContext;
191
192
class CDBWrapper
193
{
194
    friend const Obfuscation& dbwrapper_private::GetObfuscation(const CDBWrapper&);
195
private:
196
    //! holds all leveldb-specific fields of this class
197
    std::unique_ptr<LevelDBContext> m_db_context;
198
199
    //! the name of this database
200
    std::string m_name;
201
202
    //! optional XOR-obfuscation of the database
203
    Obfuscation m_obfuscation;
204
205
    //! obfuscation key storage key, null-prefixed to avoid collisions
206
    inline static const std::string OBFUSCATION_KEY{"\000obfuscate_key", 14}; // explicit size to avoid truncation at leading \0
207
208
    std::optional<std::string> ReadImpl(std::span<const std::byte> key) const;
209
    bool ExistsImpl(std::span<const std::byte> key) const;
210
    size_t EstimateSizeImpl(std::span<const std::byte> key1, std::span<const std::byte> key2) const;
211
258k
    auto& DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); }
212
213
public:
214
    CDBWrapper(const DBParams& params);
215
    ~CDBWrapper();
216
217
    CDBWrapper(const CDBWrapper&) = delete;
218
    CDBWrapper& operator=(const CDBWrapper&) = delete;
219
220
    struct ReadFailure {
221
        enum class Code {
222
            DeserializationError,   //!< Key exists but value could not be deserialized.
223
            DatabaseError,          //!< Unexpected internal DB error.
224
        };
225
226
        Code status;
227
        std::string err_msg;
228
    };
229
230
    using ReadStatus = util::Expected<bool, ReadFailure>;
231
232
    /**
233
     * Read and deserialize a value from the database, with explicit error discrimination.
234
     *
235
     * Unlike Read(), this method distinguishes between a missing key, a deserialization
236
     * failure (DeserializationError), and an internal DB error (DatabaseError),
237
     * enabling callers to treat data corruption differently from an absent entry.
238
     *
239
     * @note Callers are expected to provide well-formed keys; key serialization
240
     *       is the only operation that may throw.
241
     *
242
     * @param[in]  key    The key to look up.
243
     * @param[out] value  Populated with the deserialized value when the returned
244
     *                    Expected holds true; indeterminate otherwise.
245
     * @return On success, true if the key was found (value populated) or false if
246
     *         the key was absent. On failure, a ReadFailure describing the error.
247
     */
248
    template <typename K, typename V>
249
    [[nodiscard]] ReadStatus TryRead(const K& key, V& value) const
250
129k
    {
251
129k
        DataStream ssKey{};
252
129k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
253
        // Key serialization is the only operation that may throw.
254
        // Callers are expected to provide well-formed keys.
255
129k
        ssKey << key;
256
257
129k
        std::optional<std::string> strValue;
258
129k
        try {
259
129k
            strValue = ReadImpl(ssKey);
260
129k
            if (!strValue) {
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 129k, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
  Branch (260:17): [True: 0, False: 0]
261
129k
                return false; // not found
262
129k
            }
263
129k
        } catch (const std::exception& e) {
264
0
            return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()});
265
0
        }
266
267
0
        try {
268
0
            std::span ssValue{MakeWritableByteSpan(*strValue)};
269
0
            m_obfuscation(ssValue);
270
0
            SpanReader{ssValue} >> value;
271
0
        } catch (const std::exception& e) {
272
0
            return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()});
273
0
        }
274
275
0
        return true;
276
0
    }
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadItSt6vectorIhSaIhEEEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: dbwrapper.cpp:_ZNK10CDBWrapper7TryReadItN12_GLOBAL__N_115FailUnserializeEEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE11ObfuscationEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadISt4pairIhiEN6kernel14CBlockFileInfoEEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadIhiEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadISt4pairIhNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEhEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
txdb.cpp:_ZNK10CDBWrapper7TryReadIN12_GLOBAL__N_19CoinEntryE4CoinEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Line
Count
Source
250
129k
    {
251
129k
        DataStream ssKey{};
252
129k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
253
        // Key serialization is the only operation that may throw.
254
        // Callers are expected to provide well-formed keys.
255
129k
        ssKey << key;
256
257
129k
        std::optional<std::string> strValue;
258
129k
        try {
259
129k
            strValue = ReadImpl(ssKey);
260
129k
            if (!strValue) {
  Branch (260:17): [True: 129k, False: 0]
261
129k
                return false; // not found
262
129k
            }
263
129k
        } catch (const std::exception& e) {
264
0
            return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()});
265
0
        }
266
267
0
        try {
268
0
            std::span ssValue{MakeWritableByteSpan(*strValue)};
269
0
            m_obfuscation(ssValue);
270
0
            SpanReader{ssValue} >> value;
271
0
        } catch (const std::exception& e) {
272
0
            return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()});
273
0
        }
274
275
0
        return true;
276
0
    }
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadIh7uint256EEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadIhSt6vectorI7uint256SaIS2_EEEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadIh13CBlockLocatorEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: blockfilterindex.cpp:_ZNK10CDBWrapper7TryReadIN10index_util9DBHashKeyEN12_GLOBAL__N_15DBValEEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadIh11FlatFilePosEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: blockfilterindex.cpp:_ZNK10CDBWrapper7TryReadIN10index_util11DBHeightKeyESt4pairI7uint256N12_GLOBAL__N_15DBValEEEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: coinstatsindex.cpp:_ZNK10CDBWrapper7TryReadIN10index_util9DBHashKeyEN12_GLOBAL__N_15DBValEEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadIh10MuHash3072EEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: coinstatsindex.cpp:_ZNK10CDBWrapper7TryReadIN10index_util11DBHeightKeyESt4pairI7uint256N12_GLOBAL__N_15DBValEEEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: coinstatsindex.cpp:_ZNK10CDBWrapper7TryReadIN10index_util9DBHashKeyESt4pairI7uint256N12_GLOBAL__N_15DBValEEEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairImmEEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13CBlockLocatorEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadIN7txindex11BlockSeqKeyE7uint256EEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadISt4pairIh7uint256E10CDiskTxPosEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper7TryReadIA12_cSt4pairImmEEEN4util8ExpectedIbNS_11ReadFailureEEERKT_RT0_
277
278
    /**
279
     * Wrapper around TryRead() that preserves the original Read() semantics:
280
     * returns true on success, false if the key is absent or deserialization
281
     * fails, and throws dbwrapper_error on an internal DB error.
282
     *
283
     * Prefer TryRead() when the caller needs to distinguish between a missing
284
     * key and a corrupt value.
285
     */
286
    template <typename K, typename V>
287
    bool Read(const K& key, V& value) const
288
0
    {
289
0
        const ReadStatus res = TryRead(key,value);
290
0
        if (res.has_value()) return res.value();
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
  Branch (290:13): [True: 0, False: 0]
291
0
        switch (const auto& [err_code, err_msg] = res.error(); err_code) {
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
  Branch (291:64): [True: 0, False: 0]
292
0
            case ReadFailure::Code::DeserializationError: return false;
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
  Branch (292:13): [True: 0, False: 0]
293
0
            case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg);
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
  Branch (293:13): [True: 0, False: 0]
294
0
        } // no default case, so the compiler can warn about missing cases
295
0
        std::abort(); // unreachable
296
0
    }
Unexecuted instantiation: _ZNK10CDBWrapper4ReadItSt6vectorIhSaIhEEEEbRKT_RT0_
Unexecuted instantiation: dbwrapper.cpp:_ZNK10CDBWrapper4ReadItN12_GLOBAL__N_115FailUnserializeEEEbRKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper4ReadINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE11ObfuscationEEbRKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper4ReadISt4pairIhiEN6kernel14CBlockFileInfoEEEbRKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper4ReadIhiEEbRKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper4ReadISt4pairIhNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEhEEbRKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper4ReadIh7uint256EEbRKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper4ReadIhSt6vectorI7uint256SaIS2_EEEEbRKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper4ReadIh13CBlockLocatorEEbRKT_RT0_
Unexecuted instantiation: blockfilterindex.cpp:_ZNK10CDBWrapper4ReadIN10index_util9DBHashKeyEN12_GLOBAL__N_15DBValEEEbRKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper4ReadIh11FlatFilePosEEbRKT_RT0_
Unexecuted instantiation: blockfilterindex.cpp:_ZNK10CDBWrapper4ReadIN10index_util11DBHeightKeyESt4pairI7uint256N12_GLOBAL__N_15DBValEEEEbRKT_RT0_
Unexecuted instantiation: coinstatsindex.cpp:_ZNK10CDBWrapper4ReadIN10index_util9DBHashKeyEN12_GLOBAL__N_15DBValEEEbRKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper4ReadIh10MuHash3072EEbRKT_RT0_
Unexecuted instantiation: coinstatsindex.cpp:_ZNK10CDBWrapper4ReadIN10index_util11DBHeightKeyESt4pairI7uint256N12_GLOBAL__N_15DBValEEEEbRKT_RT0_
Unexecuted instantiation: coinstatsindex.cpp:_ZNK10CDBWrapper4ReadIN10index_util9DBHashKeyESt4pairI7uint256N12_GLOBAL__N_15DBValEEEEbRKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper4ReadINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairImmEEEbRKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper4ReadINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13CBlockLocatorEEbRKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper4ReadINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjEEbRKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper4ReadIN7txindex11BlockSeqKeyE7uint256EEbRKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper4ReadISt4pairIh7uint256E10CDiskTxPosEEbRKT_RT0_
Unexecuted instantiation: _ZNK10CDBWrapper4ReadIA12_cSt4pairImmEEEbRKT_RT0_
297
298
    template <typename K, typename V>
299
    void Write(const K& key, const V& value, bool fSync = false)
300
0
    {
301
0
        CDBBatch batch(*this);
302
0
        batch.Write(key, value);
303
0
        WriteBatch(batch, fSync);
304
0
    }
Unexecuted instantiation: _ZN10CDBWrapper5WriteItSt6vectorIhSaIhEEEEvRKT_RKT0_b
Unexecuted instantiation: _ZN10CDBWrapper5WriteINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE11ObfuscationEEvRKT_RKT0_b
Unexecuted instantiation: _ZN10CDBWrapper5WriteIhhEEvRKT_RKT0_b
Unexecuted instantiation: _ZN10CDBWrapper5WriteISt4pairIhNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEhEEvRKT_RKT0_b
Unexecuted instantiation: blockfilterindex.cpp:_ZN10CDBWrapper5WriteIN10index_util11DBHeightKeyESt4pairI7uint256N12_GLOBAL__N_15DBValEEEEvRKT_RKT0_b
Unexecuted instantiation: coinstatsindex.cpp:_ZN10CDBWrapper5WriteIN10index_util11DBHeightKeyESt4pairI7uint256N12_GLOBAL__N_15DBValEEEEvRKT_RKT0_b
Unexecuted instantiation: _ZN10CDBWrapper5WriteINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairImmEEEvRKT_RKT0_b
Unexecuted instantiation: _ZN10CDBWrapper5WriteIA12_cSt4pairImmEEEvRKT_RKT0_b
305
306
    template <typename K>
307
    bool Exists(const K& key) const
308
0
    {
309
0
        DataStream ssKey{};
310
0
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
311
0
        ssKey << key;
312
0
        return ExistsImpl(ssKey);
313
0
    }
Unexecuted instantiation: _ZNK10CDBWrapper6ExistsItEEbRKT_
Unexecuted instantiation: _ZNK10CDBWrapper6ExistsIhEEbRKT_
Unexecuted instantiation: txdb.cpp:_ZNK10CDBWrapper6ExistsIN12_GLOBAL__N_19CoinEntryEEEbRKT_
Unexecuted instantiation: _ZNK10CDBWrapper6ExistsIN7txindex12BlockHashKeyEEEbRKT_
314
315
    template <typename K>
316
    void Erase(const K& key, bool fSync = false)
317
0
    {
318
0
        CDBBatch batch(*this);
319
0
        batch.Erase(key);
320
0
        WriteBatch(batch, fSync);
321
0
    }
Unexecuted instantiation: _ZN10CDBWrapper5EraseItEEvRKT_b
Unexecuted instantiation: _ZN10CDBWrapper5EraseIhEEvRKT_b
322
323
    void WriteBatch(CDBBatch& batch, bool fSync = false);
324
325
    //! Perform a blocking full compaction of the underlying LevelDB.
326
    void CompactFull();
327
328
    //! Return a LevelDB property value, if available.
329
    std::optional<std::string> GetProperty(const std::string& property) const;
330
331
    // Get an estimate of LevelDB memory usage (in bytes).
332
    size_t DynamicMemoryUsage() const;
333
334
    CDBIterator* NewIterator();
335
336
    /**
337
     * Return true if the database managed by this class contains no entries.
338
     */
339
    bool IsEmpty();
340
341
    //! Probe an unopened database for a key prefix. Return true if a database at
342
    //! path exists and contains at least 1 entry beginning with prefix; missing
343
    //! or empty databases return false, and database errors throw dbwrapper_error.
344
    static bool HasKeyStartingWith(const fs::path& path, uint8_t prefix);
345
346
    template<typename K>
347
    size_t EstimateSize(const K& key_begin, const K& key_end) const
348
0
    {
349
0
        DataStream ssKey1{}, ssKey2{};
350
0
        ssKey1.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
351
0
        ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
352
0
        ssKey1 << key_begin;
353
0
        ssKey2 << key_end;
354
0
        return EstimateSizeImpl(ssKey1, ssKey2);
355
0
    }
Unexecuted instantiation: _ZNK10CDBWrapper12EstimateSizeItEEmRKT_S3_
Unexecuted instantiation: _ZNK10CDBWrapper12EstimateSizeIhEEmRKT_S3_
356
};
357
358
#endif // BITCOIN_DBWRAPPER_H