Coverage Report

Created: 2026-09-02 14:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/tmp/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/fs.h>
15
#include <util/obfuscation.h>
16
17
#include <cstddef>
18
#include <cstdint>
19
#include <exception>
20
#include <memory>
21
#include <optional>
22
#include <span>
23
#include <stdexcept>
24
#include <string>
25
26
namespace leveldb {
27
class Env;
28
} // namespace leveldb
29
30
inline constexpr size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
31
inline constexpr size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;
32
inline constexpr size_t DBWRAPPER_MAX_FILE_SIZE{32_MiB};
33
34
//! User-controlled performance and debug options.
35
struct DBOptions {
36
    //! Compact database on startup.
37
    bool force_compact = false;
38
};
39
40
//! Application-specific storage settings.
41
struct DBParams {
42
    //! Location in the filesystem where leveldb data will be stored.
43
    fs::path path;
44
    //! Configures various leveldb cache settings.
45
    uint64_t cache_bytes;
46
    //! If true, use leveldb's memory environment.
47
    bool memory_only = false;
48
    //! If true, remove all existing data.
49
    bool wipe_data = false;
50
    //! If true, store data obfuscated via simple XOR. If false, XOR with a
51
    //! zero'd byte array.
52
    bool obfuscate = false;
53
    //! If true, build a LevelDB bloom filter to accelerate point lookups.
54
    bool bloom_filter = true;
55
    //! Passed-through options.
56
    DBOptions options{};
57
    //! If non-null, use this as the leveldb::Env instead of the default.
58
    //! Caller retains ownership.
59
    leveldb::Env* testing_env = nullptr;
60
    //! Maximum LevelDB SST file size. Larger values reduce the frequency
61
    //! of compactions but increase their duration.
62
    size_t max_file_size = DBWRAPPER_MAX_FILE_SIZE;
63
};
64
65
class dbwrapper_error : public std::runtime_error
66
{
67
public:
68
10
    explicit dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {}
69
};
70
71
class CDBWrapper;
72
73
/** These should be considered an implementation detail of the specific database.
74
 */
75
namespace dbwrapper_private {
76
77
/** Work around circular dependency, as well as for testing in dbwrapper_tests.
78
 * Database obfuscation should be considered an implementation detail of the
79
 * specific database.
80
 */
81
const Obfuscation& GetObfuscation(const CDBWrapper&);
82
}; // namespace dbwrapper_private
83
84
bool DestroyDB(const std::string& path_str);
85
86
/** Batch of changes queued to be written to a CDBWrapper */
87
class CDBBatch
88
{
89
    friend class CDBWrapper;
90
91
private:
92
    const CDBWrapper &parent;
93
94
    struct WriteBatchImpl;
95
    const std::unique_ptr<WriteBatchImpl> m_impl_batch;
96
97
    DataStream m_key_scratch{};
98
    DataStream m_value_scratch{};
99
100
    void WriteImpl(std::span<const std::byte> key, DataStream& value);
101
    void EraseImpl(std::span<const std::byte> key);
102
103
public:
104
    /**
105
     * @param[in] _parent   CDBWrapper that this batch is to be submitted to
106
     */
107
    explicit CDBBatch(const CDBWrapper& _parent);
108
    ~CDBBatch();
109
    void Clear();
110
111
    template <typename K, typename V>
112
    void Write(const K& key, const V& value)
113
445k
    {
114
445k
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
445k
        m_key_scratch << key;
116
445k
        m_value_scratch << value;
117
445k
        WriteImpl(m_key_scratch, m_value_scratch);
118
445k
    }
void CDBBatch::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, uint256>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, uint256 const&)
Line
Count
Source
113
8
    {
114
8
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
8
        m_key_scratch << key;
116
8
        m_value_scratch << value;
117
8
        WriteImpl(m_key_scratch, m_value_scratch);
118
8
    }
void CDBBatch::Write<unsigned char, unsigned int>(unsigned char const&, unsigned int const&)
Line
Count
Source
113
258
    {
114
258
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
258
        m_key_scratch << key;
116
258
        m_value_scratch << value;
117
258
        WriteImpl(m_key_scratch, m_value_scratch);
118
258
    }
void CDBBatch::Write<unsigned char, bool>(unsigned char const&, bool const&)
Line
Count
Source
113
2
    {
114
2
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
2
        m_key_scratch << key;
116
2
        m_value_scratch << value;
117
2
        WriteImpl(m_key_scratch, m_value_scratch);
118
2
    }
void CDBBatch::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, bool>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool const&)
Line
Count
Source
113
2
    {
114
2
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
2
        m_key_scratch << key;
116
2
        m_value_scratch << value;
117
2
        WriteImpl(m_key_scratch, m_value_scratch);
118
2
    }
void CDBBatch::Write<unsigned char, uint256>(unsigned char const&, uint256 const&)
Line
Count
Source
113
3.92k
    {
114
3.92k
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
3.92k
        m_key_scratch << key;
116
3.92k
        m_value_scratch << value;
117
3.92k
        WriteImpl(m_key_scratch, m_value_scratch);
118
3.92k
    }
void CDBBatch::Write<dbwrapper_tests::StringContentsSerializer, unsigned int>(dbwrapper_tests::StringContentsSerializer const&, unsigned int const&)
Line
Count
Source
113
100
    {
114
100
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
100
        m_key_scratch << key;
116
100
        m_value_scratch << value;
117
100
        WriteImpl(m_key_scratch, m_value_scratch);
118
100
    }
void CDBBatch::Write<txindex::DBKey, std::array<std::byte, 0ul>>(txindex::DBKey const&, std::array<std::byte, 0ul> const&)
Line
Count
Source
113
4.24k
    {
114
4.24k
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
4.24k
        m_key_scratch << key;
116
4.24k
        m_value_scratch << value;
117
4.24k
        WriteImpl(m_key_scratch, m_value_scratch);
118
4.24k
    }
void CDBBatch::Write<std::pair<unsigned char, uint256>, CDiskTxPos>(std::pair<unsigned char, uint256> const&, CDiskTxPos const&)
Line
Count
Source
113
2
    {
114
2
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
2
        m_key_scratch << key;
116
2
        m_value_scratch << value;
117
2
        WriteImpl(m_key_scratch, m_value_scratch);
118
2
    }
void CDBBatch::Write<unsigned char, CBlockLocator>(unsigned char const&, CBlockLocator const&)
Line
Count
Source
113
208
    {
114
208
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
208
        m_key_scratch << key;
116
208
        m_value_scratch << value;
117
208
        WriteImpl(m_key_scratch, m_value_scratch);
118
208
    }
void CDBBatch::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, Obfuscation>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, Obfuscation const&)
Line
Count
Source
113
538
    {
114
538
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
538
        m_key_scratch << key;
116
538
        m_value_scratch << value;
117
538
        WriteImpl(m_key_scratch, m_value_scratch);
118
538
    }
void CDBBatch::Write<unsigned char, FlatFilePos>(unsigned char const&, FlatFilePos const&)
Line
Count
Source
113
173
    {
114
173
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
173
        m_key_scratch << key;
116
173
        m_value_scratch << value;
117
173
        WriteImpl(m_key_scratch, m_value_scratch);
118
173
    }
blockfilterindex.cpp:void CDBBatch::Write<index_util::DBHeightKey, std::pair<uint256, (anonymous namespace)::DBVal>>(index_util::DBHeightKey const&, std::pair<uint256, (anonymous namespace)::DBVal> const&)
Line
Count
Source
113
7.89k
    {
114
7.89k
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
7.89k
        m_key_scratch << key;
116
7.89k
        m_value_scratch << value;
117
7.89k
        WriteImpl(m_key_scratch, m_value_scratch);
118
7.89k
    }
blockfilterindex.cpp:void CDBBatch::Write<index_util::DBHashKey, (anonymous namespace)::DBVal>(index_util::DBHashKey const&, (anonymous namespace)::DBVal const&)
Line
Count
Source
113
111
    {
114
111
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
111
        m_key_scratch << key;
116
111
        m_value_scratch << value;
117
111
        WriteImpl(m_key_scratch, m_value_scratch);
118
111
    }
coinstatsindex.cpp:void CDBBatch::Write<index_util::DBHeightKey, std::pair<uint256, (anonymous namespace)::DBVal>>(index_util::DBHeightKey const&, std::pair<uint256, (anonymous namespace)::DBVal> const&)
Line
Count
Source
113
4.08k
    {
114
4.08k
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
4.08k
        m_key_scratch << key;
116
4.08k
        m_value_scratch << value;
117
4.08k
        WriteImpl(m_key_scratch, m_value_scratch);
118
4.08k
    }
coinstatsindex.cpp:void CDBBatch::Write<index_util::DBHashKey, (anonymous namespace)::DBVal>(index_util::DBHashKey const&, (anonymous namespace)::DBVal const&)
Line
Count
Source
113
121
    {
114
121
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
121
        m_key_scratch << key;
116
121
        m_value_scratch << value;
117
121
        WriteImpl(m_key_scratch, m_value_scratch);
118
121
    }
void CDBBatch::Write<unsigned char, MuHash3072>(unsigned char const&, MuHash3072 const&)
Line
Count
Source
113
114
    {
114
114
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
114
        m_key_scratch << key;
116
114
        m_value_scratch << value;
117
114
        WriteImpl(m_key_scratch, m_value_scratch);
118
114
    }
void CDBBatch::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<unsigned long, unsigned long>>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::pair<unsigned long, unsigned long> const&)
Line
Count
Source
113
22
    {
114
22
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
22
        m_key_scratch << key;
116
22
        m_value_scratch << value;
117
22
        WriteImpl(m_key_scratch, m_value_scratch);
118
22
    }
void CDBBatch::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CBlockLocator>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, CBlockLocator const&)
Line
Count
Source
113
55
    {
114
55
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
55
        m_key_scratch << key;
116
55
        m_value_scratch << value;
117
55
        WriteImpl(m_key_scratch, m_value_scratch);
118
55
    }
void CDBBatch::Write<txindex::BlockHashKey, unsigned int>(txindex::BlockHashKey const&, unsigned int const&)
Line
Count
Source
113
4.09k
    {
114
4.09k
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
4.09k
        m_key_scratch << key;
116
4.09k
        m_value_scratch << value;
117
4.09k
        WriteImpl(m_key_scratch, m_value_scratch);
118
4.09k
    }
void CDBBatch::Write<txindex::BlockSeqKey, uint256>(txindex::BlockSeqKey const&, uint256 const&)
Line
Count
Source
113
4.09k
    {
114
4.09k
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
4.09k
        m_key_scratch << key;
116
4.09k
        m_value_scratch << value;
117
4.09k
        WriteImpl(m_key_scratch, m_value_scratch);
118
4.09k
    }
void CDBBatch::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned int>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, unsigned int const&)
Line
Count
Source
113
4.09k
    {
114
4.09k
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
4.09k
        m_key_scratch << key;
116
4.09k
        m_value_scratch << value;
117
4.09k
        WriteImpl(m_key_scratch, m_value_scratch);
118
4.09k
    }
void CDBBatch::Write<char [12], std::pair<unsigned long, unsigned long>>(char const (&) [12], std::pair<unsigned long, unsigned long> const&)
Line
Count
Source
113
9
    {
114
9
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
9
        m_key_scratch << key;
116
9
        m_value_scratch << value;
117
9
        WriteImpl(m_key_scratch, m_value_scratch);
118
9
    }
void CDBBatch::Write<DBKey, std::span<std::byte const, 18446744073709551615ul>>(DBKey const&, std::span<std::byte const, 18446744073709551615ul> const&)
Line
Count
Source
113
38
    {
114
38
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
38
        m_key_scratch << key;
116
38
        m_value_scratch << value;
117
38
        WriteImpl(m_key_scratch, m_value_scratch);
118
38
    }
void CDBBatch::Write<unsigned char, unsigned char>(unsigned char const&, unsigned char const&)
Line
Count
Source
113
15
    {
114
15
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
15
        m_key_scratch << key;
116
15
        m_value_scratch << value;
117
15
        WriteImpl(m_key_scratch, m_value_scratch);
118
15
    }
void CDBBatch::Write<std::pair<unsigned char, int>, kernel::CBlockFileInfo>(std::pair<unsigned char, int> const&, kernel::CBlockFileInfo const&)
Line
Count
Source
113
1.69k
    {
114
1.69k
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
1.69k
        m_key_scratch << key;
116
1.69k
        m_value_scratch << value;
117
1.69k
        WriteImpl(m_key_scratch, m_value_scratch);
118
1.69k
    }
void CDBBatch::Write<unsigned char, int>(unsigned char const&, int const&)
Line
Count
Source
113
3.57k
    {
114
3.57k
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
3.57k
        m_key_scratch << key;
116
3.57k
        m_value_scratch << value;
117
3.57k
        WriteImpl(m_key_scratch, m_value_scratch);
118
3.57k
    }
void CDBBatch::Write<std::pair<unsigned char, uint256>, CDiskBlockIndex>(std::pair<unsigned char, uint256> const&, CDiskBlockIndex const&)
Line
Count
Source
113
115k
    {
114
115k
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
115k
        m_key_scratch << key;
116
115k
        m_value_scratch << value;
117
115k
        WriteImpl(m_key_scratch, m_value_scratch);
118
115k
    }
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&)
Line
Count
Source
113
8
    {
114
8
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
8
        m_key_scratch << key;
116
8
        m_value_scratch << value;
117
8
        WriteImpl(m_key_scratch, m_value_scratch);
118
8
    }
void CDBBatch::Write<unsigned char, std::vector<uint256, std::allocator<uint256>>>(unsigned char const&, std::vector<uint256, std::allocator<uint256>> const&)
Line
Count
Source
113
3.88k
    {
114
3.88k
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
3.88k
        m_key_scratch << key;
116
3.88k
        m_value_scratch << value;
117
3.88k
        WriteImpl(m_key_scratch, m_value_scratch);
118
3.88k
    }
txdb.cpp:void CDBBatch::Write<(anonymous namespace)::CoinEntry, Coin>((anonymous namespace)::CoinEntry const&, Coin const&)
Line
Count
Source
113
287k
    {
114
287k
        ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115
287k
        m_key_scratch << key;
116
287k
        m_value_scratch << value;
117
287k
        WriteImpl(m_key_scratch, m_value_scratch);
118
287k
    }
119
120
    template <typename K>
121
    void Erase(const K& key)
122
41.3k
    {
123
41.3k
        ScopedDataStreamUsage scoped_key{m_key_scratch};
124
41.3k
        m_key_scratch << key;
125
41.3k
        EraseImpl(m_key_scratch);
126
41.3k
    }
void CDBBatch::Erase<unsigned char>(unsigned char const&)
Line
Count
Source
122
7.78k
    {
123
7.78k
        ScopedDataStreamUsage scoped_key{m_key_scratch};
124
7.78k
        m_key_scratch << key;
125
7.78k
        EraseImpl(m_key_scratch);
126
7.78k
    }
void CDBBatch::Erase<txindex::DBKey>(txindex::DBKey const&)
Line
Count
Source
122
2
    {
123
2
        ScopedDataStreamUsage scoped_key{m_key_scratch};
124
2
        m_key_scratch << key;
125
2
        EraseImpl(m_key_scratch);
126
2
    }
void CDBBatch::Erase<DBKey>(DBKey const&)
Line
Count
Source
122
6
    {
123
6
        ScopedDataStreamUsage scoped_key{m_key_scratch};
124
6
        m_key_scratch << key;
125
6
        EraseImpl(m_key_scratch);
126
6
    }
txdb.cpp:void CDBBatch::Erase<(anonymous namespace)::CoinEntry>((anonymous namespace)::CoinEntry const&)
Line
Count
Source
122
33.5k
    {
123
33.5k
        ScopedDataStreamUsage scoped_key{m_key_scratch};
124
33.5k
        m_key_scratch << key;
125
33.5k
        EraseImpl(m_key_scratch);
126
33.5k
    }
127
128
    size_t ApproximateSize() const;
129
};
130
131
class CDBIterator
132
{
133
public:
134
    struct IteratorImpl;
135
136
private:
137
    const CDBWrapper &parent;
138
    const std::unique_ptr<IteratorImpl> m_impl_iter;
139
    DataStream m_scratch{};
140
141
    void SeekImpl(std::span<const std::byte> key);
142
    std::span<const std::byte> GetKeyImpl() const;
143
    std::span<const std::byte> GetValueImpl() const;
144
145
public:
146
147
    /**
148
     * @param[in] _parent          Parent CDBWrapper instance.
149
     * @param[in] _piter           The original leveldb iterator.
150
     */
151
    CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter);
152
    ~CDBIterator();
153
154
    bool Valid() const;
155
156
    void SeekToFirst();
157
158
4.77k
    template<typename K> void Seek(const K& key) {
159
4.77k
        ScopedDataStreamUsage scoped_scratch{m_scratch};
160
4.77k
        m_scratch << key;
161
4.77k
        SeekImpl(m_scratch);
162
4.77k
    }
void CDBIterator::Seek<unsigned char>(unsigned char const&)
Line
Count
Source
158
1.27k
    template<typename K> void Seek(const K& key) {
159
1.27k
        ScopedDataStreamUsage scoped_scratch{m_scratch};
160
1.27k
        m_scratch << key;
161
1.27k
        SeekImpl(m_scratch);
162
1.27k
    }
void CDBIterator::Seek<dbwrapper_tests::StringContentsSerializer>(dbwrapper_tests::StringContentsSerializer const&)
Line
Count
Source
158
2
    template<typename K> void Seek(const K& key) {
159
2
        ScopedDataStreamUsage scoped_scratch{m_scratch};
160
2
        m_scratch << key;
161
2
        SeekImpl(m_scratch);
162
2
    }
void CDBIterator::Seek<txindex::DBKey>(txindex::DBKey const&)
Line
Count
Source
158
265
    template<typename K> void Seek(const K& key) {
159
265
        ScopedDataStreamUsage scoped_scratch{m_scratch};
160
265
        m_scratch << key;
161
265
        SeekImpl(m_scratch);
162
265
    }
void CDBIterator::Seek<index_util::DBHeightKey>(index_util::DBHeightKey const&)
Line
Count
Source
158
680
    template<typename K> void Seek(const K& key) {
159
680
        ScopedDataStreamUsage scoped_scratch{m_scratch};
160
680
        m_scratch << key;
161
680
        SeekImpl(m_scratch);
162
680
    }
void CDBIterator::Seek<std::pair<unsigned char, unsigned long>>(std::pair<unsigned char, unsigned long> const&)
Line
Count
Source
158
36
    template<typename K> void Seek(const K& key) {
159
36
        ScopedDataStreamUsage scoped_scratch{m_scratch};
160
36
        m_scratch << key;
161
36
        SeekImpl(m_scratch);
162
36
    }
void CDBIterator::Seek<std::pair<unsigned char, uint256>>(std::pair<unsigned char, uint256> const&)
Line
Count
Source
158
2.51k
    template<typename K> void Seek(const K& key) {
159
2.51k
        ScopedDataStreamUsage scoped_scratch{m_scratch};
160
2.51k
        m_scratch << key;
161
2.51k
        SeekImpl(m_scratch);
162
2.51k
    }
163
164
    void Next();
165
166
425k
    template<typename K> bool GetKey(K& key) {
167
425k
        try {
168
425k
            SpanReader ssKey{GetKeyImpl()};
169
425k
            ssKey >> key;
170
425k
        } catch (const std::exception&) {
171
782
            return false;
172
782
        }
173
424k
        return true;
174
425k
    }
bool CDBIterator::GetKey<unsigned short>(unsigned short&)
Line
Count
Source
166
2
    template<typename K> bool GetKey(K& key) {
167
2
        try {
168
2
            SpanReader ssKey{GetKeyImpl()};
169
2
            ssKey >> key;
170
2
        } catch (const std::exception&) {
171
2
            return false;
172
2
        }
173
0
        return true;
174
2
    }
bool CDBIterator::GetKey<unsigned char>(unsigned char&)
Line
Count
Source
166
390
    template<typename K> bool GetKey(K& key) {
167
390
        try {
168
390
            SpanReader ssKey{GetKeyImpl()};
169
390
            ssKey >> key;
170
390
        } catch (const std::exception&) {
171
0
            return false;
172
0
        }
173
390
        return true;
174
390
    }
bool CDBIterator::GetKey<dbwrapper_tests::StringContentsSerializer>(dbwrapper_tests::StringContentsSerializer&)
Line
Count
Source
166
150
    template<typename K> bool GetKey(K& key) {
167
150
        try {
168
150
            SpanReader ssKey{GetKeyImpl()};
169
150
            ssKey >> key;
170
150
        } catch (const std::exception&) {
171
0
            return false;
172
0
        }
173
150
        return true;
174
150
    }
bool CDBIterator::GetKey<txindex::DBKey>(txindex::DBKey&)
Line
Count
Source
166
325
    template<typename K> bool GetKey(K& key) {
167
325
        try {
168
325
            SpanReader ssKey{GetKeyImpl()};
169
325
            ssKey >> key;
170
325
        } catch (const std::exception&) {
171
0
            return false;
172
0
        }
173
325
        return true;
174
325
    }
bool CDBIterator::GetKey<index_util::DBHeightKey>(index_util::DBHeightKey&)
Line
Count
Source
166
3.09k
    template<typename K> bool GetKey(K& key) {
167
3.09k
        try {
168
3.09k
            SpanReader ssKey{GetKeyImpl()};
169
3.09k
            ssKey >> key;
170
3.09k
        } catch (const std::exception&) {
171
0
            return false;
172
0
        }
173
3.09k
        return true;
174
3.09k
    }
bool CDBIterator::GetKey<DBKey>(DBKey&)
Line
Count
Source
166
25
    template<typename K> bool GetKey(K& key) {
167
25
        try {
168
25
            SpanReader ssKey{GetKeyImpl()};
169
25
            ssKey >> key;
170
25
        } catch (const std::exception&) {
171
0
            return false;
172
0
        }
173
25
        return true;
174
25
    }
bool CDBIterator::GetKey<std::pair<unsigned char, uint256>>(std::pair<unsigned char, uint256>&)
Line
Count
Source
166
143k
    template<typename K> bool GetKey(K& key) {
167
143k
        try {
168
143k
            SpanReader ssKey{GetKeyImpl()};
169
143k
            ssKey >> key;
170
143k
        } catch (const std::exception&) {
171
780
            return false;
172
780
        }
173
142k
        return true;
174
143k
    }
txdb.cpp:bool CDBIterator::GetKey<(anonymous namespace)::CoinEntry>((anonymous namespace)::CoinEntry&)
Line
Count
Source
166
278k
    template<typename K> bool GetKey(K& key) {
167
278k
        try {
168
278k
            SpanReader ssKey{GetKeyImpl()};
169
278k
            ssKey >> key;
170
278k
        } catch (const std::exception&) {
171
0
            return false;
172
0
        }
173
278k
        return true;
174
278k
    }
175
176
424k
    template<typename V> bool GetValue(V& value) {
177
424k
        try {
178
424k
            ScopedDataStreamUsage scoped_scratch{m_scratch};
179
424k
            m_scratch.write(GetValueImpl());
180
424k
            dbwrapper_private::GetObfuscation(parent)(m_scratch);
181
424k
            m_scratch >> value;
182
424k
        } catch (const std::exception&) {
183
2
            return false;
184
2
        }
185
424k
        return true;
186
424k
    }
bool CDBIterator::GetValue<std::pair<uint256, unsigned char>>(std::pair<uint256, unsigned char>&)
Line
Count
Source
176
2
    template<typename V> bool GetValue(V& value) {
177
2
        try {
178
2
            ScopedDataStreamUsage scoped_scratch{m_scratch};
179
2
            m_scratch.write(GetValueImpl());
180
2
            dbwrapper_private::GetObfuscation(parent)(m_scratch);
181
2
            m_scratch >> value;
182
2
        } catch (const std::exception&) {
183
2
            return false;
184
2
        }
185
0
        return true;
186
2
    }
bool CDBIterator::GetValue<uint256>(uint256&)
Line
Count
Source
176
8
    template<typename V> bool GetValue(V& value) {
177
8
        try {
178
8
            ScopedDataStreamUsage scoped_scratch{m_scratch};
179
8
            m_scratch.write(GetValueImpl());
180
8
            dbwrapper_private::GetObfuscation(parent)(m_scratch);
181
8
            m_scratch >> value;
182
8
        } catch (const std::exception&) {
183
0
            return false;
184
0
        }
185
8
        return true;
186
8
    }
bool CDBIterator::GetValue<unsigned int>(unsigned int&)
Line
Count
Source
176
342
    template<typename V> bool GetValue(V& value) {
177
342
        try {
178
342
            ScopedDataStreamUsage scoped_scratch{m_scratch};
179
342
            m_scratch.write(GetValueImpl());
180
342
            dbwrapper_private::GetObfuscation(parent)(m_scratch);
181
342
            m_scratch >> value;
182
342
        } catch (const std::exception&) {
183
0
            return false;
184
0
        }
185
342
        return true;
186
342
    }
blockfilterindex.cpp:bool CDBIterator::GetValue<std::pair<uint256, (anonymous namespace)::DBVal>>(std::pair<uint256, (anonymous namespace)::DBVal>&)
Line
Count
Source
176
2.97k
    template<typename V> bool GetValue(V& value) {
177
2.97k
        try {
178
2.97k
            ScopedDataStreamUsage scoped_scratch{m_scratch};
179
2.97k
            m_scratch.write(GetValueImpl());
180
2.97k
            dbwrapper_private::GetObfuscation(parent)(m_scratch);
181
2.97k
            m_scratch >> value;
182
2.97k
        } catch (const std::exception&) {
183
0
            return false;
184
0
        }
185
2.97k
        return true;
186
2.97k
    }
coinstatsindex.cpp:bool CDBIterator::GetValue<std::pair<uint256, (anonymous namespace)::DBVal>>(std::pair<uint256, (anonymous namespace)::DBVal>&)
Line
Count
Source
176
121
    template<typename V> bool GetValue(V& value) {
177
121
        try {
178
121
            ScopedDataStreamUsage scoped_scratch{m_scratch};
179
121
            m_scratch.write(GetValueImpl());
180
121
            dbwrapper_private::GetObfuscation(parent)(m_scratch);
181
121
            m_scratch >> value;
182
121
        } catch (const std::exception&) {
183
0
            return false;
184
0
        }
185
121
        return true;
186
121
    }
bool CDBIterator::GetValue<CDiskBlockIndex>(CDiskBlockIndex&)
Line
Count
Source
176
142k
    template<typename V> bool GetValue(V& value) {
177
142k
        try {
178
142k
            ScopedDataStreamUsage scoped_scratch{m_scratch};
179
142k
            m_scratch.write(GetValueImpl());
180
142k
            dbwrapper_private::GetObfuscation(parent)(m_scratch);
181
142k
            m_scratch >> value;
182
142k
        } catch (const std::exception&) {
183
0
            return false;
184
0
        }
185
142k
        return true;
186
142k
    }
bool CDBIterator::GetValue<Coin>(Coin&)
Line
Count
Source
176
278k
    template<typename V> bool GetValue(V& value) {
177
278k
        try {
178
278k
            ScopedDataStreamUsage scoped_scratch{m_scratch};
179
278k
            m_scratch.write(GetValueImpl());
180
278k
            dbwrapper_private::GetObfuscation(parent)(m_scratch);
181
278k
            m_scratch >> value;
182
278k
        } catch (const std::exception&) {
183
0
            return false;
184
0
        }
185
278k
        return true;
186
278k
    }
187
};
188
189
struct LevelDBContext;
190
191
class CDBWrapper
192
{
193
    friend const Obfuscation& dbwrapper_private::GetObfuscation(const CDBWrapper&);
194
private:
195
    //! holds all leveldb-specific fields of this class
196
    std::unique_ptr<LevelDBContext> m_db_context;
197
198
    //! the name of this database
199
    std::string m_name;
200
201
    //! optional XOR-obfuscation of the database
202
    Obfuscation m_obfuscation;
203
204
    //! obfuscation key storage key, null-prefixed to avoid collisions
205
    inline static const std::string OBFUSCATION_KEY{"\000obfuscate_key", 14}; // explicit size to avoid truncation at leading \0
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
12.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
6.18M
    {
222
6.18M
        DataStream ssKey{};
223
6.18M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
6.18M
        ssKey << key;
225
6.18M
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
6.18M
        if (!strValue) {
227
6.09M
            return false;
228
6.09M
        }
229
93.8k
        try {
230
93.8k
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
93.8k
            m_obfuscation(ssValue);
232
93.8k
            SpanReader{ssValue} >> value;
233
93.8k
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
93.8k
        return true;
237
93.8k
    }
bool CDBWrapper::Read<unsigned char, uint256>(unsigned char const&, uint256&) const
Line
Count
Source
221
8.04k
    {
222
8.04k
        DataStream ssKey{};
223
8.04k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
8.04k
        ssKey << key;
225
8.04k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
8.04k
        if (!strValue) {
227
1.81k
            return false;
228
1.81k
        }
229
6.23k
        try {
230
6.23k
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
6.23k
            m_obfuscation(ssValue);
232
6.23k
            SpanReader{ssValue} >> value;
233
6.23k
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
6.23k
        return true;
237
6.23k
    }
bool CDBWrapper::Read<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, uint256>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, uint256&) const
Line
Count
Source
221
8
    {
222
8
        DataStream ssKey{};
223
8
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
8
        ssKey << key;
225
8
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
8
        if (!strValue) {
227
0
            return false;
228
0
        }
229
8
        try {
230
8
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
8
            m_obfuscation(ssValue);
232
8
            SpanReader{ssValue} >> value;
233
8
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
8
        return true;
237
8
    }
bool CDBWrapper::Read<unsigned char, unsigned int>(unsigned char const&, unsigned int&) const
Line
Count
Source
221
2
    {
222
2
        DataStream ssKey{};
223
2
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
2
        ssKey << key;
225
2
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
2
        if (!strValue) {
227
0
            return false;
228
0
        }
229
2
        try {
230
2
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
2
            m_obfuscation(ssValue);
232
2
            SpanReader{ssValue} >> value;
233
2
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
2
        return true;
237
2
    }
bool CDBWrapper::Read<unsigned char, bool>(unsigned char const&, bool&) const
Line
Count
Source
221
2
    {
222
2
        DataStream ssKey{};
223
2
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
2
        ssKey << key;
225
2
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
2
        if (!strValue) {
227
0
            return false;
228
0
        }
229
2
        try {
230
2
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
2
            m_obfuscation(ssValue);
232
2
            SpanReader{ssValue} >> value;
233
2
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
2
        return true;
237
2
    }
bool CDBWrapper::Read<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, bool>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool&) const
Line
Count
Source
221
2
    {
222
2
        DataStream ssKey{};
223
2
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
2
        ssKey << key;
225
2
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
2
        if (!strValue) {
227
0
            return false;
228
0
        }
229
2
        try {
230
2
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
2
            m_obfuscation(ssValue);
232
2
            SpanReader{ssValue} >> value;
233
2
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
2
        return true;
237
2
    }
bool CDBWrapper::Read<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<unsigned long, unsigned long>>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::pair<unsigned long, unsigned long>&) const
Line
Count
Source
221
51
    {
222
51
        DataStream ssKey{};
223
51
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
51
        ssKey << key;
225
51
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
51
        if (!strValue) {
227
22
            return false;
228
22
        }
229
29
        try {
230
29
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
29
            m_obfuscation(ssValue);
232
29
            SpanReader{ssValue} >> value;
233
29
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
29
        return true;
237
29
    }
bool CDBWrapper::Read<unsigned char, CBlockLocator>(unsigned char const&, CBlockLocator&) const
Line
Count
Source
221
171
    {
222
171
        DataStream ssKey{};
223
171
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
171
        ssKey << key;
225
171
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
171
        if (!strValue) {
227
100
            return false;
228
100
        }
229
71
        try {
230
71
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
71
            m_obfuscation(ssValue);
232
71
            SpanReader{ssValue} >> value;
233
71
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
71
        return true;
237
71
    }
bool CDBWrapper::Read<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, Obfuscation>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, Obfuscation&) const
Line
Count
Source
221
2.91k
    {
222
2.91k
        DataStream ssKey{};
223
2.91k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
2.91k
        ssKey << key;
225
2.91k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
2.91k
        if (!strValue) {
227
2.02k
            return false;
228
2.02k
        }
229
893
        try {
230
893
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
893
            m_obfuscation(ssValue);
232
893
            SpanReader{ssValue} >> value;
233
893
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
892
        return true;
237
893
    }
blockfilterindex.cpp:bool CDBWrapper::Read<index_util::DBHashKey, (anonymous namespace)::DBVal>(index_util::DBHashKey const&, (anonymous namespace)::DBVal&) const
Line
Count
Source
221
29
    {
222
29
        DataStream ssKey{};
223
29
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
29
        ssKey << key;
225
29
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
29
        if (!strValue) {
227
0
            return false;
228
0
        }
229
29
        try {
230
29
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
29
            m_obfuscation(ssValue);
232
29
            SpanReader{ssValue} >> value;
233
29
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
29
        return true;
237
29
    }
bool CDBWrapper::Read<unsigned char, FlatFilePos>(unsigned char const&, FlatFilePos&) const
Line
Count
Source
221
53
    {
222
53
        DataStream ssKey{};
223
53
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
53
        ssKey << key;
225
53
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
53
        if (!strValue) {
227
29
            return false;
228
29
        }
229
24
        try {
230
24
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
24
            m_obfuscation(ssValue);
232
24
            SpanReader{ssValue} >> value;
233
24
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
24
        return true;
237
24
    }
blockfilterindex.cpp:bool CDBWrapper::Read<index_util::DBHeightKey, std::pair<uint256, (anonymous namespace)::DBVal>>(index_util::DBHeightKey const&, std::pair<uint256, (anonymous namespace)::DBVal>&) const
Line
Count
Source
221
1.21k
    {
222
1.21k
        DataStream ssKey{};
223
1.21k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
1.21k
        ssKey << key;
225
1.21k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
1.21k
        if (!strValue) {
227
202
            return false;
228
202
        }
229
1.01k
        try {
230
1.01k
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
1.01k
            m_obfuscation(ssValue);
232
1.01k
            SpanReader{ssValue} >> value;
233
1.01k
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
1.01k
        return true;
237
1.01k
    }
coinstatsindex.cpp:bool CDBWrapper::Read<index_util::DBHashKey, (anonymous namespace)::DBVal>(index_util::DBHashKey const&, (anonymous namespace)::DBVal&) const
Line
Count
Source
221
2
    {
222
2
        DataStream ssKey{};
223
2
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
2
        ssKey << key;
225
2
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
2
        if (!strValue) {
227
0
            return false;
228
0
        }
229
2
        try {
230
2
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
2
            m_obfuscation(ssValue);
232
2
            SpanReader{ssValue} >> value;
233
2
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
2
        return true;
237
2
    }
bool CDBWrapper::Read<unsigned char, MuHash3072>(unsigned char const&, MuHash3072&) const
Line
Count
Source
221
54
    {
222
54
        DataStream ssKey{};
223
54
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
54
        ssKey << key;
225
54
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
54
        if (!strValue) {
227
27
            return false;
228
27
        }
229
27
        try {
230
27
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
27
            m_obfuscation(ssValue);
232
27
            SpanReader{ssValue} >> value;
233
27
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
27
        return true;
237
27
    }
coinstatsindex.cpp:bool CDBWrapper::Read<index_util::DBHeightKey, std::pair<uint256, (anonymous namespace)::DBVal>>(index_util::DBHeightKey const&, std::pair<uint256, (anonymous namespace)::DBVal>&) const
Line
Count
Source
221
218
    {
222
218
        DataStream ssKey{};
223
218
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
218
        ssKey << key;
225
218
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
218
        if (!strValue) {
227
1
            return false;
228
1
        }
229
217
        try {
230
217
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
217
            m_obfuscation(ssValue);
232
217
            SpanReader{ssValue} >> value;
233
217
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
217
        return true;
237
217
    }
Unexecuted instantiation: coinstatsindex.cpp:bool CDBWrapper::Read<index_util::DBHashKey, std::pair<uint256, (anonymous namespace)::DBVal>>(index_util::DBHashKey const&, std::pair<uint256, (anonymous namespace)::DBVal>&) const
bool CDBWrapper::Read<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CBlockLocator>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, CBlockLocator&) const
Line
Count
Source
221
54
    {
222
54
        DataStream ssKey{};
223
54
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
54
        ssKey << key;
225
54
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
54
        if (!strValue) {
227
29
            return false;
228
29
        }
229
25
        try {
230
25
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
25
            m_obfuscation(ssValue);
232
25
            SpanReader{ssValue} >> value;
233
25
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
25
        return true;
237
25
    }
bool CDBWrapper::Read<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned int>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, unsigned int&) const
Line
Count
Source
221
4.09k
    {
222
4.09k
        DataStream ssKey{};
223
4.09k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
4.09k
        ssKey << key;
225
4.09k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
4.09k
        if (!strValue) {
227
20
            return false;
228
20
        }
229
4.07k
        try {
230
4.07k
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
4.07k
            m_obfuscation(ssValue);
232
4.07k
            SpanReader{ssValue} >> value;
233
4.07k
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
4.07k
        return true;
237
4.07k
    }
bool CDBWrapper::Read<txindex::BlockSeqKey, uint256>(txindex::BlockSeqKey const&, uint256&) const
Line
Count
Source
221
156
    {
222
156
        DataStream ssKey{};
223
156
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
156
        ssKey << key;
225
156
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
156
        if (!strValue) {
227
0
            return false;
228
0
        }
229
156
        try {
230
156
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
156
            m_obfuscation(ssValue);
232
156
            SpanReader{ssValue} >> value;
233
156
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
156
        return true;
237
156
    }
bool CDBWrapper::Read<std::pair<unsigned char, uint256>, CDiskTxPos>(std::pair<unsigned char, uint256> const&, CDiskTxPos&) const
Line
Count
Source
221
3
    {
222
3
        DataStream ssKey{};
223
3
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
3
        ssKey << key;
225
3
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
3
        if (!strValue) {
227
0
            return false;
228
0
        }
229
3
        try {
230
3
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
3
            m_obfuscation(ssValue);
232
3
            SpanReader{ssValue} >> value;
233
3
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
3
        return true;
237
3
    }
bool CDBWrapper::Read<char [12], std::pair<unsigned long, unsigned long>>(char const (&) [12], std::pair<unsigned long, unsigned long>&) const
Line
Count
Source
221
30
    {
222
30
        DataStream ssKey{};
223
30
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
30
        ssKey << key;
225
30
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
30
        if (!strValue) {
227
9
            return false;
228
9
        }
229
21
        try {
230
21
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
21
            m_obfuscation(ssValue);
232
21
            SpanReader{ssValue} >> value;
233
21
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
21
        return true;
237
21
    }
bool CDBWrapper::Read<std::pair<unsigned char, int>, kernel::CBlockFileInfo>(std::pair<unsigned char, int> const&, kernel::CBlockFileInfo&) const
Line
Count
Source
221
2.51k
    {
222
2.51k
        DataStream ssKey{};
223
2.51k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
2.51k
        ssKey << key;
225
2.51k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
2.51k
        if (!strValue) {
227
1.72k
            return false;
228
1.72k
        }
229
795
        try {
230
795
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
795
            m_obfuscation(ssValue);
232
795
            SpanReader{ssValue} >> value;
233
795
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
795
        return true;
237
795
    }
bool CDBWrapper::Read<unsigned char, int>(unsigned char const&, int&) const
Line
Count
Source
221
1.25k
    {
222
1.25k
        DataStream ssKey{};
223
1.25k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
1.25k
        ssKey << key;
225
1.25k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
1.25k
        if (!strValue) {
227
472
            return false;
228
472
        }
229
778
        try {
230
778
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
778
            m_obfuscation(ssValue);
232
778
            SpanReader{ssValue} >> value;
233
778
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
778
        return true;
237
778
    }
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
1.24k
    {
222
1.24k
        DataStream ssKey{};
223
1.24k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
1.24k
        ssKey << key;
225
1.24k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
1.24k
        if (!strValue) {
227
1.24k
            return false;
228
1.24k
        }
229
2
        try {
230
2
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
2
            m_obfuscation(ssValue);
232
2
            SpanReader{ssValue} >> value;
233
2
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
2
        return true;
237
2
    }
txdb.cpp:bool CDBWrapper::Read<(anonymous namespace)::CoinEntry, Coin>((anonymous namespace)::CoinEntry const&, Coin&) const
Line
Count
Source
221
6.16M
    {
222
6.16M
        DataStream ssKey{};
223
6.16M
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
6.16M
        ssKey << key;
225
6.16M
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
6.16M
        if (!strValue) {
227
6.08M
            return false;
228
6.08M
        }
229
79.4k
        try {
230
79.4k
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
79.4k
            m_obfuscation(ssValue);
232
79.4k
            SpanReader{ssValue} >> value;
233
79.4k
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
79.4k
        return true;
237
79.4k
    }
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
1.63k
    {
222
1.63k
        DataStream ssKey{};
223
1.63k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
224
1.63k
        ssKey << key;
225
1.63k
        std::optional<std::string> strValue{ReadImpl(ssKey)};
226
1.63k
        if (!strValue) {
227
1.63k
            return false;
228
1.63k
        }
229
0
        try {
230
0
            std::span ssValue{MakeWritableByteSpan(*strValue)};
231
0
            m_obfuscation(ssValue);
232
0
            SpanReader{ssValue} >> value;
233
0
        } catch (const std::exception&) {
234
0
            return false;
235
0
        }
236
0
        return true;
237
0
    }
238
239
    template <typename K, typename V>
240
    void Write(const K& key, const V& value, bool fSync = false)
241
12.9k
    {
242
12.9k
        CDBBatch batch(*this);
243
12.9k
        batch.Write(key, value);
244
12.9k
        WriteBatch(batch, fSync);
245
12.9k
    }
void CDBWrapper::Write<unsigned char, uint256>(unsigned char const&, uint256 const&, bool)
Line
Count
Source
241
30
    {
242
30
        CDBBatch batch(*this);
243
30
        batch.Write(key, value);
244
30
        WriteBatch(batch, fSync);
245
30
    }
void CDBWrapper::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, uint256>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, uint256 const&, bool)
Line
Count
Source
241
8
    {
242
8
        CDBBatch batch(*this);
243
8
        batch.Write(key, value);
244
8
        WriteBatch(batch, fSync);
245
8
    }
void CDBWrapper::Write<unsigned char, unsigned int>(unsigned char const&, unsigned int const&, bool)
Line
Count
Source
241
258
    {
242
258
        CDBBatch batch(*this);
243
258
        batch.Write(key, value);
244
258
        WriteBatch(batch, fSync);
245
258
    }
void CDBWrapper::Write<unsigned char, bool>(unsigned char const&, bool const&, bool)
Line
Count
Source
241
2
    {
242
2
        CDBBatch batch(*this);
243
2
        batch.Write(key, value);
244
2
        WriteBatch(batch, fSync);
245
2
    }
void CDBWrapper::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, bool>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool const&, bool)
Line
Count
Source
241
2
    {
242
2
        CDBBatch batch(*this);
243
2
        batch.Write(key, value);
244
2
        WriteBatch(batch, fSync);
245
2
    }
void CDBWrapper::Write<dbwrapper_tests::StringContentsSerializer, unsigned int>(dbwrapper_tests::StringContentsSerializer const&, unsigned int const&, bool)
Line
Count
Source
241
100
    {
242
100
        CDBBatch batch(*this);
243
100
        batch.Write(key, value);
244
100
        WriteBatch(batch, fSync);
245
100
    }
void CDBWrapper::Write<txindex::DBKey, std::array<std::byte, 0ul>>(txindex::DBKey const&, std::array<std::byte, 0ul> const&, bool)
Line
Count
Source
241
1
    {
242
1
        CDBBatch batch(*this);
243
1
        batch.Write(key, value);
244
1
        WriteBatch(batch, fSync);
245
1
    }
void CDBWrapper::Write<std::pair<unsigned char, uint256>, CDiskTxPos>(std::pair<unsigned char, uint256> const&, CDiskTxPos const&, bool)
Line
Count
Source
241
2
    {
242
2
        CDBBatch batch(*this);
243
2
        batch.Write(key, value);
244
2
        WriteBatch(batch, fSync);
245
2
    }
void CDBWrapper::Write<unsigned char, CBlockLocator>(unsigned char const&, CBlockLocator const&, bool)
Line
Count
Source
241
1
    {
242
1
        CDBBatch batch(*this);
243
1
        batch.Write(key, value);
244
1
        WriteBatch(batch, fSync);
245
1
    }
void CDBWrapper::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, Obfuscation>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, Obfuscation const&, bool)
Line
Count
Source
241
538
    {
242
538
        CDBBatch batch(*this);
243
538
        batch.Write(key, value);
244
538
        WriteBatch(batch, fSync);
245
538
    }
blockfilterindex.cpp:void CDBWrapper::Write<index_util::DBHeightKey, std::pair<uint256, (anonymous namespace)::DBVal>>(index_util::DBHeightKey const&, std::pair<uint256, (anonymous namespace)::DBVal> const&, bool)
Line
Count
Source
241
7.89k
    {
242
7.89k
        CDBBatch batch(*this);
243
7.89k
        batch.Write(key, value);
244
7.89k
        WriteBatch(batch, fSync);
245
7.89k
    }
coinstatsindex.cpp:void CDBWrapper::Write<index_util::DBHeightKey, std::pair<uint256, (anonymous namespace)::DBVal>>(index_util::DBHeightKey const&, std::pair<uint256, (anonymous namespace)::DBVal> const&, bool)
Line
Count
Source
241
4.08k
    {
242
4.08k
        CDBBatch batch(*this);
243
4.08k
        batch.Write(key, value);
244
4.08k
        WriteBatch(batch, fSync);
245
4.08k
    }
void CDBWrapper::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<unsigned long, unsigned long>>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::pair<unsigned long, unsigned long> const&, bool)
Line
Count
Source
241
22
    {
242
22
        CDBBatch batch(*this);
243
22
        batch.Write(key, value);
244
22
        WriteBatch(batch, fSync);
245
22
    }
void CDBWrapper::Write<char [12], std::pair<unsigned long, unsigned long>>(char const (&) [12], std::pair<unsigned long, unsigned long> const&, bool)
Line
Count
Source
241
9
    {
242
9
        CDBBatch batch(*this);
243
9
        batch.Write(key, value);
244
9
        WriteBatch(batch, fSync);
245
9
    }
void CDBWrapper::Write<unsigned char, unsigned char>(unsigned char const&, unsigned char const&, bool)
Line
Count
Source
241
15
    {
242
15
        CDBBatch batch(*this);
243
15
        batch.Write(key, value);
244
15
        WriteBatch(batch, fSync);
245
15
    }
void 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)
Line
Count
Source
241
8
    {
242
8
        CDBBatch batch(*this);
243
8
        batch.Write(key, value);
244
8
        WriteBatch(batch, fSync);
245
8
    }
246
247
    template <typename K>
248
    bool Exists(const K& key) const
249
5.94k
    {
250
5.94k
        DataStream ssKey{};
251
5.94k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
252
5.94k
        ssKey << key;
253
5.94k
        return ExistsImpl(ssKey);
254
5.94k
    }
bool CDBWrapper::Exists<unsigned char>(unsigned char const&) const
Line
Count
Source
249
1.30k
    {
250
1.30k
        DataStream ssKey{};
251
1.30k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
252
1.30k
        ssKey << key;
253
1.30k
        return ExistsImpl(ssKey);
254
1.30k
    }
bool CDBWrapper::Exists<txindex::BlockHashKey>(txindex::BlockHashKey const&) const
Line
Count
Source
249
4.59k
    {
250
4.59k
        DataStream ssKey{};
251
4.59k
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
252
4.59k
        ssKey << key;
253
4.59k
        return ExistsImpl(ssKey);
254
4.59k
    }
txdb.cpp:bool CDBWrapper::Exists<(anonymous namespace)::CoinEntry>((anonymous namespace)::CoinEntry const&) const
Line
Count
Source
249
44
    {
250
44
        DataStream ssKey{};
251
44
        ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
252
44
        ssKey << key;
253
44
        return ExistsImpl(ssKey);
254
44
    }
255
256
    template <typename K>
257
    void Erase(const K& key, bool fSync = false)
258
16
    {
259
16
        CDBBatch batch(*this);
260
16
        batch.Erase(key);
261
16
        WriteBatch(batch, fSync);
262
16
    }
void CDBWrapper::Erase<txindex::DBKey>(txindex::DBKey const&, bool)
Line
Count
Source
258
2
    {
259
2
        CDBBatch batch(*this);
260
2
        batch.Erase(key);
261
2
        WriteBatch(batch, fSync);
262
2
    }
void CDBWrapper::Erase<unsigned char>(unsigned char const&, bool)
Line
Count
Source
258
14
    {
259
14
        CDBBatch batch(*this);
260
14
        batch.Erase(key);
261
14
        WriteBatch(batch, fSync);
262
14
    }
263
264
    void WriteBatch(CDBBatch& batch, bool fSync = false);
265
266
    //! Perform a blocking full compaction of the underlying LevelDB.
267
    void CompactFull();
268
269
    //! Return a LevelDB property value, if available.
270
    std::optional<std::string> GetProperty(const std::string& property) const;
271
272
    // Get an estimate of LevelDB memory usage (in bytes).
273
    size_t DynamicMemoryUsage() const;
274
275
    CDBIterator* NewIterator();
276
277
    /**
278
     * Return true if the database managed by this class contains no entries.
279
     */
280
    bool IsEmpty();
281
282
    //! Probe an unopened database for a key prefix. Return true if a database at
283
    //! path exists and contains at least 1 entry beginning with prefix; missing
284
    //! or empty databases return false, and database errors throw dbwrapper_error.
285
    static bool HasKeyStartingWith(const fs::path& path, uint8_t prefix);
286
287
    template<typename K>
288
    size_t EstimateSize(const K& key_begin, const K& key_end) const
289
102
    {
290
102
        DataStream ssKey1{}, ssKey2{};
291
102
        ssKey1.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
292
102
        ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
293
102
        ssKey1 << key_begin;
294
102
        ssKey2 << key_end;
295
102
        return EstimateSizeImpl(ssKey1, ssKey2);
296
102
    }
297
};
298
299
#endif // BITCOIN_DBWRAPPER_H