Bitcoin Core 28.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
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;
25
27struct DBOptions {
29 bool force_compact = false;
30};
31
33struct DBParams {
39 bool memory_only = false;
41 bool wipe_data = false;
44 bool obfuscate = false;
47};
48
49class dbwrapper_error : public std::runtime_error
50{
51public:
52 explicit dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {}
53};
54
55class CDBWrapper;
56
59namespace dbwrapper_private {
60
65const std::vector<unsigned char>& GetObfuscateKey(const CDBWrapper &w);
66
67}; // namespace dbwrapper_private
68
69bool DestroyDB(const std::string& path_str);
70
73{
74 friend class CDBWrapper;
75
76private:
78
79 struct WriteBatchImpl;
80 const std::unique_ptr<WriteBatchImpl> m_impl_batch;
81
84
85 size_t size_estimate{0};
86
89
90public:
94 explicit CDBBatch(const CDBWrapper& _parent);
96 void Clear();
97
98 template <typename K, typename V>
99 void Write(const K& key, const V& value)
100 {
103 ssKey << key;
104 ssValue << value;
106 ssKey.clear();
107 ssValue.clear();
108 }
109
110 template <typename K>
111 void Erase(const K& key)
112 {
114 ssKey << key;
116 ssKey.clear();
117 }
118
119 size_t SizeEstimate() const { return size_estimate; }
120};
121
123{
124public:
125 struct IteratorImpl;
126
127private:
129 const std::unique_ptr<IteratorImpl> m_impl_iter;
130
134
135public:
136
141 CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter);
143
144 bool Valid() const;
145
146 void SeekToFirst();
147
148 template<typename K> void Seek(const K& key) {
149 DataStream ssKey{};
151 ssKey << key;
152 SeekImpl(ssKey);
153 }
154
155 void Next();
156
157 template<typename K> bool GetKey(K& key) {
158 try {
159 DataStream ssKey{GetKeyImpl()};
160 ssKey >> key;
161 } catch (const std::exception&) {
162 return false;
163 }
164 return true;
165 }
166
167 template<typename V> bool GetValue(V& value) {
168 try {
169 DataStream ssValue{GetValueImpl()};
171 ssValue >> value;
172 } catch (const std::exception&) {
173 return false;
174 }
175 return true;
176 }
177};
178
179struct LevelDBContext;
180
182{
183 friend const std::vector<unsigned char>& dbwrapper_private::GetObfuscateKey(const CDBWrapper &w);
184private:
186 std::unique_ptr<LevelDBContext> m_db_context;
187
189 std::string m_name;
190
192 std::vector<unsigned char> obfuscate_key;
193
195 static const std::string OBFUSCATE_KEY_KEY;
196
198 static const unsigned int OBFUSCATE_KEY_NUM_BYTES;
199
200 std::vector<unsigned char> CreateObfuscateKey() const;
201
204
207
208 std::optional<std::string> ReadImpl(Span<const std::byte> key) const;
209 bool ExistsImpl(Span<const std::byte> key) const;
211 auto& DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); }
212
213public:
214 CDBWrapper(const DBParams& params);
215 ~CDBWrapper();
216
217 CDBWrapper(const CDBWrapper&) = delete;
218 CDBWrapper& operator=(const CDBWrapper&) = delete;
219
220 template <typename K, typename V>
221 bool Read(const K& key, V& value) const
222 {
223 DataStream ssKey{};
225 ssKey << key;
226 std::optional<std::string> strValue{ReadImpl(ssKey)};
227 if (!strValue) {
228 return false;
229 }
230 try {
231 DataStream ssValue{MakeByteSpan(*strValue)};
232 ssValue.Xor(obfuscate_key);
233 ssValue >> value;
234 } catch (const std::exception&) {
235 return false;
236 }
237 return true;
238 }
239
240 template <typename K, typename V>
241 bool Write(const K& key, const V& value, bool fSync = false)
242 {
243 CDBBatch batch(*this);
244 batch.Write(key, value);
245 return WriteBatch(batch, fSync);
246 }
247
249 std::optional<fs::path> StoragePath() {
250 if (m_is_memory) {
251 return {};
252 }
253 return m_path;
254 }
255
256 template <typename K>
257 bool Exists(const K& key) const
258 {
259 DataStream ssKey{};
261 ssKey << key;
262 return ExistsImpl(ssKey);
263 }
264
265 template <typename K>
266 bool Erase(const K& key, bool fSync = false)
267 {
268 CDBBatch batch(*this);
269 batch.Erase(key);
270 return WriteBatch(batch, fSync);
271 }
272
273 bool WriteBatch(CDBBatch& batch, bool fSync = false);
274
275 // Get an estimate of LevelDB memory usage (in bytes).
276 size_t DynamicMemoryUsage() const;
277
279
283 bool IsEmpty();
284
285 template<typename K>
286 size_t EstimateSize(const K& key_begin, const K& key_end) const
287 {
288 DataStream ssKey1{}, ssKey2{};
290 ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
291 ssKey1 << key_begin;
292 ssKey2 << key_end;
293 return EstimateSizeImpl(ssKey1, ssKey2);
294 }
295};
296
297#endif // BITCOIN_DBWRAPPER_H
#define LIFETIMEBOUND
Definition attributes.h:16
#define Assert(val)
Identity function.
Definition check.h:77
Batch of changes queued to be written to a CDBWrapper.
Definition dbwrapper.h:73
void Erase(const K &key)
Definition dbwrapper.h:111
size_t SizeEstimate() const
Definition dbwrapper.h:119
const std::unique_ptr< WriteBatchImpl > m_impl_batch
Definition dbwrapper.h:80
DataStream ssKey
Definition dbwrapper.h:82
size_t size_estimate
Definition dbwrapper.h:85
void Write(const K &key, const V &value)
Definition dbwrapper.h:99
DataStream ssValue
Definition dbwrapper.h:83
void Clear()
CDBBatch(const CDBWrapper &_parent)
void WriteImpl(Span< const std::byte > key, DataStream &ssValue)
const CDBWrapper & parent
Definition dbwrapper.h:77
void EraseImpl(Span< const std::byte > key)
Span< const std::byte > GetKeyImpl() const
CDBIterator(const CDBWrapper &_parent, std::unique_ptr< IteratorImpl > _piter)
bool GetValue(V &value)
Definition dbwrapper.h:167
const std::unique_ptr< IteratorImpl > m_impl_iter
Definition dbwrapper.h:129
bool GetKey(K &key)
Definition dbwrapper.h:157
void Seek(const K &key)
Definition dbwrapper.h:148
const CDBWrapper & parent
Definition dbwrapper.h:128
bool Valid() const
void SeekToFirst()
Span< const std::byte > GetValueImpl() const
void SeekImpl(Span< const std::byte > key)
CDBWrapper(const CDBWrapper &)=delete
size_t DynamicMemoryUsage() const
bool WriteBatch(CDBBatch &batch, bool fSync=false)
bool Read(const K &key, V &value) const
Definition dbwrapper.h:221
CDBIterator * NewIterator()
std::string m_name
the name of this database
Definition dbwrapper.h:189
bool Erase(const K &key, bool fSync=false)
Definition dbwrapper.h:266
bool Write(const K &key, const V &value, bool fSync=false)
Definition dbwrapper.h:241
bool Exists(const K &key) const
Definition dbwrapper.h:257
std::vector< unsigned char > obfuscate_key
a key used for optional XOR-obfuscation of the database
Definition dbwrapper.h:192
CDBWrapper(const DBParams &params)
static const unsigned int OBFUSCATE_KEY_NUM_BYTES
the length of the obfuscate key in number of bytes
Definition dbwrapper.h:198
static const std::string OBFUSCATE_KEY_KEY
the key under which the obfuscation key is stored
Definition dbwrapper.h:195
const fs::path m_path
path to filesystem storage
Definition dbwrapper.h:203
std::optional< std::string > ReadImpl(Span< const std::byte > key) const
std::unique_ptr< LevelDBContext > m_db_context
holds all leveldb-specific fields of this class
Definition dbwrapper.h:186
CDBWrapper & operator=(const CDBWrapper &)=delete
bool m_is_memory
whether or not the database resides in memory
Definition dbwrapper.h:206
std::vector< unsigned char > CreateObfuscateKey() const
Returns a string (consisting of 8 random bytes) suitable for use as an obfuscating XOR key.
auto & DBContext() const LIFETIMEBOUND
Definition dbwrapper.h:211
bool ExistsImpl(Span< const std::byte > key) const
bool IsEmpty()
Return true if the database managed by this class contains no entries.
size_t EstimateSizeImpl(Span< const std::byte > key1, Span< const std::byte > key2) const
std::optional< fs::path > StoragePath()
Definition dbwrapper.h:249
size_t EstimateSize(const K &key_begin, const K &key_end) const
Definition dbwrapper.h:286
Double ended buffer combining vector and stream-like interfaces.
Definition streams.h:147
void Xor(const std::vector< unsigned char > &key)
XOR the contents of this stream with a certain key.
Definition streams.h:276
void reserve(size_type n)
Definition streams.h:184
void clear()
Definition streams.h:187
A Span is an object that can refer to a contiguous sequence of objects.
Definition span.h:98
dbwrapper_error(const std::string &msg)
Definition dbwrapper.h:52
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
These should be considered an implementation detail of the specific database.
const std::vector< unsigned char > & GetObfuscateKey(const CDBWrapper &w)
Work around circular dependency, as well as for testing in dbwrapper_tests.
Span< const std::byte > MakeByteSpan(V &&v) noexcept
Definition span.h:277
User-controlled performance and debug options.
Definition dbwrapper.h:27
bool force_compact
Compact database on startup.
Definition dbwrapper.h:29
Application-specific storage settings.
Definition dbwrapper.h:33
DBOptions options
Passed-through options.
Definition dbwrapper.h:46
bool obfuscate
If true, store data obfuscated via simple XOR.
Definition dbwrapper.h:44
bool wipe_data
If true, remove all existing data.
Definition dbwrapper.h:41
size_t cache_bytes
Configures various leveldb cache settings.
Definition dbwrapper.h:37
fs::path path
Location in the filesystem where leveldb data will be stored.
Definition dbwrapper.h:35
bool memory_only
If true, use leveldb's memory environment.
Definition dbwrapper.h:39