Dash Core  0.12.2.1
P2P Digital Currency
dbwrapper.h
Go to the documentation of this file.
1 // Copyright (c) 2012-2015 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 "clientversion.h"
9 #include "serialize.h"
10 #include "streams.h"
11 #include "util.h"
12 #include "utilstrencodings.h"
13 #include "version.h"
14 
15 #include <boost/filesystem/path.hpp>
16 
17 #include <leveldb/db.h>
18 #include <leveldb/write_batch.h>
19 
20 class dbwrapper_error : public std::runtime_error
21 {
22 public:
23  dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {}
24 };
25 
26 void HandleError(const leveldb::Status& status) throw(dbwrapper_error);
27 
29 class CDBBatch
30 {
31  friend class CDBWrapper;
32 
33 private:
34  leveldb::WriteBatch batch;
35  const std::vector<unsigned char> *obfuscate_key;
36 
37 public:
41  CDBBatch(const std::vector<unsigned char> *obfuscate_key) : obfuscate_key(obfuscate_key) { };
42 
43  template <typename K, typename V>
44  void Write(const K& key, const V& value)
45  {
47  ssKey.reserve(ssKey.GetSerializeSize(key));
48  ssKey << key;
49  leveldb::Slice slKey(&ssKey[0], ssKey.size());
50 
52  ssValue.reserve(ssValue.GetSerializeSize(value));
53  ssValue << value;
54  ssValue.Xor(*obfuscate_key);
55  leveldb::Slice slValue(&ssValue[0], ssValue.size());
56 
57  batch.Put(slKey, slValue);
58  }
59 
60  template <typename K>
61  void Erase(const K& key)
62  {
64  ssKey.reserve(ssKey.GetSerializeSize(key));
65  ssKey << key;
66  leveldb::Slice slKey(&ssKey[0], ssKey.size());
67 
68  batch.Delete(slKey);
69  }
70 };
71 
73 {
74 private:
75  leveldb::Iterator *piter;
76  const std::vector<unsigned char> *obfuscate_key;
77 
78 public:
79 
84  CDBIterator(leveldb::Iterator *piterIn, const std::vector<unsigned char>* obfuscate_key) :
85  piter(piterIn), obfuscate_key(obfuscate_key) { };
86  ~CDBIterator();
87 
88  bool Valid();
89 
90  void SeekToFirst();
91 
92  template<typename K> void Seek(const K& key) {
94  ssKey.reserve(ssKey.GetSerializeSize(key));
95  ssKey << key;
96  leveldb::Slice slKey(&ssKey[0], ssKey.size());
97  piter->Seek(slKey);
98  }
99 
100  void Next();
101 
102  template<typename K> bool GetKey(K& key) {
103  leveldb::Slice slKey = piter->key();
104  try {
105  CDataStream ssKey(slKey.data(), slKey.data() + slKey.size(), SER_DISK, CLIENT_VERSION);
106  ssKey >> key;
107  } catch (const std::exception&) {
108  return false;
109  }
110  return true;
111  }
112 
113  unsigned int GetKeySize() {
114  return piter->key().size();
115  }
116 
117  template<typename V> bool GetValue(V& value) {
118  leveldb::Slice slValue = piter->value();
119  try {
120  CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION);
121  ssValue.Xor(*obfuscate_key);
122  ssValue >> value;
123  } catch (const std::exception&) {
124  return false;
125  }
126  return true;
127  }
128 
129  unsigned int GetValueSize() {
130  return piter->value().size();
131  }
132 
133 };
134 
136 {
137 private:
139  leveldb::Env* penv;
140 
142  leveldb::Options options;
143 
145  leveldb::ReadOptions readoptions;
146 
148  leveldb::ReadOptions iteroptions;
149 
151  leveldb::WriteOptions writeoptions;
152 
154  leveldb::WriteOptions syncoptions;
155 
157  leveldb::DB* pdb;
158 
160  std::vector<unsigned char> obfuscate_key;
161 
163  static const std::string OBFUSCATE_KEY_KEY;
164 
166  static const unsigned int OBFUSCATE_KEY_NUM_BYTES;
167 
168  std::vector<unsigned char> CreateObfuscateKey() const;
169 
170 public:
179  CDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false, bool obfuscate = false);
180  ~CDBWrapper();
181 
182  template <typename K, typename V>
183  bool Read(const K& key, V& value) const throw(dbwrapper_error)
184  {
186  ssKey.reserve(ssKey.GetSerializeSize(key));
187  ssKey << key;
188  leveldb::Slice slKey(&ssKey[0], ssKey.size());
189 
190  std::string strValue;
191  leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
192  if (!status.ok()) {
193  if (status.IsNotFound())
194  return false;
195  LogPrintf("LevelDB read failure: %s\n", status.ToString());
196  HandleError(status);
197  }
198  try {
199  CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION);
200  ssValue.Xor(obfuscate_key);
201  ssValue >> value;
202  } catch (const std::exception&) {
203  return false;
204  }
205  return true;
206  }
207 
208  template <typename K, typename V>
209  bool Write(const K& key, const V& value, bool fSync = false) throw(dbwrapper_error)
210  {
211  CDBBatch batch(&obfuscate_key);
212  batch.Write(key, value);
213  return WriteBatch(batch, fSync);
214  }
215 
216  template <typename K>
217  bool Exists(const K& key) const throw(dbwrapper_error)
218  {
220  ssKey.reserve(ssKey.GetSerializeSize(key));
221  ssKey << key;
222  leveldb::Slice slKey(&ssKey[0], ssKey.size());
223 
224  std::string strValue;
225  leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
226  if (!status.ok()) {
227  if (status.IsNotFound())
228  return false;
229  LogPrintf("LevelDB read failure: %s\n", status.ToString());
230  HandleError(status);
231  }
232  return true;
233  }
234 
235  template <typename K>
236  bool Erase(const K& key, bool fSync = false) throw(dbwrapper_error)
237  {
238  CDBBatch batch(&obfuscate_key);
239  batch.Erase(key);
240  return WriteBatch(batch, fSync);
241  }
242 
243  bool WriteBatch(CDBBatch& batch, bool fSync = false) throw(dbwrapper_error);
244 
245  // not available for LevelDB; provide for compatibility with BDB
246  bool Flush()
247  {
248  return true;
249  }
250 
251  bool Sync() throw(dbwrapper_error)
252  {
253  CDBBatch batch(&obfuscate_key);
254  return WriteBatch(batch, true);
255  }
256 
258  {
259  return new CDBIterator(pdb->NewIterator(iteroptions), &obfuscate_key);
260  }
261 
265  bool IsEmpty();
266 
270  const std::vector<unsigned char>& GetObfuscateKey() const;
271 
275  std::string GetObfuscateKeyHex() const;
276 
277 };
278 
279 #endif // BITCOIN_DBWRAPPER_H
280 
dbwrapper_error(const std::string &msg)
Definition: dbwrapper.h:23
leveldb::Env * penv
custom environment this database is using (may be NULL in case of default environment) ...
Definition: dbwrapper.h:139
static const unsigned int OBFUSCATE_KEY_NUM_BYTES
the length of the obfuscate key in number of bytes
Definition: dbwrapper.h:166
CDBIterator(leveldb::Iterator *piterIn, const std::vector< unsigned char > *obfuscate_key)
Definition: dbwrapper.h:84
bool Valid()
Definition: dbwrapper.cpp:150
void Next()
Definition: dbwrapper.cpp:152
void HandleError(const leveldb::Status &status)
Definition: dbwrapper.cpp:18
CDBBatch(const std::vector< unsigned char > *obfuscate_key)
Definition: dbwrapper.h:41
const std::vector< unsigned char > * obfuscate_key
Definition: dbwrapper.h:35
static const std::string OBFUSCATE_KEY_KEY
the key under which the obfuscation key is stored
Definition: dbwrapper.h:163
leveldb::WriteBatch batch
Definition: dbwrapper.h:34
void Xor(const std::vector< unsigned char > &key)
Definition: streams.h:312
const std::vector< unsigned char > * obfuscate_key
Definition: dbwrapper.h:76
bool GetKey(K &key)
Definition: dbwrapper.h:102
leveldb::DB * pdb
the database itself
Definition: dbwrapper.h:157
bool Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:209
unsigned int GetSerializeSize(const T &obj)
Definition: streams.h:280
void reserve(size_type n)
Definition: streams.h:125
void Erase(const K &key)
Definition: dbwrapper.h:61
leveldb::Options options
database options used
Definition: dbwrapper.h:142
#define LogPrintf(...)
Definition: util.h:98
std::string GetObfuscateKeyHex() const
Definition: dbwrapper.cpp:144
CDBWrapper(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory=false, bool fWipe=false, bool obfuscate=false)
Definition: dbwrapper.cpp:48
bool Flush()
Definition: dbwrapper.h:246
bool WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:105
void Write(const K &key, const V &value)
Definition: dbwrapper.h:44
leveldb::WriteOptions syncoptions
options used when sync writing to the database
Definition: dbwrapper.h:154
leveldb::WriteOptions writeoptions
options used when writing to the database
Definition: dbwrapper.h:151
leveldb::ReadOptions readoptions
options used when reading from the database
Definition: dbwrapper.h:145
unsigned int GetValueSize()
Definition: dbwrapper.h:129
leveldb::ReadOptions iteroptions
options used when iterating over values of the database
Definition: dbwrapper.h:148
bool Exists(const K &key) const
Definition: dbwrapper.h:217
CDBIterator * NewIterator()
Definition: dbwrapper.h:257
void Seek(const K &key)
Definition: dbwrapper.h:92
bool Erase(const K &key, bool fSync=false)
Definition: dbwrapper.h:236
bool Sync()
Definition: dbwrapper.h:251
const std::vector< unsigned char > & GetObfuscateKey() const
Definition: dbwrapper.cpp:139
bool GetValue(V &value)
Definition: dbwrapper.h:117
bool IsEmpty()
Definition: dbwrapper.cpp:132
std::vector< unsigned char > CreateObfuscateKey() const
Definition: dbwrapper.cpp:124
size_type size() const
Definition: streams.h:122
static const int CLIENT_VERSION
Definition: clientversion.h:54
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:183
void SeekToFirst()
Definition: dbwrapper.cpp:151
unsigned int GetKeySize()
Definition: dbwrapper.h:113
leveldb::Iterator * piter
Definition: dbwrapper.h:75
std::vector< unsigned char > obfuscate_key
a key used for optional XOR-obfuscation of the database
Definition: dbwrapper.h:160