/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/expected.h> |
15 | | #include <util/fs.h> |
16 | | #include <util/not_null.h> |
17 | | #include <util/obfuscation.h> |
18 | | |
19 | | #include <cstddef> |
20 | | #include <cstdint> |
21 | | #include <exception> |
22 | | #include <memory> |
23 | | #include <optional> |
24 | | #include <span> |
25 | | #include <stdexcept> |
26 | | #include <string> |
27 | | |
28 | | namespace leveldb { |
29 | | class Env; |
30 | | } // namespace leveldb |
31 | | |
32 | | inline constexpr size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64; |
33 | | inline constexpr size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024; |
34 | | inline constexpr size_t DBWRAPPER_MAX_FILE_SIZE{32_MiB}; |
35 | | |
36 | | //! User-controlled performance and debug options. |
37 | | struct DBOptions { |
38 | | //! Compact database on startup. |
39 | | bool force_compact = false; |
40 | | }; |
41 | | |
42 | | //! Application-specific storage settings. |
43 | | struct DBParams { |
44 | | //! Location in the filesystem where leveldb data will be stored. |
45 | | fs::path path; |
46 | | //! Configures various leveldb cache settings. |
47 | | uint64_t cache_bytes; |
48 | | //! If true, use leveldb's memory environment. |
49 | | bool memory_only = false; |
50 | | //! If true, remove all existing data. |
51 | | bool wipe_data = false; |
52 | | //! If true, store data obfuscated via simple XOR. If false, XOR with a |
53 | | //! zero'd byte array. |
54 | | bool obfuscate = false; |
55 | | //! If true, build a LevelDB bloom filter to accelerate point lookups. |
56 | | bool bloom_filter = true; |
57 | | //! Passed-through options. |
58 | | DBOptions options{}; |
59 | | //! If non-null, use this as the leveldb::Env instead of the default. |
60 | | //! Caller retains ownership. |
61 | | leveldb::Env* testing_env = nullptr; |
62 | | //! Maximum LevelDB SST file size. Larger values reduce the frequency |
63 | | //! of compactions but increase their duration. |
64 | | size_t max_file_size = DBWRAPPER_MAX_FILE_SIZE; |
65 | | }; |
66 | | |
67 | | class dbwrapper_error : public std::runtime_error |
68 | | { |
69 | | public: |
70 | 14 | explicit dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {} |
71 | | }; |
72 | | |
73 | | class CDBWrapper; |
74 | | |
75 | | /** These should be considered an implementation detail of the specific database. |
76 | | */ |
77 | | namespace dbwrapper_private { |
78 | | |
79 | | /** Work around circular dependency, as well as for testing in dbwrapper_tests. |
80 | | * Database obfuscation should be considered an implementation detail of the |
81 | | * specific database. |
82 | | */ |
83 | | const Obfuscation& GetObfuscation(const CDBWrapper&); |
84 | | }; // namespace dbwrapper_private |
85 | | |
86 | | bool DestroyDB(const std::string& path_str); |
87 | | |
88 | | /** Batch of changes queued to be written to a CDBWrapper */ |
89 | | class CDBBatch |
90 | | { |
91 | | friend class CDBWrapper; |
92 | | |
93 | | private: |
94 | | const CDBWrapper &parent; |
95 | | |
96 | | struct WriteBatchImpl; |
97 | | const std::unique_ptr<WriteBatchImpl> m_impl_batch; |
98 | | |
99 | | DataStream m_key_scratch{}; |
100 | | DataStream m_value_scratch{}; |
101 | | |
102 | | void WriteImpl(std::span<const std::byte> key, DataStream& value); |
103 | | void EraseImpl(std::span<const std::byte> key); |
104 | | |
105 | | public: |
106 | | /** |
107 | | * @param[in] _parent CDBWrapper that this batch is to be submitted to |
108 | | */ |
109 | | explicit CDBBatch(const CDBWrapper& _parent); |
110 | | ~CDBBatch(); |
111 | | void Clear(); |
112 | | |
113 | | template <typename K, typename V> |
114 | | void Write(const K& key, const V& value) |
115 | 452k | { |
116 | 452k | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; |
117 | 452k | m_key_scratch << key; |
118 | 452k | m_value_scratch << value; |
119 | 452k | WriteImpl(m_key_scratch, m_value_scratch); |
120 | 452k | } 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 | 115 | 8 | { | 116 | 8 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 8 | m_key_scratch << key; | 118 | 8 | m_value_scratch << value; | 119 | 8 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 8 | } |
void CDBBatch::Write<unsigned char, unsigned int>(unsigned char const&, unsigned int const&) Line | Count | Source | 115 | 258 | { | 116 | 258 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 258 | m_key_scratch << key; | 118 | 258 | m_value_scratch << value; | 119 | 258 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 258 | } |
void CDBBatch::Write<unsigned char, bool>(unsigned char const&, bool const&) Line | Count | Source | 115 | 2 | { | 116 | 2 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 2 | m_key_scratch << key; | 118 | 2 | m_value_scratch << value; | 119 | 2 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 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 | 115 | 2 | { | 116 | 2 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 2 | m_key_scratch << key; | 118 | 2 | m_value_scratch << value; | 119 | 2 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 2 | } |
void CDBBatch::Write<unsigned char, uint256>(unsigned char const&, uint256 const&) Line | Count | Source | 115 | 3.96k | { | 116 | 3.96k | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 3.96k | m_key_scratch << key; | 118 | 3.96k | m_value_scratch << value; | 119 | 3.96k | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 3.96k | } |
void CDBBatch::Write<unsigned char, unsigned char>(unsigned char const&, unsigned char const&) Line | Count | Source | 115 | 19 | { | 116 | 19 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 19 | m_key_scratch << key; | 118 | 19 | m_value_scratch << value; | 119 | 19 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 19 | } |
void CDBBatch::Write<dbwrapper_tests::StringContentsSerializer, unsigned int>(dbwrapper_tests::StringContentsSerializer const&, unsigned int const&) Line | Count | Source | 115 | 100 | { | 116 | 100 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 100 | m_key_scratch << key; | 118 | 100 | m_value_scratch << value; | 119 | 100 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 100 | } |
void CDBBatch::Write<txindex::DBKey, std::array<std::byte, 0ul>>(txindex::DBKey const&, std::array<std::byte, 0ul> const&) Line | Count | Source | 115 | 4.38k | { | 116 | 4.38k | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 4.38k | m_key_scratch << key; | 118 | 4.38k | m_value_scratch << value; | 119 | 4.38k | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 4.38k | } |
void CDBBatch::Write<std::pair<unsigned char, uint256>, CDiskTxPos>(std::pair<unsigned char, uint256> const&, CDiskTxPos const&) Line | Count | Source | 115 | 2 | { | 116 | 2 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 2 | m_key_scratch << key; | 118 | 2 | m_value_scratch << value; | 119 | 2 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 2 | } |
void CDBBatch::Write<unsigned char, CBlockLocator>(unsigned char const&, CBlockLocator const&) Line | Count | Source | 115 | 219 | { | 116 | 219 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 219 | m_key_scratch << key; | 118 | 219 | m_value_scratch << value; | 119 | 219 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 219 | } |
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 | 115 | 563 | { | 116 | 563 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 563 | m_key_scratch << key; | 118 | 563 | m_value_scratch << value; | 119 | 563 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 563 | } |
void CDBBatch::Write<unsigned char, FlatFilePos>(unsigned char const&, FlatFilePos const&) Line | Count | Source | 115 | 178 | { | 116 | 178 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 178 | m_key_scratch << key; | 118 | 178 | m_value_scratch << value; | 119 | 178 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 178 | } |
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 | 115 | 7.98k | { | 116 | 7.98k | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 7.98k | m_key_scratch << key; | 118 | 7.98k | m_value_scratch << value; | 119 | 7.98k | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 7.98k | } |
blockfilterindex.cpp:void CDBBatch::Write<index_util::DBHashKey, (anonymous namespace)::DBVal>(index_util::DBHashKey const&, (anonymous namespace)::DBVal const&) Line | Count | Source | 115 | 112 | { | 116 | 112 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 112 | m_key_scratch << key; | 118 | 112 | m_value_scratch << value; | 119 | 112 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 112 | } |
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 | 115 | 4.08k | { | 116 | 4.08k | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 4.08k | m_key_scratch << key; | 118 | 4.08k | m_value_scratch << value; | 119 | 4.08k | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 4.08k | } |
coinstatsindex.cpp:void CDBBatch::Write<index_util::DBHashKey, (anonymous namespace)::DBVal>(index_util::DBHashKey const&, (anonymous namespace)::DBVal const&) Line | Count | Source | 115 | 121 | { | 116 | 121 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 121 | m_key_scratch << key; | 118 | 121 | m_value_scratch << value; | 119 | 121 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 121 | } |
void CDBBatch::Write<unsigned char, MuHash3072>(unsigned char const&, MuHash3072 const&) Line | Count | Source | 115 | 118 | { | 116 | 118 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 118 | m_key_scratch << key; | 118 | 118 | m_value_scratch << value; | 119 | 118 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 118 | } |
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 | 115 | 22 | { | 116 | 22 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 22 | m_key_scratch << key; | 118 | 22 | m_value_scratch << value; | 119 | 22 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 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 | 115 | 55 | { | 116 | 55 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 55 | m_key_scratch << key; | 118 | 55 | m_value_scratch << value; | 119 | 55 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 55 | } |
void CDBBatch::Write<txindex::BlockHashKey, unsigned int>(txindex::BlockHashKey const&, unsigned int const&) Line | Count | Source | 115 | 4.22k | { | 116 | 4.22k | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 4.22k | m_key_scratch << key; | 118 | 4.22k | m_value_scratch << value; | 119 | 4.22k | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 4.22k | } |
void CDBBatch::Write<txindex::BlockSeqKey, uint256>(txindex::BlockSeqKey const&, uint256 const&) Line | Count | Source | 115 | 4.22k | { | 116 | 4.22k | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 4.22k | m_key_scratch << key; | 118 | 4.22k | m_value_scratch << value; | 119 | 4.22k | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 4.22k | } |
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 | 115 | 4.22k | { | 116 | 4.22k | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 4.22k | m_key_scratch << key; | 118 | 4.22k | m_value_scratch << value; | 119 | 4.22k | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 4.22k | } |
void CDBBatch::Write<char [12], std::pair<unsigned long, unsigned long>>(char const (&) [12], std::pair<unsigned long, unsigned long> const&) Line | Count | Source | 115 | 9 | { | 116 | 9 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 9 | m_key_scratch << key; | 118 | 9 | m_value_scratch << value; | 119 | 9 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 9 | } |
void CDBBatch::Write<DBKey, std::span<std::byte const, 18446744073709551615ul>>(DBKey const&, std::span<std::byte const, 18446744073709551615ul> const&) Line | Count | Source | 115 | 38 | { | 116 | 38 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 38 | m_key_scratch << key; | 118 | 38 | m_value_scratch << value; | 119 | 38 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 38 | } |
void CDBBatch::Write<std::pair<unsigned char, int>, kernel::CBlockFileInfo>(std::pair<unsigned char, int> const&, kernel::CBlockFileInfo const&) Line | Count | Source | 115 | 1.72k | { | 116 | 1.72k | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 1.72k | m_key_scratch << key; | 118 | 1.72k | m_value_scratch << value; | 119 | 1.72k | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 1.72k | } |
void CDBBatch::Write<unsigned char, int>(unsigned char const&, int const&) Line | Count | Source | 115 | 3.64k | { | 116 | 3.64k | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 3.64k | m_key_scratch << key; | 118 | 3.64k | m_value_scratch << value; | 119 | 3.64k | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 3.64k | } |
void CDBBatch::Write<std::pair<unsigned char, uint256>, CDiskBlockIndex>(std::pair<unsigned char, uint256> const&, CDiskBlockIndex const&) Line | Count | Source | 115 | 117k | { | 116 | 117k | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 117k | m_key_scratch << key; | 118 | 117k | m_value_scratch << value; | 119 | 117k | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 117k | } |
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 | 115 | 8 | { | 116 | 8 | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 8 | m_key_scratch << key; | 118 | 8 | m_value_scratch << value; | 119 | 8 | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 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 | 115 | 3.92k | { | 116 | 3.92k | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 3.92k | m_key_scratch << key; | 118 | 3.92k | m_value_scratch << value; | 119 | 3.92k | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 3.92k | } |
txdb.cpp:void CDBBatch::Write<(anonymous namespace)::CoinEntry, Coin>((anonymous namespace)::CoinEntry const&, Coin const&) Line | Count | Source | 115 | 290k | { | 116 | 290k | ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch}; | 117 | 290k | m_key_scratch << key; | 118 | 290k | m_value_scratch << value; | 119 | 290k | WriteImpl(m_key_scratch, m_value_scratch); | 120 | 290k | } |
|
121 | | |
122 | | template <typename K> |
123 | | void Erase(const K& key) |
124 | 41.0k | { |
125 | 41.0k | ScopedDataStreamUsage scoped_key{m_key_scratch}; |
126 | 41.0k | m_key_scratch << key; |
127 | 41.0k | EraseImpl(m_key_scratch); |
128 | 41.0k | } void CDBBatch::Erase<unsigned char>(unsigned char const&) Line | Count | Source | 124 | 7.87k | { | 125 | 7.87k | ScopedDataStreamUsage scoped_key{m_key_scratch}; | 126 | 7.87k | m_key_scratch << key; | 127 | 7.87k | EraseImpl(m_key_scratch); | 128 | 7.87k | } |
void CDBBatch::Erase<txindex::DBKey>(txindex::DBKey const&) Line | Count | Source | 124 | 2 | { | 125 | 2 | ScopedDataStreamUsage scoped_key{m_key_scratch}; | 126 | 2 | m_key_scratch << key; | 127 | 2 | EraseImpl(m_key_scratch); | 128 | 2 | } |
void CDBBatch::Erase<DBKey>(DBKey const&) Line | Count | Source | 124 | 6 | { | 125 | 6 | ScopedDataStreamUsage scoped_key{m_key_scratch}; | 126 | 6 | m_key_scratch << key; | 127 | 6 | EraseImpl(m_key_scratch); | 128 | 6 | } |
txdb.cpp:void CDBBatch::Erase<(anonymous namespace)::CoinEntry>((anonymous namespace)::CoinEntry const&) Line | Count | Source | 124 | 33.2k | { | 125 | 33.2k | ScopedDataStreamUsage scoped_key{m_key_scratch}; | 126 | 33.2k | m_key_scratch << key; | 127 | 33.2k | EraseImpl(m_key_scratch); | 128 | 33.2k | } |
|
129 | | |
130 | | size_t ApproximateSize() const; |
131 | | }; |
132 | | |
133 | | class CDBIterator |
134 | | { |
135 | | public: |
136 | | struct IteratorImpl; |
137 | | |
138 | | private: |
139 | | const CDBWrapper &parent; |
140 | | const std::unique_ptr<IteratorImpl> m_impl_iter; |
141 | | DataStream m_scratch{}; |
142 | | |
143 | | void SeekImpl(std::span<const std::byte> key); |
144 | | std::span<const std::byte> GetKeyImpl() const; |
145 | | std::span<const std::byte> GetValueImpl() const; |
146 | | |
147 | | public: |
148 | | |
149 | | /** |
150 | | * @param[in] _parent Parent CDBWrapper instance. |
151 | | * @param[in] _piter The original leveldb iterator. |
152 | | */ |
153 | | CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter); |
154 | | ~CDBIterator(); |
155 | | |
156 | | bool Valid() const; |
157 | | |
158 | | void SeekToFirst(); |
159 | | |
160 | 4.89k | template<typename K> void Seek(const K& key) { |
161 | 4.89k | ScopedDataStreamUsage scoped_scratch{m_scratch}; |
162 | 4.89k | m_scratch << key; |
163 | 4.89k | SeekImpl(m_scratch); |
164 | 4.89k | } void CDBIterator::Seek<unsigned char>(unsigned char const&) Line | Count | Source | 160 | 1.26k | template<typename K> void Seek(const K& key) { | 161 | 1.26k | ScopedDataStreamUsage scoped_scratch{m_scratch}; | 162 | 1.26k | m_scratch << key; | 163 | 1.26k | SeekImpl(m_scratch); | 164 | 1.26k | } |
void CDBIterator::Seek<dbwrapper_tests::StringContentsSerializer>(dbwrapper_tests::StringContentsSerializer const&) Line | Count | Source | 160 | 2 | template<typename K> void Seek(const K& key) { | 161 | 2 | ScopedDataStreamUsage scoped_scratch{m_scratch}; | 162 | 2 | m_scratch << key; | 163 | 2 | SeekImpl(m_scratch); | 164 | 2 | } |
void CDBIterator::Seek<txindex::DBKey>(txindex::DBKey const&) Line | Count | Source | 160 | 265 | template<typename K> void Seek(const K& key) { | 161 | 265 | ScopedDataStreamUsage scoped_scratch{m_scratch}; | 162 | 265 | m_scratch << key; | 163 | 265 | SeekImpl(m_scratch); | 164 | 265 | } |
void CDBIterator::Seek<index_util::DBHeightKey>(index_util::DBHeightKey const&) Line | Count | Source | 160 | 681 | template<typename K> void Seek(const K& key) { | 161 | 681 | ScopedDataStreamUsage scoped_scratch{m_scratch}; | 162 | 681 | m_scratch << key; | 163 | 681 | SeekImpl(m_scratch); | 164 | 681 | } |
void CDBIterator::Seek<std::pair<unsigned char, unsigned long>>(std::pair<unsigned char, unsigned long> const&) Line | Count | Source | 160 | 36 | template<typename K> void Seek(const K& key) { | 161 | 36 | ScopedDataStreamUsage scoped_scratch{m_scratch}; | 162 | 36 | m_scratch << key; | 163 | 36 | SeekImpl(m_scratch); | 164 | 36 | } |
void CDBIterator::Seek<std::pair<unsigned char, uint256>>(std::pair<unsigned char, uint256> const&) Line | Count | Source | 160 | 2.64k | template<typename K> void Seek(const K& key) { | 161 | 2.64k | ScopedDataStreamUsage scoped_scratch{m_scratch}; | 162 | 2.64k | m_scratch << key; | 163 | 2.64k | SeekImpl(m_scratch); | 164 | 2.64k | } |
|
165 | | |
166 | | void Next(); |
167 | | |
168 | 429k | template<typename K> bool GetKey(K& key) { |
169 | 429k | try { |
170 | 429k | SpanReader ssKey{GetKeyImpl()}; |
171 | 429k | ssKey >> key; |
172 | 429k | } catch (const std::exception&) { |
173 | 821 | return false; |
174 | 821 | } |
175 | 429k | return true; |
176 | 429k | } bool CDBIterator::GetKey<unsigned short>(unsigned short&) Line | Count | Source | 168 | 2 | template<typename K> bool GetKey(K& key) { | 169 | 2 | try { | 170 | 2 | SpanReader ssKey{GetKeyImpl()}; | 171 | 2 | ssKey >> key; | 172 | 2 | } catch (const std::exception&) { | 173 | 2 | return false; | 174 | 2 | } | 175 | 0 | return true; | 176 | 2 | } |
bool CDBIterator::GetKey<unsigned char>(unsigned char&) Line | Count | Source | 168 | 390 | template<typename K> bool GetKey(K& key) { | 169 | 390 | try { | 170 | 390 | SpanReader ssKey{GetKeyImpl()}; | 171 | 390 | ssKey >> key; | 172 | 390 | } catch (const std::exception&) { | 173 | 0 | return false; | 174 | 0 | } | 175 | 390 | return true; | 176 | 390 | } |
bool CDBIterator::GetKey<dbwrapper_tests::StringContentsSerializer>(dbwrapper_tests::StringContentsSerializer&) Line | Count | Source | 168 | 150 | template<typename K> bool GetKey(K& key) { | 169 | 150 | try { | 170 | 150 | SpanReader ssKey{GetKeyImpl()}; | 171 | 150 | ssKey >> key; | 172 | 150 | } catch (const std::exception&) { | 173 | 0 | return false; | 174 | 0 | } | 175 | 150 | return true; | 176 | 150 | } |
bool CDBIterator::GetKey<txindex::DBKey>(txindex::DBKey&) Line | Count | Source | 168 | 325 | template<typename K> bool GetKey(K& key) { | 169 | 325 | try { | 170 | 325 | SpanReader ssKey{GetKeyImpl()}; | 171 | 325 | ssKey >> key; | 172 | 325 | } catch (const std::exception&) { | 173 | 0 | return false; | 174 | 0 | } | 175 | 325 | return true; | 176 | 325 | } |
bool CDBIterator::GetKey<index_util::DBHeightKey>(index_util::DBHeightKey&) Line | Count | Source | 168 | 3.09k | template<typename K> bool GetKey(K& key) { | 169 | 3.09k | try { | 170 | 3.09k | SpanReader ssKey{GetKeyImpl()}; | 171 | 3.09k | ssKey >> key; | 172 | 3.09k | } catch (const std::exception&) { | 173 | 0 | return false; | 174 | 0 | } | 175 | 3.09k | return true; | 176 | 3.09k | } |
bool CDBIterator::GetKey<DBKey>(DBKey&) Line | Count | Source | 168 | 27 | template<typename K> bool GetKey(K& key) { | 169 | 27 | try { | 170 | 27 | SpanReader ssKey{GetKeyImpl()}; | 171 | 27 | ssKey >> key; | 172 | 27 | } catch (const std::exception&) { | 173 | 0 | return false; | 174 | 0 | } | 175 | 27 | return true; | 176 | 27 | } |
bool CDBIterator::GetKey<std::pair<unsigned char, uint256>>(std::pair<unsigned char, uint256>&) Line | Count | Source | 168 | 152k | template<typename K> bool GetKey(K& key) { | 169 | 152k | try { | 170 | 152k | SpanReader ssKey{GetKeyImpl()}; | 171 | 152k | ssKey >> key; | 172 | 152k | } catch (const std::exception&) { | 173 | 819 | return false; | 174 | 819 | } | 175 | 151k | return true; | 176 | 152k | } |
txdb.cpp:bool CDBIterator::GetKey<(anonymous namespace)::CoinEntry>((anonymous namespace)::CoinEntry&) Line | Count | Source | 168 | 273k | template<typename K> bool GetKey(K& key) { | 169 | 273k | try { | 170 | 273k | SpanReader ssKey{GetKeyImpl()}; | 171 | 273k | ssKey >> key; | 172 | 273k | } catch (const std::exception&) { | 173 | 0 | return false; | 174 | 0 | } | 175 | 273k | return true; | 176 | 273k | } |
|
177 | | |
178 | 428k | template<typename V> bool GetValue(V& value) { |
179 | 428k | try { |
180 | 428k | ScopedDataStreamUsage scoped_scratch{m_scratch}; |
181 | 428k | m_scratch.write(GetValueImpl()); |
182 | 428k | dbwrapper_private::GetObfuscation(parent)(m_scratch); |
183 | 428k | m_scratch >> value; |
184 | 428k | } catch (const std::exception&) { |
185 | 2 | return false; |
186 | 2 | } |
187 | 428k | return true; |
188 | 428k | } bool CDBIterator::GetValue<std::pair<uint256, unsigned char>>(std::pair<uint256, unsigned char>&) Line | Count | Source | 178 | 2 | template<typename V> bool GetValue(V& value) { | 179 | 2 | try { | 180 | 2 | ScopedDataStreamUsage scoped_scratch{m_scratch}; | 181 | 2 | m_scratch.write(GetValueImpl()); | 182 | 2 | dbwrapper_private::GetObfuscation(parent)(m_scratch); | 183 | 2 | m_scratch >> value; | 184 | 2 | } catch (const std::exception&) { | 185 | 2 | return false; | 186 | 2 | } | 187 | 0 | return true; | 188 | 2 | } |
bool CDBIterator::GetValue<uint256>(uint256&) Line | Count | Source | 178 | 8 | template<typename V> bool GetValue(V& value) { | 179 | 8 | try { | 180 | 8 | ScopedDataStreamUsage scoped_scratch{m_scratch}; | 181 | 8 | m_scratch.write(GetValueImpl()); | 182 | 8 | dbwrapper_private::GetObfuscation(parent)(m_scratch); | 183 | 8 | m_scratch >> value; | 184 | 8 | } catch (const std::exception&) { | 185 | 0 | return false; | 186 | 0 | } | 187 | 8 | return true; | 188 | 8 | } |
bool CDBIterator::GetValue<unsigned int>(unsigned int&) Line | Count | Source | 178 | 342 | template<typename V> bool GetValue(V& value) { | 179 | 342 | try { | 180 | 342 | ScopedDataStreamUsage scoped_scratch{m_scratch}; | 181 | 342 | m_scratch.write(GetValueImpl()); | 182 | 342 | dbwrapper_private::GetObfuscation(parent)(m_scratch); | 183 | 342 | m_scratch >> value; | 184 | 342 | } catch (const std::exception&) { | 185 | 0 | return false; | 186 | 0 | } | 187 | 342 | return true; | 188 | 342 | } |
blockfilterindex.cpp:bool CDBIterator::GetValue<std::pair<uint256, (anonymous namespace)::DBVal>>(std::pair<uint256, (anonymous namespace)::DBVal>&) Line | Count | Source | 178 | 2.97k | template<typename V> bool GetValue(V& value) { | 179 | 2.97k | try { | 180 | 2.97k | ScopedDataStreamUsage scoped_scratch{m_scratch}; | 181 | 2.97k | m_scratch.write(GetValueImpl()); | 182 | 2.97k | dbwrapper_private::GetObfuscation(parent)(m_scratch); | 183 | 2.97k | m_scratch >> value; | 184 | 2.97k | } catch (const std::exception&) { | 185 | 0 | return false; | 186 | 0 | } | 187 | 2.97k | return true; | 188 | 2.97k | } |
coinstatsindex.cpp:bool CDBIterator::GetValue<std::pair<uint256, (anonymous namespace)::DBVal>>(std::pair<uint256, (anonymous namespace)::DBVal>&) Line | Count | Source | 178 | 121 | template<typename V> bool GetValue(V& value) { | 179 | 121 | try { | 180 | 121 | ScopedDataStreamUsage scoped_scratch{m_scratch}; | 181 | 121 | m_scratch.write(GetValueImpl()); | 182 | 121 | dbwrapper_private::GetObfuscation(parent)(m_scratch); | 183 | 121 | m_scratch >> value; | 184 | 121 | } catch (const std::exception&) { | 185 | 0 | return false; | 186 | 0 | } | 187 | 121 | return true; | 188 | 121 | } |
bool CDBIterator::GetValue<CDiskBlockIndex>(CDiskBlockIndex&) Line | Count | Source | 178 | 151k | template<typename V> bool GetValue(V& value) { | 179 | 151k | try { | 180 | 151k | ScopedDataStreamUsage scoped_scratch{m_scratch}; | 181 | 151k | m_scratch.write(GetValueImpl()); | 182 | 151k | dbwrapper_private::GetObfuscation(parent)(m_scratch); | 183 | 151k | m_scratch >> value; | 184 | 151k | } catch (const std::exception&) { | 185 | 0 | return false; | 186 | 0 | } | 187 | 151k | return true; | 188 | 151k | } |
bool CDBIterator::GetValue<Coin>(Coin&) Line | Count | Source | 178 | 273k | template<typename V> bool GetValue(V& value) { | 179 | 273k | try { | 180 | 273k | ScopedDataStreamUsage scoped_scratch{m_scratch}; | 181 | 273k | m_scratch.write(GetValueImpl()); | 182 | 273k | dbwrapper_private::GetObfuscation(parent)(m_scratch); | 183 | 273k | m_scratch >> value; | 184 | 273k | } catch (const std::exception&) { | 185 | 0 | return false; | 186 | 0 | } | 187 | 273k | return true; | 188 | 273k | } |
|
189 | | }; |
190 | | |
191 | | struct LevelDBContext; |
192 | | |
193 | | class CDBWrapper |
194 | | { |
195 | | friend const Obfuscation& dbwrapper_private::GetObfuscation(const CDBWrapper&); |
196 | | private: |
197 | | //! holds all leveldb-specific fields of this class |
198 | | util::NotNullUniquePtr<LevelDBContext> m_db_context; |
199 | | |
200 | | //! the name of this database |
201 | | std::string m_name; |
202 | | |
203 | | //! optional XOR-obfuscation of the database |
204 | | Obfuscation m_obfuscation; |
205 | | |
206 | | //! obfuscation key storage key, null-prefixed to avoid collisions |
207 | | inline static const std::string OBFUSCATION_KEY{"\000obfuscate_key", 14}; // explicit size to avoid truncation at leading \0 |
208 | | |
209 | | std::optional<std::string> ReadImpl(std::span<const std::byte> key) const; |
210 | | bool ExistsImpl(std::span<const std::byte> key) const; |
211 | | size_t EstimateSizeImpl(std::span<const std::byte> key1, std::span<const std::byte> key2) const; |
212 | 11.0M | auto& DBContext() const LIFETIMEBOUND { return *m_db_context; } |
213 | | |
214 | | public: |
215 | | CDBWrapper(const DBParams& params); |
216 | | ~CDBWrapper(); |
217 | | |
218 | | CDBWrapper(const CDBWrapper&) = delete; |
219 | | CDBWrapper& operator=(const CDBWrapper&) = delete; |
220 | | |
221 | | struct ReadFailure { |
222 | | enum class Code { |
223 | | DeserializationError, //!< Key exists but value could not be deserialized. |
224 | | DatabaseError, //!< Unexpected internal DB error. |
225 | | }; |
226 | | |
227 | | Code status; |
228 | | std::string err_msg; |
229 | | }; |
230 | | |
231 | | using ReadStatus = util::Expected<bool, ReadFailure>; |
232 | | |
233 | | /** |
234 | | * Read and deserialize a value from the database, with explicit error discrimination. |
235 | | * |
236 | | * Unlike Read(), this method distinguishes between a missing key, a deserialization |
237 | | * failure (DeserializationError), and an internal DB error (DatabaseError), |
238 | | * enabling callers to treat data corruption differently from an absent entry. |
239 | | * |
240 | | * @note Callers are expected to provide well-formed keys; key serialization |
241 | | * is the only operation that may throw. |
242 | | * |
243 | | * @param[in] key The key to look up. |
244 | | * @param[out] value Populated with the deserialized value when the returned |
245 | | * Expected holds true; indeterminate otherwise. |
246 | | * @return On success, true if the key was found (value populated) or false if |
247 | | * the key was absent. On failure, a ReadFailure describing the error. |
248 | | */ |
249 | | template <typename K, typename V> |
250 | | [[nodiscard]] ReadStatus TryRead(const K& key, V& value) const |
251 | 5.44M | { |
252 | 5.44M | DataStream ssKey{}; |
253 | 5.44M | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); |
254 | | // Key serialization is the only operation that may throw. |
255 | | // Callers are expected to provide well-formed keys. |
256 | 5.44M | ssKey << key; |
257 | | |
258 | 5.44M | std::optional<std::string> strValue; |
259 | 5.44M | try { |
260 | 5.44M | strValue = ReadImpl(ssKey); |
261 | 5.44M | if (!strValue) { |
262 | 5.33M | return false; // not found |
263 | 5.33M | } |
264 | 5.44M | } catch (const std::exception& e) { |
265 | 3 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); |
266 | 3 | } |
267 | | |
268 | 111k | try { |
269 | 111k | std::span ssValue{MakeWritableByteSpan(*strValue)}; |
270 | 111k | m_obfuscation(ssValue); |
271 | 111k | SpanReader{ssValue} >> value; |
272 | 111k | } catch (const std::exception& e) { |
273 | 4 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); |
274 | 4 | } |
275 | | |
276 | 111k | return true; |
277 | 111k | } util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<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 | 251 | 8 | { | 252 | 8 | DataStream ssKey{}; | 253 | 8 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 8 | ssKey << key; | 257 | | | 258 | 8 | std::optional<std::string> strValue; | 259 | 8 | try { | 260 | 8 | strValue = ReadImpl(ssKey); | 261 | 8 | if (!strValue) { | 262 | 0 | return false; // not found | 263 | 0 | } | 264 | 8 | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 8 | try { | 269 | 8 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 8 | m_obfuscation(ssValue); | 271 | 8 | SpanReader{ssValue} >> value; | 272 | 8 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 8 | return true; | 277 | 8 | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<unsigned char, unsigned int>(unsigned char const&, unsigned int&) const Line | Count | Source | 251 | 2 | { | 252 | 2 | DataStream ssKey{}; | 253 | 2 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 2 | ssKey << key; | 257 | | | 258 | 2 | std::optional<std::string> strValue; | 259 | 2 | try { | 260 | 2 | strValue = ReadImpl(ssKey); | 261 | 2 | if (!strValue) { | 262 | 0 | return false; // not found | 263 | 0 | } | 264 | 2 | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 2 | try { | 269 | 2 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 2 | m_obfuscation(ssValue); | 271 | 2 | SpanReader{ssValue} >> value; | 272 | 2 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 2 | return true; | 277 | 2 | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<unsigned char, bool>(unsigned char const&, bool&) const Line | Count | Source | 251 | 2 | { | 252 | 2 | DataStream ssKey{}; | 253 | 2 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 2 | ssKey << key; | 257 | | | 258 | 2 | std::optional<std::string> strValue; | 259 | 2 | try { | 260 | 2 | strValue = ReadImpl(ssKey); | 261 | 2 | if (!strValue) { | 262 | 0 | return false; // not found | 263 | 0 | } | 264 | 2 | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 2 | try { | 269 | 2 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 2 | m_obfuscation(ssValue); | 271 | 2 | SpanReader{ssValue} >> value; | 272 | 2 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 2 | return true; | 277 | 2 | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<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 | 251 | 2 | { | 252 | 2 | DataStream ssKey{}; | 253 | 2 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 2 | ssKey << key; | 257 | | | 258 | 2 | std::optional<std::string> strValue; | 259 | 2 | try { | 260 | 2 | strValue = ReadImpl(ssKey); | 261 | 2 | if (!strValue) { | 262 | 0 | return false; // not found | 263 | 0 | } | 264 | 2 | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 2 | try { | 269 | 2 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 2 | m_obfuscation(ssValue); | 271 | 2 | SpanReader{ssValue} >> value; | 272 | 2 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 2 | return true; | 277 | 2 | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<unsigned char, uint256>(unsigned char const&, uint256&) const Line | Count | Source | 251 | 8.23k | { | 252 | 8.23k | DataStream ssKey{}; | 253 | 8.23k | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 8.23k | ssKey << key; | 257 | | | 258 | 8.23k | std::optional<std::string> strValue; | 259 | 8.23k | try { | 260 | 8.23k | strValue = ReadImpl(ssKey); | 261 | 8.23k | if (!strValue) { | 262 | 1.88k | return false; // not found | 263 | 1.88k | } | 264 | 8.23k | } catch (const std::exception& e) { | 265 | 2 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 2 | } | 267 | | | 268 | 6.34k | try { | 269 | 6.34k | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 6.34k | m_obfuscation(ssValue); | 271 | 6.34k | SpanReader{ssValue} >> value; | 272 | 6.34k | } catch (const std::exception& e) { | 273 | 4 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 4 | } | 275 | | | 276 | 6.33k | return true; | 277 | 6.34k | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<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 | 251 | 49 | { | 252 | 49 | DataStream ssKey{}; | 253 | 49 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 49 | ssKey << key; | 257 | | | 258 | 49 | std::optional<std::string> strValue; | 259 | 49 | try { | 260 | 49 | strValue = ReadImpl(ssKey); | 261 | 49 | if (!strValue) { | 262 | 22 | return false; // not found | 263 | 22 | } | 264 | 49 | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 27 | try { | 269 | 27 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 27 | m_obfuscation(ssValue); | 271 | 27 | SpanReader{ssValue} >> value; | 272 | 27 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 27 | return true; | 277 | 27 | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<unsigned char, CBlockLocator>(unsigned char const&, CBlockLocator&) const Line | Count | Source | 251 | 165 | { | 252 | 165 | DataStream ssKey{}; | 253 | 165 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 165 | ssKey << key; | 257 | | | 258 | 165 | std::optional<std::string> strValue; | 259 | 165 | try { | 260 | 165 | strValue = ReadImpl(ssKey); | 261 | 165 | if (!strValue) { | 262 | 83 | return false; // not found | 263 | 83 | } | 264 | 165 | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 82 | try { | 269 | 82 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 82 | m_obfuscation(ssValue); | 271 | 82 | SpanReader{ssValue} >> value; | 272 | 82 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 82 | return true; | 277 | 82 | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<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 | 251 | 3.04k | { | 252 | 3.04k | DataStream ssKey{}; | 253 | 3.04k | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 3.04k | ssKey << key; | 257 | | | 258 | 3.04k | std::optional<std::string> strValue; | 259 | 3.04k | try { | 260 | 3.04k | strValue = ReadImpl(ssKey); | 261 | 3.04k | if (!strValue) { | 262 | 2.11k | return false; // not found | 263 | 2.11k | } | 264 | 3.04k | } catch (const std::exception& e) { | 265 | 1 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 1 | } | 267 | | | 268 | 931 | try { | 269 | 931 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 931 | m_obfuscation(ssValue); | 271 | 931 | SpanReader{ssValue} >> value; | 272 | 931 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 931 | return true; | 277 | 931 | } |
blockfilterindex.cpp:util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<index_util::DBHashKey, (anonymous namespace)::DBVal>(index_util::DBHashKey const&, (anonymous namespace)::DBVal&) const Line | Count | Source | 251 | 33 | { | 252 | 33 | DataStream ssKey{}; | 253 | 33 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 33 | ssKey << key; | 257 | | | 258 | 33 | std::optional<std::string> strValue; | 259 | 33 | try { | 260 | 33 | strValue = ReadImpl(ssKey); | 261 | 33 | if (!strValue) { | 262 | 0 | return false; // not found | 263 | 0 | } | 264 | 33 | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 33 | try { | 269 | 33 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 33 | m_obfuscation(ssValue); | 271 | 33 | SpanReader{ssValue} >> value; | 272 | 33 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 33 | return true; | 277 | 33 | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<unsigned char, FlatFilePos>(unsigned char const&, FlatFilePos&) const Line | Count | Source | 251 | 53 | { | 252 | 53 | DataStream ssKey{}; | 253 | 53 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 53 | ssKey << key; | 257 | | | 258 | 53 | std::optional<std::string> strValue; | 259 | 53 | try { | 260 | 53 | strValue = ReadImpl(ssKey); | 261 | 53 | if (!strValue) { | 262 | 24 | return false; // not found | 263 | 24 | } | 264 | 53 | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 29 | try { | 269 | 29 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 29 | m_obfuscation(ssValue); | 271 | 29 | SpanReader{ssValue} >> value; | 272 | 29 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 29 | return true; | 277 | 29 | } |
blockfilterindex.cpp:util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<index_util::DBHeightKey, std::pair<uint256, (anonymous namespace)::DBVal>>(index_util::DBHeightKey const&, std::pair<uint256, (anonymous namespace)::DBVal>&) const Line | Count | Source | 251 | 1.33k | { | 252 | 1.33k | DataStream ssKey{}; | 253 | 1.33k | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 1.33k | ssKey << key; | 257 | | | 258 | 1.33k | std::optional<std::string> strValue; | 259 | 1.33k | try { | 260 | 1.33k | strValue = ReadImpl(ssKey); | 261 | 1.33k | if (!strValue) { | 262 | 304 | return false; // not found | 263 | 304 | } | 264 | 1.33k | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 1.02k | try { | 269 | 1.02k | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 1.02k | m_obfuscation(ssValue); | 271 | 1.02k | SpanReader{ssValue} >> value; | 272 | 1.02k | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 1.02k | return true; | 277 | 1.02k | } |
coinstatsindex.cpp:util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<index_util::DBHashKey, (anonymous namespace)::DBVal>(index_util::DBHashKey const&, (anonymous namespace)::DBVal&) const Line | Count | Source | 251 | 2 | { | 252 | 2 | DataStream ssKey{}; | 253 | 2 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 2 | ssKey << key; | 257 | | | 258 | 2 | std::optional<std::string> strValue; | 259 | 2 | try { | 260 | 2 | strValue = ReadImpl(ssKey); | 261 | 2 | if (!strValue) { | 262 | 0 | return false; // not found | 263 | 0 | } | 264 | 2 | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 2 | try { | 269 | 2 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 2 | m_obfuscation(ssValue); | 271 | 2 | SpanReader{ssValue} >> value; | 272 | 2 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 2 | return true; | 277 | 2 | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<unsigned char, MuHash3072>(unsigned char const&, MuHash3072&) const Line | Count | Source | 251 | 52 | { | 252 | 52 | DataStream ssKey{}; | 253 | 52 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 52 | ssKey << key; | 257 | | | 258 | 52 | std::optional<std::string> strValue; | 259 | 52 | try { | 260 | 52 | strValue = ReadImpl(ssKey); | 261 | 52 | if (!strValue) { | 262 | 21 | return false; // not found | 263 | 21 | } | 264 | 52 | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 31 | try { | 269 | 31 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 31 | m_obfuscation(ssValue); | 271 | 31 | SpanReader{ssValue} >> value; | 272 | 31 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 31 | return true; | 277 | 31 | } |
coinstatsindex.cpp:util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<index_util::DBHeightKey, std::pair<uint256, (anonymous namespace)::DBVal>>(index_util::DBHeightKey const&, std::pair<uint256, (anonymous namespace)::DBVal>&) const Line | Count | Source | 251 | 222 | { | 252 | 222 | DataStream ssKey{}; | 253 | 222 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 222 | ssKey << key; | 257 | | | 258 | 222 | std::optional<std::string> strValue; | 259 | 222 | try { | 260 | 222 | strValue = ReadImpl(ssKey); | 261 | 222 | if (!strValue) { | 262 | 1 | return false; // not found | 263 | 1 | } | 264 | 222 | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 221 | try { | 269 | 221 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 221 | m_obfuscation(ssValue); | 271 | 221 | SpanReader{ssValue} >> value; | 272 | 221 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 221 | return true; | 277 | 221 | } |
Unexecuted instantiation: coinstatsindex.cpp:util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<index_util::DBHashKey, std::pair<uint256, (anonymous namespace)::DBVal>>(index_util::DBHashKey const&, std::pair<uint256, (anonymous namespace)::DBVal>&) const util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<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 | 251 | 52 | { | 252 | 52 | DataStream ssKey{}; | 253 | 52 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 52 | ssKey << key; | 257 | | | 258 | 52 | std::optional<std::string> strValue; | 259 | 52 | try { | 260 | 52 | strValue = ReadImpl(ssKey); | 261 | 52 | if (!strValue) { | 262 | 27 | return false; // not found | 263 | 27 | } | 264 | 52 | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 25 | try { | 269 | 25 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 25 | m_obfuscation(ssValue); | 271 | 25 | SpanReader{ssValue} >> value; | 272 | 25 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 25 | return true; | 277 | 25 | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<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 | 251 | 4.22k | { | 252 | 4.22k | DataStream ssKey{}; | 253 | 4.22k | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 4.22k | ssKey << key; | 257 | | | 258 | 4.22k | std::optional<std::string> strValue; | 259 | 4.22k | try { | 260 | 4.22k | strValue = ReadImpl(ssKey); | 261 | 4.22k | if (!strValue) { | 262 | 20 | return false; // not found | 263 | 20 | } | 264 | 4.22k | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 4.20k | try { | 269 | 4.20k | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 4.20k | m_obfuscation(ssValue); | 271 | 4.20k | SpanReader{ssValue} >> value; | 272 | 4.20k | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 4.20k | return true; | 277 | 4.20k | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<txindex::BlockSeqKey, uint256>(txindex::BlockSeqKey const&, uint256&) const Line | Count | Source | 251 | 156 | { | 252 | 156 | DataStream ssKey{}; | 253 | 156 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 156 | ssKey << key; | 257 | | | 258 | 156 | std::optional<std::string> strValue; | 259 | 156 | try { | 260 | 156 | strValue = ReadImpl(ssKey); | 261 | 156 | if (!strValue) { | 262 | 0 | return false; // not found | 263 | 0 | } | 264 | 156 | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 156 | try { | 269 | 156 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 156 | m_obfuscation(ssValue); | 271 | 156 | SpanReader{ssValue} >> value; | 272 | 156 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 156 | return true; | 277 | 156 | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<std::pair<unsigned char, uint256>, CDiskTxPos>(std::pair<unsigned char, uint256> const&, CDiskTxPos&) const Line | Count | Source | 251 | 3 | { | 252 | 3 | DataStream ssKey{}; | 253 | 3 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 3 | ssKey << key; | 257 | | | 258 | 3 | std::optional<std::string> strValue; | 259 | 3 | try { | 260 | 3 | strValue = ReadImpl(ssKey); | 261 | 3 | if (!strValue) { | 262 | 0 | return false; // not found | 263 | 0 | } | 264 | 3 | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 3 | try { | 269 | 3 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 3 | m_obfuscation(ssValue); | 271 | 3 | SpanReader{ssValue} >> value; | 272 | 3 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 3 | return true; | 277 | 3 | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<char [12], std::pair<unsigned long, unsigned long>>(char const (&) [12], std::pair<unsigned long, unsigned long>&) const Line | Count | Source | 251 | 28 | { | 252 | 28 | DataStream ssKey{}; | 253 | 28 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 28 | ssKey << key; | 257 | | | 258 | 28 | std::optional<std::string> strValue; | 259 | 28 | try { | 260 | 28 | strValue = ReadImpl(ssKey); | 261 | 28 | if (!strValue) { | 262 | 9 | return false; // not found | 263 | 9 | } | 264 | 28 | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 19 | try { | 269 | 19 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 19 | m_obfuscation(ssValue); | 271 | 19 | SpanReader{ssValue} >> value; | 272 | 19 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 19 | return true; | 277 | 19 | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<std::pair<unsigned char, int>, kernel::CBlockFileInfo>(std::pair<unsigned char, int> const&, kernel::CBlockFileInfo&) const Line | Count | Source | 251 | 2.64k | { | 252 | 2.64k | DataStream ssKey{}; | 253 | 2.64k | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 2.64k | ssKey << key; | 257 | | | 258 | 2.64k | std::optional<std::string> strValue; | 259 | 2.64k | try { | 260 | 2.64k | strValue = ReadImpl(ssKey); | 261 | 2.64k | if (!strValue) { | 262 | 1.80k | return false; // not found | 263 | 1.80k | } | 264 | 2.64k | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 834 | try { | 269 | 834 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 834 | m_obfuscation(ssValue); | 271 | 834 | SpanReader{ssValue} >> value; | 272 | 834 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 834 | return true; | 277 | 834 | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<unsigned char, int>(unsigned char const&, int&) const Line | Count | Source | 251 | 1.31k | { | 252 | 1.31k | DataStream ssKey{}; | 253 | 1.31k | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 1.31k | ssKey << key; | 257 | | | 258 | 1.31k | std::optional<std::string> strValue; | 259 | 1.31k | try { | 260 | 1.31k | strValue = ReadImpl(ssKey); | 261 | 1.31k | if (!strValue) { | 262 | 495 | return false; // not found | 263 | 495 | } | 264 | 1.31k | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 817 | try { | 269 | 817 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 817 | m_obfuscation(ssValue); | 271 | 817 | SpanReader{ssValue} >> value; | 272 | 817 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 817 | return true; | 277 | 817 | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<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 | 251 | 1.31k | { | 252 | 1.31k | DataStream ssKey{}; | 253 | 1.31k | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 1.31k | ssKey << key; | 257 | | | 258 | 1.31k | std::optional<std::string> strValue; | 259 | 1.31k | try { | 260 | 1.31k | strValue = ReadImpl(ssKey); | 261 | 1.31k | if (!strValue) { | 262 | 1.30k | return false; // not found | 263 | 1.30k | } | 264 | 1.31k | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 2 | try { | 269 | 2 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 2 | m_obfuscation(ssValue); | 271 | 2 | SpanReader{ssValue} >> value; | 272 | 2 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 2 | return true; | 277 | 2 | } |
txdb.cpp:util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<(anonymous namespace)::CoinEntry, Coin>((anonymous namespace)::CoinEntry const&, Coin&) const Line | Count | Source | 251 | 5.42M | { | 252 | 5.42M | DataStream ssKey{}; | 253 | 5.42M | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 5.42M | ssKey << key; | 257 | | | 258 | 5.42M | std::optional<std::string> strValue; | 259 | 5.42M | try { | 260 | 5.42M | strValue = ReadImpl(ssKey); | 261 | 5.42M | if (!strValue) { | 262 | 5.32M | return false; // not found | 263 | 5.32M | } | 264 | 5.42M | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 96.4k | try { | 269 | 96.4k | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 96.4k | m_obfuscation(ssValue); | 271 | 96.4k | SpanReader{ssValue} >> value; | 272 | 96.4k | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 96.4k | return true; | 277 | 96.4k | } |
util::Expected<bool, CDBWrapper::ReadFailure> CDBWrapper::TryRead<unsigned char, std::vector<uint256, std::allocator<uint256>>>(unsigned char const&, std::vector<uint256, std::allocator<uint256>>&) const Line | Count | Source | 251 | 1.69k | { | 252 | 1.69k | DataStream ssKey{}; | 253 | 1.69k | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 254 | | // Key serialization is the only operation that may throw. | 255 | | // Callers are expected to provide well-formed keys. | 256 | 1.69k | ssKey << key; | 257 | | | 258 | 1.69k | std::optional<std::string> strValue; | 259 | 1.69k | try { | 260 | 1.69k | strValue = ReadImpl(ssKey); | 261 | 1.69k | if (!strValue) { | 262 | 1.69k | return false; // not found | 263 | 1.69k | } | 264 | 1.69k | } catch (const std::exception& e) { | 265 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()}); | 266 | 0 | } | 267 | | | 268 | 0 | try { | 269 | 0 | std::span ssValue{MakeWritableByteSpan(*strValue)}; | 270 | 0 | m_obfuscation(ssValue); | 271 | 0 | SpanReader{ssValue} >> value; | 272 | 0 | } catch (const std::exception& e) { | 273 | 0 | return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()}); | 274 | 0 | } | 275 | | | 276 | 0 | return true; | 277 | 0 | } |
|
278 | | |
279 | | /** |
280 | | * Wrapper around TryRead() that preserves the original Read() semantics: |
281 | | * returns true on success, false if the key is absent or deserialization |
282 | | * fails, and throws dbwrapper_error on an internal DB error. |
283 | | * |
284 | | * Prefer TryRead() when the caller needs to distinguish between a missing |
285 | | * key and a corrupt value. |
286 | | */ |
287 | | template <typename K, typename V> |
288 | | bool Read(const K& key, V& value) const |
289 | 24.6k | { |
290 | 24.6k | const ReadStatus res = TryRead(key,value); |
291 | 24.6k | if (res.has_value()) return res.value(); |
292 | 4 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { |
293 | 2 | case ReadFailure::Code::DeserializationError: return false; |
294 | 2 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); |
295 | 4 | } // no default case, so the compiler can warn about missing cases |
296 | 0 | std::abort(); // unreachable |
297 | 4 | } bool CDBWrapper::Read<unsigned char, uint256>(unsigned char const&, uint256&) const Line | Count | Source | 289 | 8.22k | { | 290 | 8.22k | const ReadStatus res = TryRead(key,value); | 291 | 8.22k | if (res.has_value()) return res.value(); | 292 | 3 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 2 | case ReadFailure::Code::DeserializationError: return false; | 294 | 1 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 3 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 3 | } |
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 | 289 | 8 | { | 290 | 8 | const ReadStatus res = TryRead(key,value); | 291 | 8 | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
bool CDBWrapper::Read<unsigned char, unsigned int>(unsigned char const&, unsigned int&) const Line | Count | Source | 289 | 2 | { | 290 | 2 | const ReadStatus res = TryRead(key,value); | 291 | 2 | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
bool CDBWrapper::Read<unsigned char, bool>(unsigned char const&, bool&) const Line | Count | Source | 289 | 2 | { | 290 | 2 | const ReadStatus res = TryRead(key,value); | 291 | 2 | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
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 | 289 | 2 | { | 290 | 2 | const ReadStatus res = TryRead(key,value); | 291 | 2 | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
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 | 289 | 49 | { | 290 | 49 | const ReadStatus res = TryRead(key,value); | 291 | 49 | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
bool CDBWrapper::Read<unsigned char, CBlockLocator>(unsigned char const&, CBlockLocator&) const Line | Count | Source | 289 | 165 | { | 290 | 165 | const ReadStatus res = TryRead(key,value); | 291 | 165 | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
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 | 289 | 3.04k | { | 290 | 3.04k | const ReadStatus res = TryRead(key,value); | 291 | 3.04k | if (res.has_value()) return res.value(); | 292 | 1 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 1 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 1 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 1 | } |
blockfilterindex.cpp:bool CDBWrapper::Read<index_util::DBHashKey, (anonymous namespace)::DBVal>(index_util::DBHashKey const&, (anonymous namespace)::DBVal&) const Line | Count | Source | 289 | 33 | { | 290 | 33 | const ReadStatus res = TryRead(key,value); | 291 | 33 | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
bool CDBWrapper::Read<unsigned char, FlatFilePos>(unsigned char const&, FlatFilePos&) const Line | Count | Source | 289 | 53 | { | 290 | 53 | const ReadStatus res = TryRead(key,value); | 291 | 53 | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
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 | 289 | 1.33k | { | 290 | 1.33k | const ReadStatus res = TryRead(key,value); | 291 | 1.33k | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
coinstatsindex.cpp:bool CDBWrapper::Read<index_util::DBHashKey, (anonymous namespace)::DBVal>(index_util::DBHashKey const&, (anonymous namespace)::DBVal&) const Line | Count | Source | 289 | 2 | { | 290 | 2 | const ReadStatus res = TryRead(key,value); | 291 | 2 | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
bool CDBWrapper::Read<unsigned char, MuHash3072>(unsigned char const&, MuHash3072&) const Line | Count | Source | 289 | 52 | { | 290 | 52 | const ReadStatus res = TryRead(key,value); | 291 | 52 | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
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 | 289 | 222 | { | 290 | 222 | const ReadStatus res = TryRead(key,value); | 291 | 222 | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
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 | 289 | 52 | { | 290 | 52 | const ReadStatus res = TryRead(key,value); | 291 | 52 | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
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 | 289 | 4.22k | { | 290 | 4.22k | const ReadStatus res = TryRead(key,value); | 291 | 4.22k | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
bool CDBWrapper::Read<txindex::BlockSeqKey, uint256>(txindex::BlockSeqKey const&, uint256&) const Line | Count | Source | 289 | 156 | { | 290 | 156 | const ReadStatus res = TryRead(key,value); | 291 | 156 | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
bool CDBWrapper::Read<std::pair<unsigned char, uint256>, CDiskTxPos>(std::pair<unsigned char, uint256> const&, CDiskTxPos&) const Line | Count | Source | 289 | 3 | { | 290 | 3 | const ReadStatus res = TryRead(key,value); | 291 | 3 | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
bool CDBWrapper::Read<char [12], std::pair<unsigned long, unsigned long>>(char const (&) [12], std::pair<unsigned long, unsigned long>&) const Line | Count | Source | 289 | 28 | { | 290 | 28 | const ReadStatus res = TryRead(key,value); | 291 | 28 | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
bool CDBWrapper::Read<std::pair<unsigned char, int>, kernel::CBlockFileInfo>(std::pair<unsigned char, int> const&, kernel::CBlockFileInfo&) const Line | Count | Source | 289 | 2.64k | { | 290 | 2.64k | const ReadStatus res = TryRead(key,value); | 291 | 2.64k | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
bool CDBWrapper::Read<unsigned char, int>(unsigned char const&, int&) const Line | Count | Source | 289 | 1.31k | { | 290 | 1.31k | const ReadStatus res = TryRead(key,value); | 291 | 1.31k | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 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 | 289 | 1.31k | { | 290 | 1.31k | const ReadStatus res = TryRead(key,value); | 291 | 1.31k | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
bool CDBWrapper::Read<unsigned char, std::vector<uint256, std::allocator<uint256>>>(unsigned char const&, std::vector<uint256, std::allocator<uint256>>&) const Line | Count | Source | 289 | 1.69k | { | 290 | 1.69k | const ReadStatus res = TryRead(key,value); | 291 | 1.69k | if (res.has_value()) return res.value(); | 292 | 0 | switch (const auto& [err_code, err_msg] = res.error(); err_code) { | 293 | 0 | case ReadFailure::Code::DeserializationError: return false; | 294 | 0 | case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg); | 295 | 0 | } // no default case, so the compiler can warn about missing cases | 296 | 0 | std::abort(); // unreachable | 297 | 0 | } |
|
298 | | |
299 | | template <typename K, typename V> |
300 | | void Write(const K& key, const V& value, bool fSync = false) |
301 | 13.0k | { |
302 | 13.0k | CDBBatch batch(*this); |
303 | 13.0k | batch.Write(key, value); |
304 | 13.0k | WriteBatch(batch, fSync); |
305 | 13.0k | } void CDBWrapper::Write<unsigned char, uint256>(unsigned char const&, uint256 const&, bool) Line | Count | Source | 301 | 33 | { | 302 | 33 | CDBBatch batch(*this); | 303 | 33 | batch.Write(key, value); | 304 | 33 | WriteBatch(batch, fSync); | 305 | 33 | } |
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 | 301 | 8 | { | 302 | 8 | CDBBatch batch(*this); | 303 | 8 | batch.Write(key, value); | 304 | 8 | WriteBatch(batch, fSync); | 305 | 8 | } |
void CDBWrapper::Write<unsigned char, unsigned int>(unsigned char const&, unsigned int const&, bool) Line | Count | Source | 301 | 258 | { | 302 | 258 | CDBBatch batch(*this); | 303 | 258 | batch.Write(key, value); | 304 | 258 | WriteBatch(batch, fSync); | 305 | 258 | } |
void CDBWrapper::Write<unsigned char, bool>(unsigned char const&, bool const&, bool) Line | Count | Source | 301 | 2 | { | 302 | 2 | CDBBatch batch(*this); | 303 | 2 | batch.Write(key, value); | 304 | 2 | WriteBatch(batch, fSync); | 305 | 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 | 301 | 2 | { | 302 | 2 | CDBBatch batch(*this); | 303 | 2 | batch.Write(key, value); | 304 | 2 | WriteBatch(batch, fSync); | 305 | 2 | } |
void CDBWrapper::Write<unsigned char, unsigned char>(unsigned char const&, unsigned char const&, bool) Line | Count | Source | 301 | 19 | { | 302 | 19 | CDBBatch batch(*this); | 303 | 19 | batch.Write(key, value); | 304 | 19 | WriteBatch(batch, fSync); | 305 | 19 | } |
void CDBWrapper::Write<dbwrapper_tests::StringContentsSerializer, unsigned int>(dbwrapper_tests::StringContentsSerializer const&, unsigned int const&, bool) Line | Count | Source | 301 | 100 | { | 302 | 100 | CDBBatch batch(*this); | 303 | 100 | batch.Write(key, value); | 304 | 100 | WriteBatch(batch, fSync); | 305 | 100 | } |
void CDBWrapper::Write<txindex::DBKey, std::array<std::byte, 0ul>>(txindex::DBKey const&, std::array<std::byte, 0ul> const&, bool) Line | Count | Source | 301 | 1 | { | 302 | 1 | CDBBatch batch(*this); | 303 | 1 | batch.Write(key, value); | 304 | 1 | WriteBatch(batch, fSync); | 305 | 1 | } |
void CDBWrapper::Write<std::pair<unsigned char, uint256>, CDiskTxPos>(std::pair<unsigned char, uint256> const&, CDiskTxPos const&, bool) Line | Count | Source | 301 | 2 | { | 302 | 2 | CDBBatch batch(*this); | 303 | 2 | batch.Write(key, value); | 304 | 2 | WriteBatch(batch, fSync); | 305 | 2 | } |
void CDBWrapper::Write<unsigned char, CBlockLocator>(unsigned char const&, CBlockLocator const&, bool) Line | Count | Source | 301 | 1 | { | 302 | 1 | CDBBatch batch(*this); | 303 | 1 | batch.Write(key, value); | 304 | 1 | WriteBatch(batch, fSync); | 305 | 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 | 301 | 563 | { | 302 | 563 | CDBBatch batch(*this); | 303 | 563 | batch.Write(key, value); | 304 | 563 | WriteBatch(batch, fSync); | 305 | 563 | } |
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 | 301 | 7.98k | { | 302 | 7.98k | CDBBatch batch(*this); | 303 | 7.98k | batch.Write(key, value); | 304 | 7.98k | WriteBatch(batch, fSync); | 305 | 7.98k | } |
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 | 301 | 4.08k | { | 302 | 4.08k | CDBBatch batch(*this); | 303 | 4.08k | batch.Write(key, value); | 304 | 4.08k | WriteBatch(batch, fSync); | 305 | 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 | 301 | 22 | { | 302 | 22 | CDBBatch batch(*this); | 303 | 22 | batch.Write(key, value); | 304 | 22 | WriteBatch(batch, fSync); | 305 | 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 | 301 | 9 | { | 302 | 9 | CDBBatch batch(*this); | 303 | 9 | batch.Write(key, value); | 304 | 9 | WriteBatch(batch, fSync); | 305 | 9 | } |
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 | 301 | 8 | { | 302 | 8 | CDBBatch batch(*this); | 303 | 8 | batch.Write(key, value); | 304 | 8 | WriteBatch(batch, fSync); | 305 | 8 | } |
|
306 | | |
307 | | template <typename K> |
308 | | bool Exists(const K& key) const |
309 | 6.13k | { |
310 | 6.13k | DataStream ssKey{}; |
311 | 6.13k | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); |
312 | 6.13k | ssKey << key; |
313 | 6.13k | return ExistsImpl(ssKey); |
314 | 6.13k | } bool CDBWrapper::Exists<unsigned char>(unsigned char const&) const Line | Count | Source | 309 | 1.35k | { | 310 | 1.35k | DataStream ssKey{}; | 311 | 1.35k | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 312 | 1.35k | ssKey << key; | 313 | 1.35k | return ExistsImpl(ssKey); | 314 | 1.35k | } |
bool CDBWrapper::Exists<txindex::BlockHashKey>(txindex::BlockHashKey const&) const Line | Count | Source | 309 | 4.73k | { | 310 | 4.73k | DataStream ssKey{}; | 311 | 4.73k | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 312 | 4.73k | ssKey << key; | 313 | 4.73k | return ExistsImpl(ssKey); | 314 | 4.73k | } |
txdb.cpp:bool CDBWrapper::Exists<(anonymous namespace)::CoinEntry>((anonymous namespace)::CoinEntry const&) const Line | Count | Source | 309 | 44 | { | 310 | 44 | DataStream ssKey{}; | 311 | 44 | ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); | 312 | 44 | ssKey << key; | 313 | 44 | return ExistsImpl(ssKey); | 314 | 44 | } |
|
315 | | |
316 | | template <typename K> |
317 | | void Erase(const K& key, bool fSync = false) |
318 | 16 | { |
319 | 16 | CDBBatch batch(*this); |
320 | 16 | batch.Erase(key); |
321 | 16 | WriteBatch(batch, fSync); |
322 | 16 | } void CDBWrapper::Erase<txindex::DBKey>(txindex::DBKey const&, bool) Line | Count | Source | 318 | 2 | { | 319 | 2 | CDBBatch batch(*this); | 320 | 2 | batch.Erase(key); | 321 | 2 | WriteBatch(batch, fSync); | 322 | 2 | } |
void CDBWrapper::Erase<unsigned char>(unsigned char const&, bool) Line | Count | Source | 318 | 14 | { | 319 | 14 | CDBBatch batch(*this); | 320 | 14 | batch.Erase(key); | 321 | 14 | WriteBatch(batch, fSync); | 322 | 14 | } |
|
323 | | |
324 | | void WriteBatch(CDBBatch& batch, bool fSync = false); |
325 | | |
326 | | //! Perform a blocking full compaction of the underlying LevelDB. |
327 | | void CompactFull(); |
328 | | |
329 | | //! Return a LevelDB property value, if available. |
330 | | std::optional<std::string> GetProperty(const std::string& property) const; |
331 | | |
332 | | // Get an estimate of LevelDB memory usage (in bytes). |
333 | | size_t DynamicMemoryUsage() const; |
334 | | |
335 | | CDBIterator* NewIterator(); |
336 | | |
337 | | /** |
338 | | * Return true if the database managed by this class contains no entries. |
339 | | */ |
340 | | bool IsEmpty(); |
341 | | |
342 | | //! Probe an unopened database for a key prefix. Return true if a database at |
343 | | //! path exists and contains at least 1 entry beginning with prefix; missing |
344 | | //! or empty databases return false, and database errors throw dbwrapper_error. |
345 | | static bool HasKeyStartingWith(const fs::path& path, uint8_t prefix); |
346 | | |
347 | | template<typename K> |
348 | | size_t EstimateSize(const K& key_begin, const K& key_end) const |
349 | 102 | { |
350 | 102 | DataStream ssKey1{}, ssKey2{}; |
351 | 102 | ssKey1.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); |
352 | 102 | ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); |
353 | 102 | ssKey1 << key_begin; |
354 | 102 | ssKey2 << key_end; |
355 | 102 | return EstimateSizeImpl(ssKey1, ssKey2); |
356 | 102 | } |
357 | | }; |
358 | | |
359 | | #endif // BITCOIN_DBWRAPPER_H |