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