Bitcoin Core 29.99.0
P2P Digital Currency
dbwrapper.h
Go to the documentation of this file.
1// Copyright (c) 2012-present The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#ifndef BITCOIN_DBWRAPPER_H
6#define BITCOIN_DBWRAPPER_H
7
8#include <attributes.h>
9#include <serialize.h>
10#include <span.h>
11#include <streams.h>
12#include <util/check.h>
13#include <util/fs.h>
14
15#include <cstddef>
16#include <exception>
17#include <memory>
18#include <optional>
19#include <stdexcept>
20#include <string>
21#include <vector>
22
23static const size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
24static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;
25static const size_t DBWRAPPER_MAX_FILE_SIZE = 32 << 20; // 32 MiB
26
28struct DBOptions {
30 bool force_compact = false;
31};
32
34struct DBParams {
36 fs::path path;
40 bool memory_only = false;
42 bool wipe_data = false;
45 bool obfuscate = false;
48};
49
50class dbwrapper_error : public std::runtime_error
51{
52public:
53 explicit dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {}
54};
55
56class CDBWrapper;
57
60namespace dbwrapper_private {
61
66const std::vector<unsigned char>& GetObfuscateKey(const CDBWrapper &w);
67
68}; // namespace dbwrapper_private
69
70bool DestroyDB(const std::string& path_str);
71
74{
75 friend class CDBWrapper;
76
77private:
79
80 struct WriteBatchImpl;
81 const std::unique_ptr<WriteBatchImpl> m_impl_batch;
82
85
86 void WriteImpl(std::span<const std::byte> key, DataStream& ssValue);
87 void EraseImpl(std::span<const std::byte> key);
88
89public:
93 explicit CDBBatch(const CDBWrapper& _parent);
95 void Clear();
96
97 template <typename K, typename V>
98 void Write(const K& key, const V& value)
99 {
102 ssKey << key;
103 ssValue << value;
105 ssKey.clear();
106 ssValue.clear();
107 }
108
109 template <typename K>
110 void Erase(const K& key)
111 {
113 ssKey << key;
115 ssKey.clear();
116 }
117
118 size_t ApproximateSize() const;
119};
120
122{
123public:
124 struct IteratorImpl;
125
126private:
128 const std::unique_ptr<IteratorImpl> m_impl_iter;
129
130 void SeekImpl(std::span<const std::byte> key);
131 std::span<const std::byte> GetKeyImpl() const;
132 std::span<const std::byte> GetValueImpl() const;
133
134public:
135
140 CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter);
142
143 bool Valid() const;
144
145 void SeekToFirst();
146
147 template<typename K> void Seek(const K& key) {
148 DataStream ssKey{};
150 ssKey << key;
151 SeekImpl(ssKey);
152 }
153
154 void Next();
155
156 template<typename K> bool GetKey(K& key) {
157 try {
158 DataStream ssKey{GetKeyImpl()};
159 ssKey >> key;
160 } catch (const std::exception&) {
161 return false;
162 }
163 return true;
164 }
165
166 template<typename V> bool GetValue(V& value) {
167 try {
168 DataStream ssValue{GetValueImpl()};
170 ssValue >> value;
171 } catch (const std::exception&) {
172 return false;
173 }
174 return true;
175 }
176};
177
178struct LevelDBContext;
179
181{
182 friend const std::vector<unsigned char>& dbwrapper_private::GetObfuscateKey(const CDBWrapper &w);
183private:
185 std::unique_ptr<LevelDBContext> m_db_context;
186
188 std::string m_name;
189
191 std::vector<unsigned char> obfuscate_key;
192
194 static const std::string OBFUSCATE_KEY_KEY;
195
197 static const unsigned int OBFUSCATE_KEY_NUM_BYTES;
198
199 std::vector<unsigned char> CreateObfuscateKey() const;
200
202 const fs::path m_path;
203
206
207 std::optional<std::string> ReadImpl(std::span<const std::byte> key) const;
208 bool ExistsImpl(std::span<const std::byte> key) const;
209 size_t EstimateSizeImpl(std::span<const std::byte> key1, std::span<const std::byte> key2) const;
210 auto& DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); }
211
212public:
213 CDBWrapper(const DBParams& params);
214 ~CDBWrapper();
215
216 CDBWrapper(const CDBWrapper&) = delete;
217 CDBWrapper& operator=(const CDBWrapper&) = delete;
218
219 template <typename K, typename V>
220 bool Read(const K& key, V& value) const
221 {
222 DataStream ssKey{};
224 ssKey << key;
225 std::optional<std::string> strValue{ReadImpl(ssKey)};
226 if (!strValue) {
227 return false;
228 }
229 try {
230 DataStream ssValue{MakeByteSpan(*strValue)};
231 ssValue.Xor(obfuscate_key);
232 ssValue >> value;
233 } catch (const std::exception&) {
234 return false;
235 }
236 return true;
237 }
238
239 template <typename K, typename V>
240 bool Write(const K& key, const V& value, bool fSync = false)
241 {
242 CDBBatch batch(*this);
243 batch.Write(key, value);
244 return WriteBatch(batch, fSync);
245 }
246
248 std::optional<fs::path> StoragePath() {
249 if (m_is_memory) {
250 return {};
251 }
252 return m_path;
253 }
254
255 template <typename K>
256 bool Exists(const K& key) const
257 {
258 DataStream ssKey{};
260 ssKey << key;
261 return ExistsImpl(ssKey);
262 }
263
264 template <typename K>
265 bool Erase(const K& key, bool fSync = false)
266 {
267 CDBBatch batch(*this);
268 batch.Erase(key);
269 return WriteBatch(batch, fSync);
270 }
271
272 bool WriteBatch(CDBBatch& batch, bool fSync = false);
273
274 // Get an estimate of LevelDB memory usage (in bytes).
275 size_t DynamicMemoryUsage() const;
276
278
282 bool IsEmpty();
283
284 template<typename K>
285 size_t EstimateSize(const K& key_begin, const K& key_end) const
286 {
287 DataStream ssKey1{}, ssKey2{};
289 ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
290 ssKey1 << key_begin;
291 ssKey2 << key_end;
292 return EstimateSizeImpl(ssKey1, ssKey2);
293 }
294};
295
296#endif // BITCOIN_DBWRAPPER_H
#define LIFETIMEBOUND
Definition: attributes.h:16
#define Assert(val)
Identity function.
Definition: check.h:85
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:74
void Erase(const K &key)
Definition: dbwrapper.h:110
void WriteImpl(std::span< const std::byte > key, DataStream &ssValue)
Definition: dbwrapper.cpp:173
const std::unique_ptr< WriteBatchImpl > m_impl_batch
Definition: dbwrapper.h:81
DataStream ssKey
Definition: dbwrapper.h:83
void Write(const K &key, const V &value)
Definition: dbwrapper.h:98
void EraseImpl(std::span< const std::byte > key)
Definition: dbwrapper.cpp:181
DataStream ssValue
Definition: dbwrapper.h:84
void Clear()
Definition: dbwrapper.cpp:168
CDBBatch(const CDBWrapper &_parent)
Definition: dbwrapper.cpp:159
size_t ApproximateSize() const
Definition: dbwrapper.cpp:187
const CDBWrapper & parent
Definition: dbwrapper.h:78
CDBIterator(const CDBWrapper &_parent, std::unique_ptr< IteratorImpl > _piter)
Definition: dbwrapper.cpp:384
bool GetValue(V &value)
Definition: dbwrapper.h:166
const std::unique_ptr< IteratorImpl > m_impl_iter
Definition: dbwrapper.h:128
void SeekImpl(std::span< const std::byte > key)
Definition: dbwrapper.cpp:392
std::span< const std::byte > GetKeyImpl() const
Definition: dbwrapper.cpp:398
bool GetKey(K &key)
Definition: dbwrapper.h:156
void Seek(const K &key)
Definition: dbwrapper.h:147
const CDBWrapper & parent
Definition: dbwrapper.h:127
bool Valid() const
Definition: dbwrapper.cpp:409
void SeekToFirst()
Definition: dbwrapper.cpp:410
void Next()
Definition: dbwrapper.cpp:411
std::span< const std::byte > GetValueImpl() const
Definition: dbwrapper.cpp:403
CDBWrapper(const CDBWrapper &)=delete
std::optional< std::string > ReadImpl(std::span< const std::byte > key) const
Definition: dbwrapper.cpp:332
size_t EstimateSizeImpl(std::span< const std::byte > key1, std::span< const std::byte > key2) const
Definition: dbwrapper.cpp:361
size_t DynamicMemoryUsage() const
Definition: dbwrapper.cpp:302
bool WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:285
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:220
CDBIterator * NewIterator()
Definition: dbwrapper.cpp:387
std::string m_name
the name of this database
Definition: dbwrapper.h:188
bool Erase(const K &key, bool fSync=false)
Definition: dbwrapper.h:265
bool Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:240
bool Exists(const K &key) const
Definition: dbwrapper.h:256
std::vector< unsigned char > obfuscate_key
a key used for optional XOR-obfuscation of the database
Definition: dbwrapper.h:191
CDBWrapper(const DBParams &params)
Definition: dbwrapper.cpp:215
static const unsigned int OBFUSCATE_KEY_NUM_BYTES
the length of the obfuscate key in number of bytes
Definition: dbwrapper.h:197
static const std::string OBFUSCATE_KEY_KEY
the key under which the obfuscation key is stored
Definition: dbwrapper.h:194
const fs::path m_path
path to filesystem storage
Definition: dbwrapper.h:202
bool ExistsImpl(std::span< const std::byte > key) const
Definition: dbwrapper.cpp:346
std::unique_ptr< LevelDBContext > m_db_context
holds all leveldb-specific fields of this class
Definition: dbwrapper.h:185
CDBWrapper & operator=(const CDBWrapper &)=delete
bool m_is_memory
whether or not the database resides in memory
Definition: dbwrapper.h:205
std::vector< unsigned char > CreateObfuscateKey() const
Returns a string (consisting of 8 random bytes) suitable for use as an obfuscating XOR key.
Definition: dbwrapper.cpp:325
auto & DBContext() const LIFETIMEBOUND
Definition: dbwrapper.h:210
bool IsEmpty()
Return true if the database managed by this class contains no entries.
Definition: dbwrapper.cpp:371
std::optional< fs::path > StoragePath()
Definition: dbwrapper.h:248
size_t EstimateSize(const K &key_begin, const K &key_end) const
Definition: dbwrapper.h:285
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:147
void reserve(size_type n)
Definition: streams.h:184
void clear()
Definition: streams.h:187
dbwrapper_error(const std::string &msg)
Definition: dbwrapper.h:53
static const size_t DBWRAPPER_PREALLOC_KEY_SIZE
Definition: dbwrapper.h:23
bool DestroyDB(const std::string &path_str)
Definition: dbwrapper.cpp:37
static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE
Definition: dbwrapper.h:24
static const size_t DBWRAPPER_MAX_FILE_SIZE
Definition: dbwrapper.h:25
These should be considered an implementation detail of the specific database.
Definition: dbwrapper.cpp:413
const std::vector< unsigned char > & GetObfuscateKey(const CDBWrapper &w)
Work around circular dependency, as well as for testing in dbwrapper_tests.
Definition: dbwrapper.cpp:415
auto MakeByteSpan(const V &v) noexcept
Definition: span.h:84
User-controlled performance and debug options.
Definition: dbwrapper.h:28
bool force_compact
Compact database on startup.
Definition: dbwrapper.h:30
Application-specific storage settings.
Definition: dbwrapper.h:34
DBOptions options
Passed-through options.
Definition: dbwrapper.h:47
bool obfuscate
If true, store data obfuscated via simple XOR.
Definition: dbwrapper.h:45
bool wipe_data
If true, remove all existing data.
Definition: dbwrapper.h:42
size_t cache_bytes
Configures various leveldb cache settings.
Definition: dbwrapper.h:38
fs::path path
Location in the filesystem where leveldb data will be stored.
Definition: dbwrapper.h:36
bool memory_only
If true, use leveldb's memory environment.
Definition: dbwrapper.h:40