Coverage Report

Created: 2026-03-23 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bitcoin-core/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
22
static const size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
23
static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;
24
static const size_t DBWRAPPER_MAX_FILE_SIZE = 32 << 20; // 32 MiB
25
26
//! User-controlled performance and debug options.
27
struct DBOptions {
28
    //! Compact database on startup.
29
    bool force_compact = false;
30
};
31
32
//! Application-specific storage settings.
33
struct DBParams {
34
    //! Location in the filesystem where leveldb data will be stored.
35
    fs::path path;
36
    //! Configures various leveldb cache settings.
37
    size_t cache_bytes;
38
    //! If true, use leveldb's memory environment.
39
    bool memory_only = false;
40
    //! If true, remove all existing data.
41
    bool wipe_data = false;
42
    //! If true, store data obfuscated via simple XOR. If false, XOR with a
43
    //! zero'd byte array.
44
    bool obfuscate = false;
45
    //! Passed-through options.
46
    DBOptions options{};
47
};
48
49
class dbwrapper_error : public std::runtime_error
50
{
51
public:
52
0
    explicit dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {}
53
};
54
55
class CDBWrapper;
56
57
/** These should be considered an implementation detail of the specific database.
58
 */
59
namespace dbwrapper_private {
60
61
/** Work around circular dependency, as well as for testing in dbwrapper_tests.
62
 * Database obfuscation should be considered an implementation detail of the
63
 * specific database.
64
 */
65
const Obfuscation& GetObfuscation(const CDBWrapper&);
66
}; // namespace dbwrapper_private
67
68
bool DestroyDB(const std::string& path_str);
69
70
/** Batch of changes queued to be written to a CDBWrapper */
71
class CDBBatch
72
{
73
    friend class CDBWrapper;
74
75
private:
76
    const CDBWrapper &parent;
77
78
    struct WriteBatchImpl;
79
    const std::unique_ptr<WriteBatchImpl> m_impl_batch;
80
81
    DataStream ssKey{};
82
    DataStream ssValue{};
83
84
    void WriteImpl(std::span<const std::byte> key, DataStream& ssValue);
85
    void EraseImpl(std::span<const std::byte> key);
86
87
public:
88
    /**
89
     * @param[in] _parent   CDBWrapper that this batch is to be submitted to
90
     */
91
    explicit CDBBatch(const CDBWrapper& _parent);
92
    ~CDBBatch();
93
    void Clear();
94
95
    template <typename K, typename V>
96
    void Write(const K& key, const V& value)
97
8.21M
    {
98
8.21M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
99
8.21M
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
100
8.21M
        ssKey << key;
101
8.21M
        ssValue << value;
102
8.21M
        WriteImpl(ssKey, ssValue);
103
8.21M
        ssKey.clear();
104
8.21M
        ssValue.clear();
105
8.21M
    }
void CDBBatch::Write<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, Obfuscation>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Obfuscation const&)
Line
Count
Source
97
14.2k
    {
98
14.2k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
99
14.2k
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
100
14.2k
        ssKey << key;
101
14.2k
        ssValue << value;
102
14.2k
        WriteImpl(ssKey, ssValue);
103
14.2k
        ssKey.clear();
104
14.2k
        ssValue.clear();
105
14.2k
    }
Unexecuted instantiation: void CDBBatch::Write<unsigned char, CBlockLocator>(unsigned char const&, CBlockLocator const&)
Unexecuted instantiation: void CDBBatch::Write<unsigned char, FlatFilePos>(unsigned char const&, FlatFilePos const&)
Unexecuted instantiation: blockfilterindex.cpp:void CDBBatch::Write<index_util::DBHeightKey, std::__1::pair<uint256, (anonymous namespace)::DBVal> >(index_util::DBHeightKey const&, std::__1::pair<uint256, (anonymous namespace)::DBVal> const&)
Unexecuted instantiation: blockfilterindex.cpp:void CDBBatch::Write<index_util::DBHashKey, (anonymous namespace)::DBVal>(index_util::DBHashKey const&, (anonymous namespace)::DBVal const&)
Unexecuted instantiation: void CDBBatch::Write<std::__1::pair<unsigned char, uint256>, CDiskTxPos>(std::__1::pair<unsigned char, uint256> const&, CDiskTxPos const&)
Unexecuted instantiation: void CDBBatch::Write<char [12], std::__1::pair<unsigned long, unsigned long> >(char const (&) [12], std::__1::pair<unsigned long, unsigned long> const&)
Unexecuted instantiation: void CDBBatch::Write<DBKey, char [1]>(DBKey const&, char const (&) [1])
Unexecuted instantiation: coinstatsindex.cpp:void CDBBatch::Write<index_util::DBHeightKey, std::__1::pair<uint256, (anonymous namespace)::DBVal> >(index_util::DBHeightKey const&, std::__1::pair<uint256, (anonymous namespace)::DBVal> const&)
Unexecuted instantiation: coinstatsindex.cpp:void CDBBatch::Write<index_util::DBHashKey, (anonymous namespace)::DBVal>(index_util::DBHashKey const&, (anonymous namespace)::DBVal const&)
Unexecuted instantiation: void CDBBatch::Write<unsigned char, MuHash3072>(unsigned char const&, MuHash3072 const&)
void CDBBatch::Write<unsigned char, unsigned char>(unsigned char const&, unsigned char const&)
Line
Count
Source
97
1.45k
    {
98
1.45k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
99
1.45k
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
100
1.45k
        ssKey << key;
101
1.45k
        ssValue << value;
102
1.45k
        WriteImpl(ssKey, ssValue);
103
1.45k
        ssKey.clear();
104
1.45k
        ssValue.clear();
105
1.45k
    }
void CDBBatch::Write<std::__1::pair<unsigned char, int>, kernel::CBlockFileInfo>(std::__1::pair<unsigned char, int> const&, kernel::CBlockFileInfo const&)
Line
Count
Source
97
126k
    {
98
126k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
99
126k
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
100
126k
        ssKey << key;
101
126k
        ssValue << value;
102
126k
        WriteImpl(ssKey, ssValue);
103
126k
        ssKey.clear();
104
126k
        ssValue.clear();
105
126k
    }
void CDBBatch::Write<unsigned char, int>(unsigned char const&, int const&)
Line
Count
Source
97
128k
    {
98
128k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
99
128k
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
100
128k
        ssKey << key;
101
128k
        ssValue << value;
102
128k
        WriteImpl(ssKey, ssValue);
103
128k
        ssKey.clear();
104
128k
        ssValue.clear();
105
128k
    }
void CDBBatch::Write<std::__1::pair<unsigned char, uint256>, CDiskBlockIndex>(std::__1::pair<unsigned char, uint256> const&, CDiskBlockIndex const&)
Line
Count
Source
97
2.01M
    {
98
2.01M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
99
2.01M
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
100
2.01M
        ssKey << key;
101
2.01M
        ssValue << value;
102
2.01M
        WriteImpl(ssKey, ssValue);
103
2.01M
        ssKey.clear();
104
2.01M
        ssValue.clear();
105
2.01M
    }
void CDBBatch::Write<std::__1::pair<unsigned char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, unsigned char>(std::__1::pair<unsigned char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const&, unsigned char const&)
Line
Count
Source
97
2.91k
    {
98
2.91k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
99
2.91k
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
100
2.91k
        ssKey << key;
101
2.91k
        ssValue << value;
102
2.91k
        WriteImpl(ssKey, ssValue);
103
2.91k
        ssKey.clear();
104
2.91k
        ssValue.clear();
105
2.91k
    }
void CDBBatch::Write<unsigned char, std::__1::vector<uint256, std::__1::allocator<uint256> > >(unsigned char const&, std::__1::vector<uint256, std::__1::allocator<uint256> > const&)
Line
Count
Source
97
2.87M
    {
98
2.87M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
99
2.87M
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
100
2.87M
        ssKey << key;
101
2.87M
        ssValue << value;
102
2.87M
        WriteImpl(ssKey, ssValue);
103
2.87M
        ssKey.clear();
104
2.87M
        ssValue.clear();
105
2.87M
    }
txdb.cpp:void CDBBatch::Write<(anonymous namespace)::CoinEntry, Coin>((anonymous namespace)::CoinEntry const&, Coin const&)
Line
Count
Source
97
166k
    {
98
166k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
99
166k
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
100
166k
        ssKey << key;
101
166k
        ssValue << value;
102
166k
        WriteImpl(ssKey, ssValue);
103
166k
        ssKey.clear();
104
166k
        ssValue.clear();
105
166k
    }
void CDBBatch::Write<unsigned char, uint256>(unsigned char const&, uint256 const&)
Line
Count
Source
97
2.87M
    {
98
2.87M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
99
2.87M
        ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
100
2.87M
        ssKey << key;
101
2.87M
        ssValue << value;
102
2.87M
        WriteImpl(ssKey, ssValue);
103
2.87M
        ssKey.clear();
104
2.87M
        ssValue.clear();
105
2.87M
    }
106
107
    template <typename K>
108
    void Erase(const K& key)
109
5.78M
    {
110
5.78M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
111
5.78M
        ssKey << key;
112
5.78M
        EraseImpl(ssKey);
113
5.78M
        ssKey.clear();
114
5.78M
    }
Unexecuted instantiation: void CDBBatch::Erase<DBKey>(DBKey const&)
void CDBBatch::Erase<unsigned char>(unsigned char const&)
Line
Count
Source
109
5.76M
    {
110
5.76M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
111
5.76M
        ssKey << key;
112
5.76M
        EraseImpl(ssKey);
113
5.76M
        ssKey.clear();
114
5.76M
    }
txdb.cpp:void CDBBatch::Erase<(anonymous namespace)::CoinEntry>((anonymous namespace)::CoinEntry const&)
Line
Count
Source
109
24.9k
    {
110
24.9k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
111
24.9k
        ssKey << key;
112
24.9k
        EraseImpl(ssKey);
113
24.9k
        ssKey.clear();
114
24.9k
    }
115
116
    size_t ApproximateSize() const;
117
};
118
119
class CDBIterator
120
{
121
public:
122
    struct IteratorImpl;
123
124
private:
125
    const CDBWrapper &parent;
126
    const std::unique_ptr<IteratorImpl> m_impl_iter;
127
128
    void SeekImpl(std::span<const std::byte> key);
129
    std::span<const std::byte> GetKeyImpl() const;
130
    std::span<const std::byte> GetValueImpl() const;
131
132
public:
133
134
    /**
135
     * @param[in] _parent          Parent CDBWrapper instance.
136
     * @param[in] _piter           The original leveldb iterator.
137
     */
138
    CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter);
139
    ~CDBIterator();
140
141
    bool Valid() const;
142
143
    void SeekToFirst();
144
145
140k
    template<typename K> void Seek(const K& key) {
146
140k
        DataStream ssKey{};
147
140k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
148
140k
        ssKey << key;
149
140k
        SeekImpl(ssKey);
150
140k
    }
Unexecuted instantiation: void CDBIterator::Seek<std::__1::pair<unsigned char, unsigned long> >(std::__1::pair<unsigned char, unsigned long> const&)
Unexecuted instantiation: void CDBIterator::Seek<index_util::DBHeightKey>(index_util::DBHeightKey const&)
void CDBIterator::Seek<std::__1::pair<unsigned char, uint256> >(std::__1::pair<unsigned char, uint256> const&)
Line
Count
Source
145
12.2k
    template<typename K> void Seek(const K& key) {
146
12.2k
        DataStream ssKey{};
147
12.2k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
148
12.2k
        ssKey << key;
149
12.2k
        SeekImpl(ssKey);
150
12.2k
    }
void CDBIterator::Seek<unsigned char>(unsigned char const&)
Line
Count
Source
145
128k
    template<typename K> void Seek(const K& key) {
146
128k
        DataStream ssKey{};
147
128k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
148
128k
        ssKey << key;
149
128k
        SeekImpl(ssKey);
150
128k
    }
151
152
    void Next();
153
154
5.31M
    template<typename K> bool GetKey(K& key) {
155
5.31M
        try {
156
5.31M
            DataStream ssKey{GetKeyImpl()};
157
5.31M
            ssKey >> key;
158
5.31M
        } catch (const std::exception&) {
159
1.45k
            return false;
160
1.45k
        }
161
5.31M
        return true;
162
5.31M
    }
Unexecuted instantiation: bool CDBIterator::GetKey<DBKey>(DBKey&)
Unexecuted instantiation: bool CDBIterator::GetKey<index_util::DBHeightKey>(index_util::DBHeightKey&)
bool CDBIterator::GetKey<std::__1::pair<unsigned char, uint256> >(std::__1::pair<unsigned char, uint256>&)
Line
Count
Source
154
2.91k
    template<typename K> bool GetKey(K& key) {
155
2.91k
        try {
156
2.91k
            DataStream ssKey{GetKeyImpl()};
157
2.91k
            ssKey >> key;
158
2.91k
        } catch (const std::exception&) {
159
1.45k
            return false;
160
1.45k
        }
161
1.45k
        return true;
162
2.91k
    }
txdb.cpp:bool CDBIterator::GetKey<(anonymous namespace)::CoinEntry>((anonymous namespace)::CoinEntry&)
Line
Count
Source
154
5.31M
    template<typename K> bool GetKey(K& key) {
155
5.31M
        try {
156
5.31M
            DataStream ssKey{GetKeyImpl()};
157
5.31M
            ssKey >> key;
158
5.31M
        } catch (const std::exception&) {
159
0
            return false;
160
0
        }
161
5.31M
        return true;
162
5.31M
    }
163
164
5.31M
    template<typename V> bool GetValue(V& value) {
165
5.31M
        try {
166
5.31M
            DataStream ssValue{GetValueImpl()};
167
5.31M
            dbwrapper_private::GetObfuscation(parent)(ssValue);
168
5.31M
            ssValue >> value;
169
5.31M
        } catch (const std::exception&) {
170
0
            return false;
171
0
        }
172
5.31M
        return true;
173
5.31M
    }
Unexecuted instantiation: blockfilterindex.cpp:bool CDBIterator::GetValue<std::__1::pair<uint256, (anonymous namespace)::DBVal> >(std::__1::pair<uint256, (anonymous namespace)::DBVal>&)
Unexecuted instantiation: coinstatsindex.cpp:bool CDBIterator::GetValue<std::__1::pair<uint256, (anonymous namespace)::DBVal> >(std::__1::pair<uint256, (anonymous namespace)::DBVal>&)
bool CDBIterator::GetValue<CDiskBlockIndex>(CDiskBlockIndex&)
Line
Count
Source
164
1.45k
    template<typename V> bool GetValue(V& value) {
165
1.45k
        try {
166
1.45k
            DataStream ssValue{GetValueImpl()};
167
1.45k
            dbwrapper_private::GetObfuscation(parent)(ssValue);
168
1.45k
            ssValue >> value;
169
1.45k
        } catch (const std::exception&) {
170
0
            return false;
171
0
        }
172
1.45k
        return true;
173
1.45k
    }
bool CDBIterator::GetValue<Coin>(Coin&)
Line
Count
Source
164
5.31M
    template<typename V> bool GetValue(V& value) {
165
5.31M
        try {
166
5.31M
            DataStream ssValue{GetValueImpl()};
167
5.31M
            dbwrapper_private::GetObfuscation(parent)(ssValue);
168
5.31M
            ssValue >> value;
169
5.31M
        } catch (const std::exception&) {
170
0
            return false;
171
0
        }
172
5.31M
        return true;
173
5.31M
    }
174
};
175
176
struct LevelDBContext;
177
178
class CDBWrapper
179
{
180
    friend const Obfuscation& dbwrapper_private::GetObfuscation(const CDBWrapper&);
181
private:
182
    //! holds all leveldb-specific fields of this class
183
    std::unique_ptr<LevelDBContext> m_db_context;
184
185
    //! the name of this database
186
    std::string m_name;
187
188
    //! optional XOR-obfuscation of the database
189
    Obfuscation m_obfuscation;
190
191
    //! obfuscation key storage key, null-prefixed to avoid collisions
192
    inline static const std::string OBFUSCATION_KEY{"\000obfuscate_key", 14}; // explicit size to avoid truncation at leading \0
193
194
    std::optional<std::string> ReadImpl(std::span<const std::byte> key) const;
195
    bool ExistsImpl(std::span<const std::byte> key) const;
196
    size_t EstimateSizeImpl(std::span<const std::byte> key1, std::span<const std::byte> key2) const;
197
20.0M
    auto& DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); }
198
199
public:
200
    CDBWrapper(const DBParams& params);
201
    ~CDBWrapper();
202
203
    CDBWrapper(const CDBWrapper&) = delete;
204
    CDBWrapper& operator=(const CDBWrapper&) = delete;
205
206
    template <typename K, typename V>
207
    bool Read(const K& key, V& value) const
208
6.44M
    {
209
6.44M
        DataStream ssKey{};
210
6.44M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
211
6.44M
        ssKey << key;
212
6.44M
        std::optional<std::string> strValue{ReadImpl(ssKey)};
213
6.44M
        if (!strValue) {
214
3.21M
            return false;
215
3.21M
        }
216
3.23M
        try {
217
3.23M
            std::span ssValue{MakeWritableByteSpan(*strValue)};
218
3.23M
            m_obfuscation(ssValue);
219
3.23M
            SpanReader{ssValue} >> value;
220
3.23M
        } catch (const std::exception&) {
221
0
            return false;
222
0
        }
223
3.23M
        return true;
224
3.23M
    }
bool CDBWrapper::Read<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, Obfuscation>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Obfuscation&) const
Line
Count
Source
208
28.4k
    {
209
28.4k
        DataStream ssKey{};
210
28.4k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
211
28.4k
        ssKey << key;
212
28.4k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
213
28.4k
        if (!strValue) {
214
28.4k
            return false;
215
28.4k
        }
216
0
        try {
217
0
            std::span ssValue{MakeWritableByteSpan(*strValue)};
218
0
            m_obfuscation(ssValue);
219
0
            SpanReader{ssValue} >> value;
220
0
        } catch (const std::exception&) {
221
0
            return false;
222
0
        }
223
0
        return true;
224
0
    }
Unexecuted instantiation: bool CDBWrapper::Read<unsigned char, CBlockLocator>(unsigned char const&, CBlockLocator&) const
Unexecuted instantiation: blockfilterindex.cpp:bool CDBWrapper::Read<index_util::DBHashKey, (anonymous namespace)::DBVal>(index_util::DBHashKey const&, (anonymous namespace)::DBVal&) const
Unexecuted instantiation: bool CDBWrapper::Read<unsigned char, FlatFilePos>(unsigned char const&, FlatFilePos&) const
Unexecuted instantiation: blockfilterindex.cpp:bool CDBWrapper::Read<index_util::DBHeightKey, std::__1::pair<uint256, (anonymous namespace)::DBVal> >(index_util::DBHeightKey const&, std::__1::pair<uint256, (anonymous namespace)::DBVal>&) const
Unexecuted instantiation: bool CDBWrapper::Read<std::__1::pair<unsigned char, uint256>, CDiskTxPos>(std::__1::pair<unsigned char, uint256> const&, CDiskTxPos&) const
Unexecuted instantiation: bool CDBWrapper::Read<char [12], std::__1::pair<unsigned long, unsigned long> >(char const (&) [12], std::__1::pair<unsigned long, unsigned long>&) const
Unexecuted instantiation: coinstatsindex.cpp:bool CDBWrapper::Read<index_util::DBHashKey, (anonymous namespace)::DBVal>(index_util::DBHashKey const&, (anonymous namespace)::DBVal&) const
Unexecuted instantiation: bool CDBWrapper::Read<unsigned char, MuHash3072>(unsigned char const&, MuHash3072&) const
Unexecuted instantiation: coinstatsindex.cpp:bool CDBWrapper::Read<index_util::DBHeightKey, std::__1::pair<uint256, (anonymous namespace)::DBVal> >(index_util::DBHeightKey const&, std::__1::pair<uint256, (anonymous namespace)::DBVal>&) const
Unexecuted instantiation: coinstatsindex.cpp:bool CDBWrapper::Read<index_util::DBHashKey, std::__1::pair<uint256, (anonymous namespace)::DBVal> >(index_util::DBHashKey const&, std::__1::pair<uint256, (anonymous namespace)::DBVal>&) const
bool CDBWrapper::Read<std::__1::pair<unsigned char, int>, kernel::CBlockFileInfo>(std::__1::pair<unsigned char, int> const&, kernel::CBlockFileInfo&) const
Line
Count
Source
208
30.6k
    {
209
30.6k
        DataStream ssKey{};
210
30.6k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
211
30.6k
        ssKey << key;
212
30.6k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
213
30.6k
        if (!strValue) {
214
10.8k
            return false;
215
10.8k
        }
216
19.8k
        try {
217
19.8k
            std::span ssValue{MakeWritableByteSpan(*strValue)};
218
19.8k
            m_obfuscation(ssValue);
219
19.8k
            SpanReader{ssValue} >> value;
220
19.8k
        } catch (const std::exception&) {
221
0
            return false;
222
0
        }
223
19.8k
        return true;
224
19.8k
    }
bool CDBWrapper::Read<unsigned char, int>(unsigned char const&, int&) const
Line
Count
Source
208
6.86k
    {
209
6.86k
        DataStream ssKey{};
210
6.86k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
211
6.86k
        ssKey << key;
212
6.86k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
213
6.86k
        if (!strValue) {
214
5.41k
            return false;
215
5.41k
        }
216
1.45k
        try {
217
1.45k
            std::span ssValue{MakeWritableByteSpan(*strValue)};
218
1.45k
            m_obfuscation(ssValue);
219
1.45k
            SpanReader{ssValue} >> value;
220
1.45k
        } catch (const std::exception&) {
221
0
            return false;
222
0
        }
223
1.45k
        return true;
224
1.45k
    }
bool CDBWrapper::Read<std::__1::pair<unsigned char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, unsigned char>(std::__1::pair<unsigned char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const&, unsigned char&) const
Line
Count
Source
208
8.32k
    {
209
8.32k
        DataStream ssKey{};
210
8.32k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
211
8.32k
        ssKey << key;
212
8.32k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
213
8.32k
        if (!strValue) {
214
5.41k
            return false;
215
5.41k
        }
216
2.91k
        try {
217
2.91k
            std::span ssValue{MakeWritableByteSpan(*strValue)};
218
2.91k
            m_obfuscation(ssValue);
219
2.91k
            SpanReader{ssValue} >> value;
220
2.91k
        } catch (const std::exception&) {
221
0
            return false;
222
0
        }
223
2.91k
        return true;
224
2.91k
    }
txdb.cpp:bool CDBWrapper::Read<(anonymous namespace)::CoinEntry, Coin>((anonymous namespace)::CoinEntry const&, Coin&) const
Line
Count
Source
208
3.31M
    {
209
3.31M
        DataStream ssKey{};
210
3.31M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
211
3.31M
        ssKey << key;
212
3.31M
        std::optional<std::string> strValue{ReadImpl(ssKey)};
213
3.31M
        if (!strValue) {
214
3.09M
            return false;
215
3.09M
        }
216
217k
        try {
217
217k
            std::span ssValue{MakeWritableByteSpan(*strValue)};
218
217k
            m_obfuscation(ssValue);
219
217k
            SpanReader{ssValue} >> value;
220
217k
        } catch (const std::exception&) {
221
0
            return false;
222
0
        }
223
217k
        return true;
224
217k
    }
bool CDBWrapper::Read<unsigned char, uint256>(unsigned char const&, uint256&) const
Line
Count
Source
208
3.03M
    {
209
3.03M
        DataStream ssKey{};
210
3.03M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
211
3.03M
        ssKey << key;
212
3.03M
        std::optional<std::string> strValue{ReadImpl(ssKey)};
213
3.03M
        if (!strValue) {
214
33.1k
            return false;
215
33.1k
        }
216
2.99M
        try {
217
2.99M
            std::span ssValue{MakeWritableByteSpan(*strValue)};
218
2.99M
            m_obfuscation(ssValue);
219
2.99M
            SpanReader{ssValue} >> value;
220
2.99M
        } catch (const std::exception&) {
221
0
            return false;
222
0
        }
223
2.99M
        return true;
224
2.99M
    }
bool CDBWrapper::Read<unsigned char, std::__1::vector<uint256, std::__1::allocator<uint256> > >(unsigned char const&, std::__1::vector<uint256, std::__1::allocator<uint256> >&) const
Line
Count
Source
208
30.9k
    {
209
30.9k
        DataStream ssKey{};
210
30.9k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
211
30.9k
        ssKey << key;
212
30.9k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
213
30.9k
        if (!strValue) {
214
30.9k
            return false;
215
30.9k
        }
216
0
        try {
217
0
            std::span ssValue{MakeWritableByteSpan(*strValue)};
218
0
            m_obfuscation(ssValue);
219
0
            SpanReader{ssValue} >> value;
220
0
        } catch (const std::exception&) {
221
0
            return false;
222
0
        }
223
0
        return true;
224
0
    }
225
226
    template <typename K, typename V>
227
    void Write(const K& key, const V& value, bool fSync = false)
228
18.6k
    {
229
18.6k
        CDBBatch batch(*this);
230
18.6k
        batch.Write(key, value);
231
18.6k
        WriteBatch(batch, fSync);
232
18.6k
    }
void CDBWrapper::Write<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, Obfuscation>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Obfuscation const&, bool)
Line
Count
Source
228
14.2k
    {
229
14.2k
        CDBBatch batch(*this);
230
14.2k
        batch.Write(key, value);
231
14.2k
        WriteBatch(batch, fSync);
232
14.2k
    }
Unexecuted instantiation: blockfilterindex.cpp:void CDBWrapper::Write<index_util::DBHeightKey, std::__1::pair<uint256, (anonymous namespace)::DBVal> >(index_util::DBHeightKey const&, std::__1::pair<uint256, (anonymous namespace)::DBVal> const&, bool)
Unexecuted instantiation: void CDBWrapper::Write<char [12], std::__1::pair<unsigned long, unsigned long> >(char const (&) [12], std::__1::pair<unsigned long, unsigned long> const&, bool)
Unexecuted instantiation: coinstatsindex.cpp:void CDBWrapper::Write<index_util::DBHeightKey, std::__1::pair<uint256, (anonymous namespace)::DBVal> >(index_util::DBHeightKey const&, std::__1::pair<uint256, (anonymous namespace)::DBVal> const&, bool)
void CDBWrapper::Write<unsigned char, unsigned char>(unsigned char const&, unsigned char const&, bool)
Line
Count
Source
228
1.45k
    {
229
1.45k
        CDBBatch batch(*this);
230
1.45k
        batch.Write(key, value);
231
1.45k
        WriteBatch(batch, fSync);
232
1.45k
    }
void CDBWrapper::Write<std::__1::pair<unsigned char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, unsigned char>(std::__1::pair<unsigned char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const&, unsigned char const&, bool)
Line
Count
Source
228
2.91k
    {
229
2.91k
        CDBBatch batch(*this);
230
2.91k
        batch.Write(key, value);
231
2.91k
        WriteBatch(batch, fSync);
232
2.91k
    }
233
234
    template <typename K>
235
    bool Exists(const K& key) const
236
15.2k
    {
237
15.2k
        DataStream ssKey{};
238
15.2k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
239
15.2k
        ssKey << key;
240
15.2k
        return ExistsImpl(ssKey);
241
15.2k
    }
bool CDBWrapper::Exists<unsigned char>(unsigned char const&) const
Line
Count
Source
236
8.32k
    {
237
8.32k
        DataStream ssKey{};
238
8.32k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
239
8.32k
        ssKey << key;
240
8.32k
        return ExistsImpl(ssKey);
241
8.32k
    }
txdb.cpp:bool CDBWrapper::Exists<(anonymous namespace)::CoinEntry>((anonymous namespace)::CoinEntry const&) const
Line
Count
Source
236
6.90k
    {
237
6.90k
        DataStream ssKey{};
238
6.90k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
239
6.90k
        ssKey << key;
240
6.90k
        return ExistsImpl(ssKey);
241
6.90k
    }
242
243
    template <typename K>
244
    void Erase(const K& key, bool fSync = false)
245
1.45k
    {
246
1.45k
        CDBBatch batch(*this);
247
1.45k
        batch.Erase(key);
248
1.45k
        WriteBatch(batch, fSync);
249
1.45k
    }
250
251
    void WriteBatch(CDBBatch& batch, bool fSync = false);
252
253
    // Get an estimate of LevelDB memory usage (in bytes).
254
    size_t DynamicMemoryUsage() const;
255
256
    CDBIterator* NewIterator();
257
258
    /**
259
     * Return true if the database managed by this class contains no entries.
260
     */
261
    bool IsEmpty();
262
263
    template<typename K>
264
    size_t EstimateSize(const K& key_begin, const K& key_end) const
265
134k
    {
266
134k
        DataStream ssKey1{}, ssKey2{};
267
134k
        ssKey1.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
268
134k
        ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
269
134k
        ssKey1 << key_begin;
270
134k
        ssKey2 << key_end;
271
134k
        return EstimateSizeImpl(ssKey1, ssKey2);
272
134k
    }
273
};
274
275
#endif // BITCOIN_DBWRAPPER_H