Bitcoin Core 28.99.0
P2P Digital Currency
dbwrapper.h
Go to the documentation of this file.
1// Copyright (c) 2012-2022 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 {
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 size_t size_estimate{0};
87
90
91public:
95 explicit CDBBatch(const CDBWrapper& _parent);
97 void Clear();
98
99 template <typename K, typename V>
100 void Write(const K& key, const V& value)
101 {
104 ssKey << key;
105 ssValue << value;
107 ssKey.clear();
108 ssValue.clear();
109 }
110
111 template <typename K>
112 void Erase(const K& key)
113 {
115 ssKey << key;
117 ssKey.clear();
118 }
119
120 size_t SizeEstimate() const { return size_estimate; }
121};
122
124{
125public:
126 struct IteratorImpl;
127
128private:
130 const std::unique_ptr<IteratorImpl> m_impl_iter;
131
135
136public:
137
142 CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter);
144
145 bool Valid() const;
146
147 void SeekToFirst();
148
149 template<typename K> void Seek(const K& key) {
150 DataStream ssKey{};
152 ssKey << key;
153 SeekImpl(ssKey);
154 }
155
156 void Next();
157
158 template<typename K> bool GetKey(K& key) {
159 try {
160 DataStream ssKey{GetKeyImpl()};
161 ssKey >> key;
162 } catch (const std::exception&) {
163 return false;
164 }
165 return true;
166 }
167
168 template<typename V> bool GetValue(V& value) {
169 try {
170 DataStream ssValue{GetValueImpl()};
172 ssValue >> value;
173 } catch (const std::exception&) {
174 return false;
175 }
176 return true;
177 }
178};
179
180struct LevelDBContext;
181
183{
184 friend const std::vector<unsigned char>& dbwrapper_private::GetObfuscateKey(const CDBWrapper &w);
185private:
187 std::unique_ptr<LevelDBContext> m_db_context;
188
190 std::string m_name;
191
193 std::vector<unsigned char> obfuscate_key;
194
196 static const std::string OBFUSCATE_KEY_KEY;
197
199 static const unsigned int OBFUSCATE_KEY_NUM_BYTES;
200
201 std::vector<unsigned char> CreateObfuscateKey() const;
202
205
208
209 std::optional<std::string> ReadImpl(Span<const std::byte> key) const;
210 bool ExistsImpl(Span<const std::byte> key) const;
212 auto& DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); }
213
214public:
215 CDBWrapper(const DBParams& params);
216 ~CDBWrapper();
217
218 CDBWrapper(const CDBWrapper&) = delete;
219 CDBWrapper& operator=(const CDBWrapper&) = delete;
220
221 template <typename K, typename V>
222 bool Read(const K& key, V& value) const
223 {
224 DataStream ssKey{};
226 ssKey << key;
227 std::optional<std::string> strValue{ReadImpl(ssKey)};
228 if (!strValue) {
229 return false;
230 }
231 try {
232 DataStream ssValue{MakeByteSpan(*strValue)};
233 ssValue.Xor(obfuscate_key);
234 ssValue >> value;
235 } catch (const std::exception&) {
236 return false;
237 }
238 return true;
239 }
240
241 template <typename K, typename V>
242 bool Write(const K& key, const V& value, bool fSync = false)
243 {
244 CDBBatch batch(*this);
245 batch.Write(key, value);
246 return WriteBatch(batch, fSync);
247 }
248
250 std::optional<fs::path> StoragePath() {
251 if (m_is_memory) {
252 return {};
253 }
254 return m_path;
255 }
256
257 template <typename K>
258 bool Exists(const K& key) const
259 {
260 DataStream ssKey{};
262 ssKey << key;
263 return ExistsImpl(ssKey);
264 }
265
266 template <typename K>
267 bool Erase(const K& key, bool fSync = false)
268 {
269 CDBBatch batch(*this);
270 batch.Erase(key);
271 return WriteBatch(batch, fSync);
272 }
273
274 bool WriteBatch(CDBBatch& batch, bool fSync = false);
275
276 // Get an estimate of LevelDB memory usage (in bytes).
277 size_t DynamicMemoryUsage() const;
278
280
284 bool IsEmpty();
285
286 template<typename K>
287 size_t EstimateSize(const K& key_begin, const K& key_end) const
288 {
289 DataStream ssKey1{}, ssKey2{};
291 ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
292 ssKey1 << key_begin;
293 ssKey2 << key_end;
294 return EstimateSizeImpl(ssKey1, ssKey2);
295 }
296};
297
298#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:112
size_t SizeEstimate() const
Definition: dbwrapper.h:120
const std::unique_ptr< WriteBatchImpl > m_impl_batch
Definition: dbwrapper.h:81
DataStream ssKey
Definition: dbwrapper.h:83
size_t size_estimate
Definition: dbwrapper.h:86
void Write(const K &key, const V &value)
Definition: dbwrapper.h:100
DataStream ssValue
Definition: dbwrapper.h:84
void Clear()
Definition: dbwrapper.cpp:165
CDBBatch(const CDBWrapper &_parent)
Definition: dbwrapper.cpp:159
void WriteImpl(Span< const std::byte > key, DataStream &ssValue)
Definition: dbwrapper.cpp:171
const CDBWrapper & parent
Definition: dbwrapper.h:78
void EraseImpl(Span< const std::byte > key)
Definition: dbwrapper.cpp:187
Span< const std::byte > GetKeyImpl() const
Definition: dbwrapper.cpp:405
CDBIterator(const CDBWrapper &_parent, std::unique_ptr< IteratorImpl > _piter)
Definition: dbwrapper.cpp:391
bool GetValue(V &value)
Definition: dbwrapper.h:168
const std::unique_ptr< IteratorImpl > m_impl_iter
Definition: dbwrapper.h:130
bool GetKey(K &key)
Definition: dbwrapper.h:158
void Seek(const K &key)
Definition: dbwrapper.h:149
const CDBWrapper & parent
Definition: dbwrapper.h:129
bool Valid() const
Definition: dbwrapper.cpp:416
void SeekToFirst()
Definition: dbwrapper.cpp:417
Span< const std::byte > GetValueImpl() const
Definition: dbwrapper.cpp:410
void Next()
Definition: dbwrapper.cpp:418
void SeekImpl(Span< const std::byte > key)
Definition: dbwrapper.cpp:399
CDBWrapper(const CDBWrapper &)=delete
size_t DynamicMemoryUsage() const
Definition: dbwrapper.cpp:309
bool WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:292
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:222
CDBIterator * NewIterator()
Definition: dbwrapper.cpp:394
std::string m_name
the name of this database
Definition: dbwrapper.h:190
bool Erase(const K &key, bool fSync=false)
Definition: dbwrapper.h:267
bool Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:242
bool Exists(const K &key) const
Definition: dbwrapper.h:258
std::vector< unsigned char > obfuscate_key
a key used for optional XOR-obfuscation of the database
Definition: dbwrapper.h:193
CDBWrapper(const DBParams &params)
Definition: dbwrapper.cpp:222
static const unsigned int OBFUSCATE_KEY_NUM_BYTES
the length of the obfuscate key in number of bytes
Definition: dbwrapper.h:199
static const std::string OBFUSCATE_KEY_KEY
the key under which the obfuscation key is stored
Definition: dbwrapper.h:196
const fs::path m_path
path to filesystem storage
Definition: dbwrapper.h:204
std::optional< std::string > ReadImpl(Span< const std::byte > key) const
Definition: dbwrapper.cpp:339
std::unique_ptr< LevelDBContext > m_db_context
holds all leveldb-specific fields of this class
Definition: dbwrapper.h:187
CDBWrapper & operator=(const CDBWrapper &)=delete
bool m_is_memory
whether or not the database resides in memory
Definition: dbwrapper.h:207
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:332
auto & DBContext() const LIFETIMEBOUND
Definition: dbwrapper.h:212
bool ExistsImpl(Span< const std::byte > key) const
Definition: dbwrapper.cpp:353
bool IsEmpty()
Return true if the database managed by this class contains no entries.
Definition: dbwrapper.cpp:378
size_t EstimateSizeImpl(Span< const std::byte > key1, Span< const std::byte > key2) const
Definition: dbwrapper.cpp:368
std::optional< fs::path > StoragePath()
Definition: dbwrapper.h:250
size_t EstimateSize(const K &key_begin, const K &key_end) const
Definition: dbwrapper.h:287
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
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:33
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:420
const std::vector< unsigned char > & GetObfuscateKey(const CDBWrapper &w)
Work around circular dependency, as well as for testing in dbwrapper_tests.
Definition: dbwrapper.cpp:422
Span< const std::byte > MakeByteSpan(V &&v) noexcept
Definition: span.h:270
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