Bitcoin ABC 0.34.2
P2P Digital Currency
dbwrapper.h
Go to the documentation of this file.
1// Copyright (c) 2012-2016 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 <common/system.h>
10#include <serialize.h>
11#include <span.h>
12#include <streams.h>
13#include <util/check.h>
14#include <util/fs.h>
15
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 {
51public:
52 explicit dbwrapper_error(const std::string &msg)
53 : std::runtime_error(msg) {}
54};
55
56class CDBWrapper;
57
61namespace dbwrapper_private {
62
68const std::vector<uint8_t> &GetObfuscateKey(const CDBWrapper &w);
69}; // namespace dbwrapper_private
70
71bool DestroyDB(const std::string &path_str);
72
74class CDBBatch {
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
88 void WriteImpl(Span<const std::byte> key, DataStream &ssValue_);
90
91public:
95 explicit CDBBatch(const CDBWrapper &_parent);
97 void Clear();
98
99 template <typename K, typename V> void Write(const K &key, const V &value) {
102 ssKey << key;
103 ssValue << value;
105 ssKey.clear();
106 ssValue.clear();
107 }
108
109 template <typename K> void Erase(const K &key) {
111 ssKey << key;
113 ssKey.clear();
114 }
115
116 size_t SizeEstimate() const { return size_estimate; }
117};
118
120public:
121 struct IteratorImpl;
122
123private:
125 const std::unique_ptr<IteratorImpl> m_impl_iter;
126
130
131public:
136 CDBIterator(const CDBWrapper &_parent,
137 std::unique_ptr<IteratorImpl> _piter);
139
140 bool Valid() const;
141
142 void SeekToFirst();
143
144 template <typename K> void Seek(const K &key) {
145 DataStream ssKey{};
147 ssKey << key;
148 SeekImpl(ssKey);
149 }
150
151 void Next();
152
153 template <typename K> bool GetKey(K &key) {
154 try {
155 DataStream ssKey{GetKeyImpl()};
156 ssKey >> key;
157 } catch (const std::exception &) {
158 return false;
159 }
160 return true;
161 }
162
163 template <typename V> bool GetValue(V &value) {
164 try {
165 DataStream ssValue{GetValueImpl()};
167 ssValue >> value;
168 } catch (const std::exception &) {
169 return false;
170 }
171 return true;
172 }
173};
174
175struct LevelDBContext;
176
178 friend const std::vector<uint8_t> &
180
181private:
183 std::unique_ptr<LevelDBContext> m_db_context;
184
186 std::string m_name;
187
189 std::vector<uint8_t> obfuscate_key;
190
192 static const std::string OBFUSCATE_KEY_KEY;
193
195 static const unsigned int OBFUSCATE_KEY_NUM_BYTES;
196
197 std::vector<uint8_t> CreateObfuscateKey() const;
198
201
204
205 std::optional<std::string> ReadImpl(Span<const std::byte> key) const;
206 bool ExistsImpl(Span<const std::byte> key) const;
208 Span<const std::byte> key2) const;
209 auto &DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); }
210
211public:
212 CDBWrapper(const DBParams &params);
213 ~CDBWrapper();
214
215 CDBWrapper(const CDBWrapper &) = delete;
216 CDBWrapper &operator=(const CDBWrapper &) = delete;
217
218 template <typename K, typename V> bool Read(const K &key, V &value) const {
219 DataStream ssKey{};
221 ssKey << key;
222 std::optional<std::string> strValue{ReadImpl(ssKey)};
223 if (!strValue) {
224 return false;
225 }
226 try {
227 DataStream ssValue{MakeByteSpan(*strValue)};
228 ssValue.Xor(obfuscate_key);
229 ssValue >> value;
230 } catch (const std::exception &) {
231 return false;
232 }
233 return true;
234 }
235
236 template <typename K, typename V>
237 void Write(const K &key, const V &value, bool fSync = false) {
238 CDBBatch batch(*this);
239 batch.Write(key, value);
240 WriteBatch(batch, fSync);
241 }
242
244 std::optional<fs::path> StoragePath() {
245 if (m_is_memory) {
246 return {};
247 }
248 return m_path;
249 }
250
251 template <typename K> bool Exists(const K &key) const {
252 DataStream ssKey{};
254 ssKey << key;
255 return ExistsImpl(ssKey);
256 }
257
258 template <typename K> void Erase(const K &key, bool fSync = false) {
259 CDBBatch batch(*this);
260 batch.Erase(key);
261 WriteBatch(batch, fSync);
262 }
263
264 void WriteBatch(CDBBatch &batch, bool fSync = false);
265
266 // Get an estimate of LevelDB memory usage (in bytes).
267 size_t DynamicMemoryUsage() const;
268
270
274 bool IsEmpty();
275
276 template <typename K>
277 size_t EstimateSize(const K &key_begin, const K &key_end) const {
278 DataStream ssKey1{}, ssKey2{};
280 ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
281 ssKey1 << key_begin;
282 ssKey2 << key_end;
283 return EstimateSizeImpl(ssKey1, ssKey2);
284 }
285};
286
287#endif // BITCOIN_DBWRAPPER_H
#define LIFETIMEBOUND
Definition: attributes.h:16
#define Assert(val)
Identity function.
Definition: check.h:87
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:74
void Erase(const K &key)
Definition: dbwrapper.h:109
size_t SizeEstimate() const
Definition: dbwrapper.h:116
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:99
DataStream ssValue
Definition: dbwrapper.h:84
void Clear()
Definition: dbwrapper.cpp:164
CDBBatch(const CDBWrapper &_parent)
Definition: dbwrapper.cpp:158
void WriteImpl(Span< const std::byte > key, DataStream &ssValue_)
Definition: dbwrapper.cpp:169
const CDBWrapper & parent
Definition: dbwrapper.h:78
void EraseImpl(Span< const std::byte > key)
Definition: dbwrapper.cpp:185
Span< const std::byte > GetKeyImpl() const
Definition: dbwrapper.cpp:416
CDBIterator(const CDBWrapper &_parent, std::unique_ptr< IteratorImpl > _piter)
Definition: dbwrapper.cpp:401
bool GetValue(V &value)
Definition: dbwrapper.h:163
const std::unique_ptr< IteratorImpl > m_impl_iter
Definition: dbwrapper.h:125
bool GetKey(K &key)
Definition: dbwrapper.h:153
void Seek(const K &key)
Definition: dbwrapper.h:144
const CDBWrapper & parent
Definition: dbwrapper.h:124
bool Valid() const
Definition: dbwrapper.cpp:425
void SeekToFirst()
Definition: dbwrapper.cpp:428
Span< const std::byte > GetValueImpl() const
Definition: dbwrapper.cpp:420
void Next()
Definition: dbwrapper.cpp:431
void SeekImpl(Span< const std::byte > key)
Definition: dbwrapper.cpp:411
CDBWrapper(const CDBWrapper &)=delete
size_t DynamicMemoryUsage() const
Definition: dbwrapper.cpp:316
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:218
std::vector< uint8_t > CreateObfuscateKey() const
Returns a string (consisting of 8 random bytes) suitable for use as an obfuscating XOR key.
Definition: dbwrapper.cpp:341
CDBIterator * NewIterator()
Definition: dbwrapper.cpp:405
std::string m_name
the name of this database
Definition: dbwrapper.h:186
bool Exists(const K &key) const
Definition: dbwrapper.h:251
std::vector< uint8_t > obfuscate_key
a key used for optional XOR-obfuscation of the database
Definition: dbwrapper.h:189
CDBWrapper(const DBParams &params)
Definition: dbwrapper.cpp:220
void Erase(const K &key, bool fSync=false)
Definition: dbwrapper.h:258
static const unsigned int OBFUSCATE_KEY_NUM_BYTES
the length of the obfuscate key in number of bytes
Definition: dbwrapper.h:195
static const std::string OBFUSCATE_KEY_KEY
the key under which the obfuscation key is stored
Definition: dbwrapper.h:192
void WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:296
const fs::path m_path
path to filesystem storage
Definition: dbwrapper.h:200
std::optional< std::string > ReadImpl(Span< const std::byte > key) const
Definition: dbwrapper.cpp:348
void Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:237
std::unique_ptr< LevelDBContext > m_db_context
holds all leveldb-specific fields of this class
Definition: dbwrapper.h:183
CDBWrapper & operator=(const CDBWrapper &)=delete
bool m_is_memory
whether or not the database resides in memory
Definition: dbwrapper.h:203
auto & DBContext() const LIFETIMEBOUND
Definition: dbwrapper.h:209
bool ExistsImpl(Span< const std::byte > key) const
Definition: dbwrapper.cpp:363
bool IsEmpty()
Return true if the database managed by this class contains no entries.
Definition: dbwrapper.cpp:389
size_t EstimateSizeImpl(Span< const std::byte > key1, Span< const std::byte > key2) const
Definition: dbwrapper.cpp:379
std::optional< fs::path > StoragePath()
Definition: dbwrapper.h:244
size_t EstimateSize(const K &key_begin, const K &key_end) const
Definition: dbwrapper.h:277
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:118
void reserve(size_type n)
Definition: streams.h:156
void clear()
Definition: streams.h:161
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:94
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:30
static const size_t DBWRAPPER_PREALLOC_KEY_SIZE
Definition: dbwrapper.h:23
bool DestroyDB(const std::string &path_str)
Definition: dbwrapper.cpp:34
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:435
const std::vector< uint8_t > & GetObfuscateKey(const CDBWrapper &w)
Work around circular dependency, as well as for testing in dbwrapper_tests.
Definition: dbwrapper.cpp:437
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:259
Span< const std::byte > MakeByteSpan(V &&v) noexcept
Definition: span.h:302
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