Coverage Report

Created: 2025-06-10 13:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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/check.h>
13
#include <util/fs.h>
14
15
#include <cstddef>
16
#include <exception>
17
#include <memory>
18
#include <optional>
19
#include <stdexcept>
20
#include <string>
21
#include <vector>
22
23
static const size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
24
static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;
25
static const size_t DBWRAPPER_MAX_FILE_SIZE = 32 << 20; // 32 MiB
26
27
//! User-controlled performance and debug options.
28
struct DBOptions {
29
    //! Compact database on startup.
30
    bool force_compact = false;
31
};
32
33
//! Application-specific storage settings.
34
struct DBParams {
35
    //! Location in the filesystem where leveldb data will be stored.
36
    fs::path path;
37
    //! Configures various leveldb cache settings.
38
    size_t cache_bytes;
39
    //! If true, use leveldb's memory environment.
40
    bool memory_only = false;
41
    //! If true, remove all existing data.
42
    bool wipe_data = false;
43
    //! If true, store data obfuscated via simple XOR. If false, XOR with a
44
    //! zero'd byte array.
45
    bool obfuscate = false;
46
    //! Passed-through options.
47
    DBOptions options{};
48
};
49
50
class dbwrapper_error : public std::runtime_error
51
{
52
public:
53
0
    explicit dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {}
54
};
55
56
class CDBWrapper;
57
58
/** These should be considered an implementation detail of the specific database.
59
 */
60
namespace dbwrapper_private {
61
62
/** Work around circular dependency, as well as for testing in dbwrapper_tests.
63
 * Database obfuscation should be considered an implementation detail of the
64
 * specific database.
65
 */
66
const std::vector<unsigned char>& GetObfuscateKey(const CDBWrapper &w);
67
68
}; // namespace dbwrapper_private
69
70
bool DestroyDB(const std::string& path_str);
71
72
/** Batch of changes queued to be written to a CDBWrapper */
73
class CDBBatch
74
{
75
    friend class CDBWrapper;
76
77
private:
78
    const CDBWrapper &parent;
79
80
    struct WriteBatchImpl;
81
    const std::unique_ptr<WriteBatchImpl> m_impl_batch;
82
83
    DataStream ssKey{};
84
    DataStream ssValue{};
85
86
    void WriteImpl(std::span<const std::byte> key, DataStream& ssValue);
87
    void EraseImpl(std::span<const std::byte> key);
88
89
public:
90
    /**
91
     * @param[in] _parent   CDBWrapper that this batch is to be submitted to
92
     */
93
    explicit CDBBatch(const CDBWrapper& _parent);
94
    ~CDBBatch();
95
    void Clear();
96
97
    template <typename K, typename V>
98
    void Write(const K& key, const V& value)
99
6.87M
    {
100
6.87M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
101
6.87M
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
102
6.87M
        ssKey << key;
103
6.87M
        ssValue << value;
104
6.87M
        WriteImpl(ssKey, ssValue);
105
6.87M
        ssKey.clear();
106
6.87M
        ssValue.clear();
107
6.87M
    }
Unexecuted instantiation: void CDBBatch::Write<unsigned char, unsigned char>(unsigned char const&, unsigned char const&)
void CDBBatch::Write<std::pair<unsigned char, int>, CBlockFileInfo>(std::pair<unsigned char, int> const&, CBlockFileInfo const&)
Line
Count
Source
99
12.6k
    {
100
12.6k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
101
12.6k
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
102
12.6k
        ssKey << key;
103
12.6k
        ssValue << value;
104
12.6k
        WriteImpl(ssKey, ssValue);
105
12.6k
        ssKey.clear();
106
12.6k
        ssValue.clear();
107
12.6k
    }
void CDBBatch::Write<unsigned char, int>(unsigned char const&, int const&)
Line
Count
Source
99
29.2k
    {
100
29.2k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
101
29.2k
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
102
29.2k
        ssKey << key;
103
29.2k
        ssValue << value;
104
29.2k
        WriteImpl(ssKey, ssValue);
105
29.2k
        ssKey.clear();
106
29.2k
        ssValue.clear();
107
29.2k
    }
void CDBBatch::Write<std::pair<unsigned char, uint256>, CDiskBlockIndex>(std::pair<unsigned char, uint256> const&, CDiskBlockIndex const&)
Line
Count
Source
99
2.25M
    {
100
2.25M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
101
2.25M
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
102
2.25M
        ssKey << key;
103
2.25M
        ssValue << value;
104
2.25M
        WriteImpl(ssKey, ssValue);
105
2.25M
        ssKey.clear();
106
2.25M
        ssValue.clear();
107
2.25M
    }
Unexecuted instantiation: void CDBBatch::Write<std::pair<unsigned char, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, unsigned char>(std::pair<unsigned char, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, unsigned char const&)
void CDBBatch::Write<unsigned char, std::vector<uint256, std::allocator<uint256> > >(unsigned char const&, std::vector<uint256, std::allocator<uint256> > const&)
Line
Count
Source
99
29.2k
    {
100
29.2k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
101
29.2k
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
102
29.2k
        ssKey << key;
103
29.2k
        ssValue << value;
104
29.2k
        WriteImpl(ssKey, ssValue);
105
29.2k
        ssKey.clear();
106
29.2k
        ssValue.clear();
107
29.2k
    }
txdb.cpp:void CDBBatch::Write<(anonymous namespace)::CoinEntry, Coin>((anonymous namespace)::CoinEntry const&, Coin const&)
Line
Count
Source
99
2.22M
    {
100
2.22M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
101
2.22M
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
102
2.22M
        ssKey << key;
103
2.22M
        ssValue << value;
104
2.22M
        WriteImpl(ssKey, ssValue);
105
2.22M
        ssKey.clear();
106
2.22M
        ssValue.clear();
107
2.22M
    }
void CDBBatch::Write<unsigned char, uint256>(unsigned char const&, uint256 const&)
Line
Count
Source
99
29.2k
    {
100
29.2k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
101
29.2k
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
102
29.2k
        ssKey << key;
103
29.2k
        ssValue << value;
104
29.2k
        WriteImpl(ssKey, ssValue);
105
29.2k
        ssKey.clear();
106
29.2k
        ssValue.clear();
107
29.2k
    }
void CDBBatch::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<unsigned char, std::allocator<unsigned char> > const&)
Line
Count
Source
99
11.0k
    {
100
11.0k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
101
11.0k
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
102
11.0k
        ssKey << key;
103
11.0k
        ssValue << value;
104
11.0k
        WriteImpl(ssKey, ssValue);
105
11.0k
        ssKey.clear();
106
11.0k
        ssValue.clear();
107
11.0k
    }
void CDBBatch::Write<unsigned char, CBlockLocator>(unsigned char const&, CBlockLocator const&)
Line
Count
Source
99
20.6k
    {
100
20.6k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
101
20.6k
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
102
20.6k
        ssKey << key;
103
20.6k
        ssValue << value;
104
20.6k
        WriteImpl(ssKey, ssValue);
105
20.6k
        ssKey.clear();
106
20.6k
        ssValue.clear();
107
20.6k
    }
blockfilterindex.cpp:void CDBBatch::Write<(anonymous namespace)::DBHashKey, (anonymous namespace)::DBVal>((anonymous namespace)::DBHashKey const&, (anonymous namespace)::DBVal const&)
Line
Count
Source
99
6.51k
    {
100
6.51k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
101
6.51k
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
102
6.51k
        ssKey << key;
103
6.51k
        ssValue << value;
104
6.51k
        WriteImpl(ssKey, ssValue);
105
6.51k
        ssKey.clear();
106
6.51k
        ssValue.clear();
107
6.51k
    }
void CDBBatch::Write<unsigned char, FlatFilePos>(unsigned char const&, FlatFilePos const&)
Line
Count
Source
99
23.2k
    {
100
23.2k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
101
23.2k
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
102
23.2k
        ssKey << key;
103
23.2k
        ssValue << value;
104
23.2k
        WriteImpl(ssKey, ssValue);
105
23.2k
        ssKey.clear();
106
23.2k
        ssValue.clear();
107
23.2k
    }
blockfilterindex.cpp:void CDBBatch::Write<(anonymous namespace)::DBHeightKey, std::pair<uint256, (anonymous namespace)::DBVal> >((anonymous namespace)::DBHeightKey const&, std::pair<uint256, (anonymous namespace)::DBVal> const&)
Line
Count
Source
99
2.23M
    {
100
2.23M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
101
2.23M
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
102
2.23M
        ssKey << key;
103
2.23M
        ssValue << value;
104
2.23M
        WriteImpl(ssKey, ssValue);
105
2.23M
        ssKey.clear();
106
2.23M
        ssValue.clear();
107
2.23M
    }
Unexecuted instantiation: coinstatsindex.cpp:void CDBBatch::Write<(anonymous namespace)::DBHashKey, (anonymous namespace)::DBVal>((anonymous namespace)::DBHashKey const&, (anonymous namespace)::DBVal const&)
Unexecuted instantiation: coinstatsindex.cpp:void CDBBatch::Write<(anonymous namespace)::DBHeightKey, std::pair<uint256, (anonymous namespace)::DBVal> >((anonymous namespace)::DBHeightKey const&, std::pair<uint256, (anonymous namespace)::DBVal> const&)
Unexecuted instantiation: void CDBBatch::Write<unsigned char, MuHash3072>(unsigned char const&, MuHash3072 const&)
Unexecuted instantiation: void CDBBatch::Write<std::pair<unsigned char, uint256>, CDiskTxPos>(std::pair<unsigned char, uint256> const&, CDiskTxPos const&)
108
109
    template <typename K>
110
    void Erase(const K& key)
111
62.0k
    {
112
62.0k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
113
62.0k
        ssKey << key;
114
62.0k
        EraseImpl(ssKey);
115
62.0k
        ssKey.clear();
116
62.0k
    }
void CDBBatch::Erase<unsigned char>(unsigned char const&)
Line
Count
Source
111
58.4k
    {
112
58.4k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
113
58.4k
        ssKey << key;
114
58.4k
        EraseImpl(ssKey);
115
58.4k
        ssKey.clear();
116
58.4k
    }
txdb.cpp:void CDBBatch::Erase<(anonymous namespace)::CoinEntry>((anonymous namespace)::CoinEntry const&)
Line
Count
Source
111
3.62k
    {
112
3.62k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
113
3.62k
        ssKey << key;
114
3.62k
        EraseImpl(ssKey);
115
3.62k
        ssKey.clear();
116
3.62k
    }
117
118
    size_t ApproximateSize() const;
119
};
120
121
class CDBIterator
122
{
123
public:
124
    struct IteratorImpl;
125
126
private:
127
    const CDBWrapper &parent;
128
    const std::unique_ptr<IteratorImpl> m_impl_iter;
129
130
    void SeekImpl(std::span<const std::byte> key);
131
    std::span<const std::byte> GetKeyImpl() const;
132
    std::span<const std::byte> GetValueImpl() const;
133
134
public:
135
136
    /**
137
     * @param[in] _parent          Parent CDBWrapper instance.
138
     * @param[in] _piter           The original leveldb iterator.
139
     */
140
    CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter);
141
    ~CDBIterator();
142
143
    bool Valid() const;
144
145
    void SeekToFirst();
146
147
24.8k
    template<typename K> void Seek(const K& key) {
148
24.8k
        DataStream ssKey{};
149
24.8k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
150
24.8k
        ssKey << key;
151
24.8k
        SeekImpl(ssKey);
152
24.8k
    }
void CDBIterator::Seek<std::pair<unsigned char, uint256> >(std::pair<unsigned char, uint256> const&)
Line
Count
Source
147
22.1k
    template<typename K> void Seek(const K& key) {
148
22.1k
        DataStream ssKey{};
149
22.1k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
150
22.1k
        ssKey << key;
151
22.1k
        SeekImpl(ssKey);
152
22.1k
    }
Unexecuted instantiation: void CDBIterator::Seek<unsigned char>(unsigned char const&)
blockfilterindex.cpp:void CDBIterator::Seek<(anonymous namespace)::DBHeightKey>((anonymous namespace)::DBHeightKey const&)
Line
Count
Source
147
2.62k
    template<typename K> void Seek(const K& key) {
148
2.62k
        DataStream ssKey{};
149
2.62k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
150
2.62k
        ssKey << key;
151
2.62k
        SeekImpl(ssKey);
152
2.62k
    }
Unexecuted instantiation: coinstatsindex.cpp:void CDBIterator::Seek<(anonymous namespace)::DBHeightKey>((anonymous namespace)::DBHeightKey const&)
153
154
    void Next();
155
156
6.51k
    template<typename K> bool GetKey(K& key) {
157
6.51k
        try {
158
6.51k
            DataStream ssKey{GetKeyImpl()};
159
6.51k
            ssKey >> key;
160
6.51k
        } catch (const std::exception&) {
161
0
            return false;
162
0
        }
163
6.51k
        return true;
164
6.51k
    }
Unexecuted instantiation: bool CDBIterator::GetKey<std::pair<unsigned char, uint256> >(std::pair<unsigned char, uint256>&)
Unexecuted instantiation: txdb.cpp:bool CDBIterator::GetKey<(anonymous namespace)::CoinEntry>((anonymous namespace)::CoinEntry&)
blockfilterindex.cpp:bool CDBIterator::GetKey<(anonymous namespace)::DBHeightKey>((anonymous namespace)::DBHeightKey&)
Line
Count
Source
156
6.51k
    template<typename K> bool GetKey(K& key) {
157
6.51k
        try {
158
6.51k
            DataStream ssKey{GetKeyImpl()};
159
6.51k
            ssKey >> key;
160
6.51k
        } catch (const std::exception&) {
161
0
            return false;
162
0
        }
163
6.51k
        return true;
164
6.51k
    }
Unexecuted instantiation: coinstatsindex.cpp:bool CDBIterator::GetKey<(anonymous namespace)::DBHeightKey>((anonymous namespace)::DBHeightKey&)
165
166
6.51k
    template<typename V> bool GetValue(V& value) {
167
6.51k
        try {
168
6.51k
            DataStream ssValue{GetValueImpl()};
169
6.51k
            ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent));
170
6.51k
            ssValue >> value;
171
6.51k
        } catch (const std::exception&) {
172
0
            return false;
173
0
        }
174
6.51k
        return true;
175
6.51k
    }
Unexecuted instantiation: bool CDBIterator::GetValue<CDiskBlockIndex>(CDiskBlockIndex&)
Unexecuted instantiation: bool CDBIterator::GetValue<Coin>(Coin&)
blockfilterindex.cpp:bool CDBIterator::GetValue<std::pair<uint256, (anonymous namespace)::DBVal> >(std::pair<uint256, (anonymous namespace)::DBVal>&)
Line
Count
Source
166
6.51k
    template<typename V> bool GetValue(V& value) {
167
6.51k
        try {
168
6.51k
            DataStream ssValue{GetValueImpl()};
169
6.51k
            ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent));
170
6.51k
            ssValue >> value;
171
6.51k
        } catch (const std::exception&) {
172
0
            return false;
173
0
        }
174
6.51k
        return true;
175
6.51k
    }
Unexecuted instantiation: coinstatsindex.cpp:bool CDBIterator::GetValue<std::pair<uint256, (anonymous namespace)::DBVal> >(std::pair<uint256, (anonymous namespace)::DBVal>&)
176
};
177
178
struct LevelDBContext;
179
180
class CDBWrapper
181
{
182
    friend const std::vector<unsigned char>& dbwrapper_private::GetObfuscateKey(const CDBWrapper &w);
183
private:
184
    //! holds all leveldb-specific fields of this class
185
    std::unique_ptr<LevelDBContext> m_db_context;
186
187
    //! the name of this database
188
    std::string m_name;
189
190
    //! a key used for optional XOR-obfuscation of the database
191
    std::vector<unsigned char> obfuscate_key;
192
193
    //! the key under which the obfuscation key is stored
194
    static const std::string OBFUSCATE_KEY_KEY;
195
196
    //! the length of the obfuscate key in number of bytes
197
    static const unsigned int OBFUSCATE_KEY_NUM_BYTES;
198
199
    std::vector<unsigned char> CreateObfuscateKey() const;
200
201
    //! path to filesystem storage
202
    const fs::path m_path;
203
204
    //! whether or not the database resides in memory
205
    bool m_is_memory;
206
207
    std::optional<std::string> ReadImpl(std::span<const std::byte> key) const;
208
    bool ExistsImpl(std::span<const std::byte> key) const;
209
    size_t EstimateSizeImpl(std::span<const std::byte> key1, std::span<const std::byte> key2) const;
210
15.5M
    auto& DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); }
211
212
public:
213
    CDBWrapper(const DBParams& params);
214
    ~CDBWrapper();
215
216
    CDBWrapper(const CDBWrapper&) = delete;
217
    CDBWrapper& operator=(const CDBWrapper&) = delete;
218
219
    template <typename K, typename V>
220
    bool Read(const K& key, V& value) const
221
5.04M
    {
222
5.04M
        DataStream ssKey{};
223
5.04M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
5.04M
        ssKey << key;
225
5.04M
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
5.04M
        if (!strValue) {
  Branch (226:13): [True: 22.1k, False: 0]
  Branch (226:13): [True: 11.0k, False: 0]
  Branch (226:13): [True: 11.0k, False: 0]
  Branch (226:13): [True: 4.86M, False: 0]
  Branch (226:13): [True: 44.3k, False: 18.1k]
  Branch (226:13): [True: 22.1k, False: 0]
  Branch (226:13): [True: 33.2k, False: 0]
  Branch (226:13): [True: 11.0k, False: 0]
  Branch (226:13): [True: 0, False: 0]
  Branch (226:13): [True: 11.0k, False: 0]
  Branch (226:13): [True: 0, False: 2.62k]
  Branch (226:13): [True: 0, False: 0]
  Branch (226:13): [True: 0, False: 0]
  Branch (226:13): [True: 0, False: 0]
  Branch (226:13): [True: 0, False: 0]
  Branch (226:13): [True: 0, False: 0]
227
5.02M
            return false;
228
5.02M
        }
229
20.7k
        try {
230
20.7k
            DataStream ssValue{MakeByteSpan(*strValue)};
231
20.7k
            ssValue.Xor(obfuscate_key);
232
20.7k
            ssValue >> value;
233
20.7k
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
20.7k
        return true;
237
20.7k
    }
bool CDBWrapper::Read<std::pair<unsigned char, int>, CBlockFileInfo>(std::pair<unsigned char, int> const&, CBlockFileInfo&) const
Line
Count
Source
221
22.1k
    {
222
22.1k
        DataStream ssKey{};
223
22.1k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
22.1k
        ssKey << key;
225
22.1k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
22.1k
        if (!strValue) {
  Branch (226:13): [True: 22.1k, False: 0]
227
22.1k
            return false;
228
22.1k
        }
229
0
        try {
230
0
            DataStream ssValue{MakeByteSpan(*strValue)};
231
0
            ssValue.Xor(obfuscate_key);
232
0
            ssValue >> value;
233
0
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
0
        return true;
237
0
    }
bool CDBWrapper::Read<unsigned char, int>(unsigned char const&, int&) const
Line
Count
Source
221
11.0k
    {
222
11.0k
        DataStream ssKey{};
223
11.0k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
11.0k
        ssKey << key;
225
11.0k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
11.0k
        if (!strValue) {
  Branch (226:13): [True: 11.0k, False: 0]
227
11.0k
            return false;
228
11.0k
        }
229
0
        try {
230
0
            DataStream ssValue{MakeByteSpan(*strValue)};
231
0
            ssValue.Xor(obfuscate_key);
232
0
            ssValue >> value;
233
0
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
0
        return true;
237
0
    }
bool CDBWrapper::Read<std::pair<unsigned char, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, unsigned char>(std::pair<unsigned char, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, unsigned char&) const
Line
Count
Source
221
11.0k
    {
222
11.0k
        DataStream ssKey{};
223
11.0k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
11.0k
        ssKey << key;
225
11.0k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
11.0k
        if (!strValue) {
  Branch (226:13): [True: 11.0k, False: 0]
227
11.0k
            return false;
228
11.0k
        }
229
0
        try {
230
0
            DataStream ssValue{MakeByteSpan(*strValue)};
231
0
            ssValue.Xor(obfuscate_key);
232
0
            ssValue >> value;
233
0
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
0
        return true;
237
0
    }
txdb.cpp:bool CDBWrapper::Read<(anonymous namespace)::CoinEntry, Coin>((anonymous namespace)::CoinEntry const&, Coin&) const
Line
Count
Source
221
4.86M
    {
222
4.86M
        DataStream ssKey{};
223
4.86M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
4.86M
        ssKey << key;
225
4.86M
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
4.86M
        if (!strValue) {
  Branch (226:13): [True: 4.86M, False: 0]
227
4.86M
            return false;
228
4.86M
        }
229
0
        try {
230
0
            DataStream ssValue{MakeByteSpan(*strValue)};
231
0
            ssValue.Xor(obfuscate_key);
232
0
            ssValue >> value;
233
0
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
0
        return true;
237
0
    }
bool CDBWrapper::Read<unsigned char, uint256>(unsigned char const&, uint256&) const
Line
Count
Source
221
62.4k
    {
222
62.4k
        DataStream ssKey{};
223
62.4k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
62.4k
        ssKey << key;
225
62.4k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
62.4k
        if (!strValue) {
  Branch (226:13): [True: 44.3k, False: 18.1k]
227
44.3k
            return false;
228
44.3k
        }
229
18.1k
        try {
230
18.1k
            DataStream ssValue{MakeByteSpan(*strValue)};
231
18.1k
            ssValue.Xor(obfuscate_key);
232
18.1k
            ssValue >> value;
233
18.1k
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
18.1k
        return true;
237
18.1k
    }
bool CDBWrapper::Read<unsigned char, std::vector<uint256, std::allocator<uint256> > >(unsigned char const&, std::vector<uint256, std::allocator<uint256> >&) const
Line
Count
Source
221
22.1k
    {
222
22.1k
        DataStream ssKey{};
223
22.1k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
22.1k
        ssKey << key;
225
22.1k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
22.1k
        if (!strValue) {
  Branch (226:13): [True: 22.1k, False: 0]
227
22.1k
            return false;
228
22.1k
        }
229
0
        try {
230
0
            DataStream ssValue{MakeByteSpan(*strValue)};
231
0
            ssValue.Xor(obfuscate_key);
232
0
            ssValue >> value;
233
0
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
0
        return true;
237
0
    }
bool CDBWrapper::Read<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<unsigned char, std::allocator<unsigned char> >&) const
Line
Count
Source
221
33.2k
    {
222
33.2k
        DataStream ssKey{};
223
33.2k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
33.2k
        ssKey << key;
225
33.2k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
33.2k
        if (!strValue) {
  Branch (226:13): [True: 33.2k, False: 0]
227
33.2k
            return false;
228
33.2k
        }
229
0
        try {
230
0
            DataStream ssValue{MakeByteSpan(*strValue)};
231
0
            ssValue.Xor(obfuscate_key);
232
0
            ssValue >> value;
233
0
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
0
        return true;
237
0
    }
bool CDBWrapper::Read<unsigned char, CBlockLocator>(unsigned char const&, CBlockLocator&) const
Line
Count
Source
221
11.0k
    {
222
11.0k
        DataStream ssKey{};
223
11.0k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
11.0k
        ssKey << key;
225
11.0k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
11.0k
        if (!strValue) {
  Branch (226:13): [True: 11.0k, False: 0]
227
11.0k
            return false;
228
11.0k
        }
229
0
        try {
230
0
            DataStream ssValue{MakeByteSpan(*strValue)};
231
0
            ssValue.Xor(obfuscate_key);
232
0
            ssValue >> value;
233
0
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
0
        return true;
237
0
    }
Unexecuted instantiation: blockfilterindex.cpp:bool CDBWrapper::Read<(anonymous namespace)::DBHashKey, (anonymous namespace)::DBVal>((anonymous namespace)::DBHashKey const&, (anonymous namespace)::DBVal&) const
bool CDBWrapper::Read<unsigned char, FlatFilePos>(unsigned char const&, FlatFilePos&) const
Line
Count
Source
221
11.0k
    {
222
11.0k
        DataStream ssKey{};
223
11.0k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
11.0k
        ssKey << key;
225
11.0k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
11.0k
        if (!strValue) {
  Branch (226:13): [True: 11.0k, False: 0]
227
11.0k
            return false;
228
11.0k
        }
229
0
        try {
230
0
            DataStream ssValue{MakeByteSpan(*strValue)};
231
0
            ssValue.Xor(obfuscate_key);
232
0
            ssValue >> value;
233
0
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
0
        return true;
237
0
    }
blockfilterindex.cpp:bool CDBWrapper::Read<(anonymous namespace)::DBHeightKey, std::pair<uint256, (anonymous namespace)::DBVal> >((anonymous namespace)::DBHeightKey const&, std::pair<uint256, (anonymous namespace)::DBVal>&) const
Line
Count
Source
221
2.62k
    {
222
2.62k
        DataStream ssKey{};
223
2.62k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
2.62k
        ssKey << key;
225
2.62k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
2.62k
        if (!strValue) {
  Branch (226:13): [True: 0, False: 2.62k]
227
0
            return false;
228
0
        }
229
2.62k
        try {
230
2.62k
            DataStream ssValue{MakeByteSpan(*strValue)};
231
2.62k
            ssValue.Xor(obfuscate_key);
232
2.62k
            ssValue >> value;
233
2.62k
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
2.62k
        return true;
237
2.62k
    }
Unexecuted instantiation: coinstatsindex.cpp:bool CDBWrapper::Read<(anonymous namespace)::DBHashKey, (anonymous namespace)::DBVal>((anonymous namespace)::DBHashKey const&, (anonymous namespace)::DBVal&) const
Unexecuted instantiation: coinstatsindex.cpp:bool CDBWrapper::Read<(anonymous namespace)::DBHeightKey, std::pair<uint256, (anonymous namespace)::DBVal> >((anonymous namespace)::DBHeightKey const&, std::pair<uint256, (anonymous namespace)::DBVal>&) const
Unexecuted instantiation: coinstatsindex.cpp:bool CDBWrapper::Read<(anonymous namespace)::DBHashKey, std::pair<uint256, (anonymous namespace)::DBVal> >((anonymous namespace)::DBHashKey const&, std::pair<uint256, (anonymous namespace)::DBVal>&) const
Unexecuted instantiation: bool CDBWrapper::Read<unsigned char, MuHash3072>(unsigned char const&, MuHash3072&) const
Unexecuted instantiation: bool CDBWrapper::Read<std::pair<unsigned char, uint256>, CDiskTxPos>(std::pair<unsigned char, uint256> const&, CDiskTxPos&) const
238
239
    template <typename K, typename V>
240
    bool Write(const K& key, const V& value, bool fSync = false)
241
2.24M
    {
242
2.24M
        CDBBatch batch(*this);
243
2.24M
        batch.Write(key, value);
244
2.24M
        return WriteBatch(batch, fSync);
245
2.24M
    }
Unexecuted instantiation: bool CDBWrapper::Write<unsigned char, unsigned char>(unsigned char const&, unsigned char const&, bool)
Unexecuted instantiation: bool CDBWrapper::Write<std::pair<unsigned char, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, unsigned char>(std::pair<unsigned char, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, unsigned char const&, bool)
bool CDBWrapper::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<unsigned char, std::allocator<unsigned char> > const&, bool)
Line
Count
Source
241
11.0k
    {
242
11.0k
        CDBBatch batch(*this);
243
11.0k
        batch.Write(key, value);
244
11.0k
        return WriteBatch(batch, fSync);
245
11.0k
    }
blockfilterindex.cpp:bool CDBWrapper::Write<(anonymous namespace)::DBHeightKey, std::pair<uint256, (anonymous namespace)::DBVal> >((anonymous namespace)::DBHeightKey const&, std::pair<uint256, (anonymous namespace)::DBVal> const&, bool)
Line
Count
Source
241
2.23M
    {
242
2.23M
        CDBBatch batch(*this);
243
2.23M
        batch.Write(key, value);
244
2.23M
        return WriteBatch(batch, fSync);
245
2.23M
    }
Unexecuted instantiation: coinstatsindex.cpp:bool CDBWrapper::Write<(anonymous namespace)::DBHeightKey, std::pair<uint256, (anonymous namespace)::DBVal> >((anonymous namespace)::DBHeightKey const&, std::pair<uint256, (anonymous namespace)::DBVal> const&, bool)
246
247
    //! @returns filesystem path to the on-disk data.
248
0
    std::optional<fs::path> StoragePath() {
249
0
        if (m_is_memory) {
  Branch (249:13): [True: 0, False: 0]
250
0
            return {};
251
0
        }
252
0
        return m_path;
253
0
    }
254
255
    template <typename K>
256
    bool Exists(const K& key) const
257
22.1k
    {
258
22.1k
        DataStream ssKey{};
259
22.1k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
260
22.1k
        ssKey << key;
261
22.1k
        return ExistsImpl(ssKey);
262
22.1k
    }
bool CDBWrapper::Exists<unsigned char>(unsigned char const&) const
Line
Count
Source
257
22.1k
    {
258
22.1k
        DataStream ssKey{};
259
22.1k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
260
22.1k
        ssKey << key;
261
22.1k
        return ExistsImpl(ssKey);
262
22.1k
    }
Unexecuted instantiation: txdb.cpp:bool CDBWrapper::Exists<(anonymous namespace)::CoinEntry>((anonymous namespace)::CoinEntry const&) const
263
264
    template <typename K>
265
    bool Erase(const K& key, bool fSync = false)
266
0
    {
267
0
        CDBBatch batch(*this);
268
0
        batch.Erase(key);
269
0
        return WriteBatch(batch, fSync);
270
0
    }
271
272
    bool WriteBatch(CDBBatch& batch, bool fSync = false);
273
274
    // Get an estimate of LevelDB memory usage (in bytes).
275
    size_t DynamicMemoryUsage() const;
276
277
    CDBIterator* NewIterator();
278
279
    /**
280
     * Return true if the database managed by this class contains no entries.
281
     */
282
    bool IsEmpty();
283
284
    template<typename K>
285
    size_t EstimateSize(const K& key_begin, const K& key_end) const
286
0
    {
287
0
        DataStream ssKey1{}, ssKey2{};
288
0
        ssKey1.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
289
0
        ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
290
0
        ssKey1 << key_begin;
291
0
        ssKey2 << key_end;
292
0
        return EstimateSizeImpl(ssKey1, ssKey2);
293
0
    }
294
};
295
296
#endif // BITCOIN_DBWRAPPER_H