Dash Core  0.12.2.1
P2P Digital Currency
db.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #ifndef BITCOIN_WALLET_DB_H
7 #define BITCOIN_WALLET_DB_H
8 
9 #include "clientversion.h"
10 #include "serialize.h"
11 #include "streams.h"
12 #include "sync.h"
13 #include "version.h"
14 
15 #include <map>
16 #include <string>
17 #include <vector>
18 
19 #include <boost/filesystem/path.hpp>
20 
21 #include <db_cxx.h>
22 
23 static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100;
24 static const bool DEFAULT_WALLET_PRIVDB = true;
25 
26 extern unsigned int nWalletDBUpdated;
27 
28 class CDBEnv
29 {
30 private:
31  bool fDbEnvInit;
32  bool fMockDb;
33  // Don't change into boost::filesystem::path, as that can result in
34  // shutdown problems/crashes caused by a static initialized internal pointer.
35  std::string strPath;
36 
37  void EnvShutdown();
38 
39 public:
41  DbEnv *dbenv;
42  std::map<std::string, int> mapFileUseCount;
43  std::map<std::string, Db*> mapDb;
44 
45  CDBEnv();
46  ~CDBEnv();
47  void Reset();
48 
49  void MakeMock();
50  bool IsMock() { return fMockDb; }
51 
61  VerifyResult Verify(const std::string& strFile, bool (*recoverFunc)(CDBEnv& dbenv, const std::string& strFile));
69  typedef std::pair<std::vector<unsigned char>, std::vector<unsigned char> > KeyValPair;
70  bool Salvage(const std::string& strFile, bool fAggressive, std::vector<KeyValPair>& vResult);
71 
72  bool Open(const boost::filesystem::path& path);
73  void Close();
74  void Flush(bool fShutdown);
75  void CheckpointLSN(const std::string& strFile);
76 
77  void CloseDb(const std::string& strFile);
78  bool RemoveDb(const std::string& strFile);
79 
80  DbTxn* TxnBegin(int flags = DB_TXN_WRITE_NOSYNC)
81  {
82  DbTxn* ptxn = NULL;
83  int ret = dbenv->txn_begin(NULL, &ptxn, flags);
84  if (!ptxn || ret != 0)
85  return NULL;
86  return ptxn;
87  }
88 };
89 
90 extern CDBEnv bitdb;
91 
92 
94 class CDB
95 {
96 protected:
97  Db* pdb;
98  std::string strFile;
99  DbTxn* activeTxn;
100  bool fReadOnly;
102 
103  explicit CDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnCloseIn=true);
104  ~CDB() { Close(); }
105 
106 public:
107  void Flush();
108  void Close();
109 
110 private:
111  CDB(const CDB&);
112  void operator=(const CDB&);
113 
114 protected:
115  template <typename K, typename T>
116  bool Read(const K& key, T& value)
117  {
118  if (!pdb)
119  return false;
120 
121  // Key
123  ssKey.reserve(1000);
124  ssKey << key;
125  Dbt datKey(&ssKey[0], ssKey.size());
126 
127  // Read
128  Dbt datValue;
129  datValue.set_flags(DB_DBT_MALLOC);
130  int ret = pdb->get(activeTxn, &datKey, &datValue, 0);
131  memset(datKey.get_data(), 0, datKey.get_size());
132  if (datValue.get_data() == NULL)
133  return false;
134 
135  // Unserialize value
136  try {
137  CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION);
138  ssValue >> value;
139  } catch (const std::exception&) {
140  return false;
141  }
142 
143  // Clear and free memory
144  memset(datValue.get_data(), 0, datValue.get_size());
145  free(datValue.get_data());
146  return (ret == 0);
147  }
148 
149  template <typename K, typename T>
150  bool Write(const K& key, const T& value, bool fOverwrite = true)
151  {
152  if (!pdb)
153  return false;
154  if (fReadOnly)
155  assert(!"Write called on database in read-only mode");
156 
157  // Key
159  ssKey.reserve(1000);
160  ssKey << key;
161  Dbt datKey(&ssKey[0], ssKey.size());
162 
163  // Value
165  ssValue.reserve(10000);
166  ssValue << value;
167  Dbt datValue(&ssValue[0], ssValue.size());
168 
169  // Write
170  int ret = pdb->put(activeTxn, &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
171 
172  // Clear memory in case it was a private key
173  memset(datKey.get_data(), 0, datKey.get_size());
174  memset(datValue.get_data(), 0, datValue.get_size());
175  return (ret == 0);
176  }
177 
178  template <typename K>
179  bool Erase(const K& key)
180  {
181  if (!pdb)
182  return false;
183  if (fReadOnly)
184  assert(!"Erase called on database in read-only mode");
185 
186  // Key
188  ssKey.reserve(1000);
189  ssKey << key;
190  Dbt datKey(&ssKey[0], ssKey.size());
191 
192  // Erase
193  int ret = pdb->del(activeTxn, &datKey, 0);
194 
195  // Clear memory
196  memset(datKey.get_data(), 0, datKey.get_size());
197  return (ret == 0 || ret == DB_NOTFOUND);
198  }
199 
200  template <typename K>
201  bool Exists(const K& key)
202  {
203  if (!pdb)
204  return false;
205 
206  // Key
208  ssKey.reserve(1000);
209  ssKey << key;
210  Dbt datKey(&ssKey[0], ssKey.size());
211 
212  // Exists
213  int ret = pdb->exists(activeTxn, &datKey, 0);
214 
215  // Clear memory
216  memset(datKey.get_data(), 0, datKey.get_size());
217  return (ret == 0);
218  }
219 
220  Dbc* GetCursor()
221  {
222  if (!pdb)
223  return NULL;
224  Dbc* pcursor = NULL;
225  int ret = pdb->cursor(NULL, &pcursor, 0);
226  if (ret != 0)
227  return NULL;
228  return pcursor;
229  }
230 
231  int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags = DB_NEXT)
232  {
233  // Read at cursor
234  Dbt datKey;
235  if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) {
236  datKey.set_data(&ssKey[0]);
237  datKey.set_size(ssKey.size());
238  }
239  Dbt datValue;
240  if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) {
241  datValue.set_data(&ssValue[0]);
242  datValue.set_size(ssValue.size());
243  }
244  datKey.set_flags(DB_DBT_MALLOC);
245  datValue.set_flags(DB_DBT_MALLOC);
246  int ret = pcursor->get(&datKey, &datValue, fFlags);
247  if (ret != 0)
248  return ret;
249  else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
250  return 99999;
251 
252  // Convert to streams
253  ssKey.SetType(SER_DISK);
254  ssKey.clear();
255  ssKey.write((char*)datKey.get_data(), datKey.get_size());
256  ssValue.SetType(SER_DISK);
257  ssValue.clear();
258  ssValue.write((char*)datValue.get_data(), datValue.get_size());
259 
260  // Clear and free memory
261  memset(datKey.get_data(), 0, datKey.get_size());
262  memset(datValue.get_data(), 0, datValue.get_size());
263  free(datKey.get_data());
264  free(datValue.get_data());
265  return 0;
266  }
267 
268 public:
269  bool TxnBegin()
270  {
271  if (!pdb || activeTxn)
272  return false;
273  DbTxn* ptxn = bitdb.TxnBegin();
274  if (!ptxn)
275  return false;
276  activeTxn = ptxn;
277  return true;
278  }
279 
280  bool TxnCommit()
281  {
282  if (!pdb || !activeTxn)
283  return false;
284  int ret = activeTxn->commit(0);
285  activeTxn = NULL;
286  return (ret == 0);
287  }
288 
289  bool TxnAbort()
290  {
291  if (!pdb || !activeTxn)
292  return false;
293  int ret = activeTxn->abort();
294  activeTxn = NULL;
295  return (ret == 0);
296  }
297 
298  bool ReadVersion(int& nVersion)
299  {
300  nVersion = 0;
301  return Read(std::string("version"), nVersion);
302  }
303 
304  bool WriteVersion(int nVersion)
305  {
306  return Write(std::string("version"), nVersion);
307  }
308 
309  bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
310 };
311 
312 #endif // BITCOIN_WALLET_DB_H
VerifyResult Verify(const std::string &strFile, bool(*recoverFunc)(CDBEnv &dbenv, const std::string &strFile))
Definition: db.cpp:151
~CDB()
Definition: db.h:104
Dbc * GetCursor()
Definition: db.h:220
bool RemoveDb(const std::string &strFile)
Definition: db.cpp:331
std::map< std::string, Db * > mapDb
Definition: db.h:43
void operator=(const CDB &)
std::string strFile
Definition: db.h:98
void EnvShutdown()
Definition: db.cpp:36
CDB(const std::string &strFilename, const char *pszMode="r+", bool fFlushOnCloseIn=true)
Definition: db.cpp:227
DbEnv * dbenv
Definition: db.h:41
bool IsMock()
Definition: db.h:50
void Close()
Definition: db.cpp:69
std::pair< std::vector< unsigned char >, std::vector< unsigned char > > KeyValPair
Definition: db.h:69
CDBEnv bitdb
Definition: db.cpp:34
int flags
Definition: dash-tx.cpp:326
bool Exists(const K &key)
Definition: db.h:201
unsigned int nWalletDBUpdated
Definition: db.cpp:27
bool Read(const K &key, T &value)
Definition: db.h:116
CDBEnv()
Definition: db.cpp:57
bool fMockDb
Definition: db.h:32
CDataStream & write(const char *pch, size_t nSize)
Definition: streams.h:264
Definition: db.h:28
Definition: db.h:94
void reserve(size_type n)
Definition: streams.h:125
bool fDbEnvInit
Definition: db.h:31
static bool Rewrite(const std::string &strFile, const char *pszSkip=NULL)
Definition: db.cpp:340
std::map< std::string, int > mapFileUseCount
Definition: db.h:42
bool Erase(const K &key)
Definition: db.h:179
void clear()
Definition: streams.h:128
bool Write(const K &key, const T &value, bool fOverwrite=true)
Definition: db.h:150
bool Open(const boost::filesystem::path &path)
Definition: db.cpp:74
void Close()
Definition: db.cpp:299
DbTxn * TxnBegin(int flags=DB_TXN_WRITE_NOSYNC)
Definition: db.h:80
int ReadAtCursor(Dbc *pcursor, CDataStream &ssKey, CDataStream &ssValue, unsigned int fFlags=DB_NEXT)
Definition: db.h:231
void Reset()
Definition: db.cpp:49
static const unsigned int DEFAULT_WALLET_DBLOGSIZE
Definition: db.h:23
bool TxnAbort()
Definition: db.h:289
bool TxnCommit()
Definition: db.h:280
DbTxn * activeTxn
Definition: db.h:99
void Flush(bool fShutdown)
Definition: db.cpp:424
void CheckpointLSN(const std::string &strFile)
Definition: db.cpp:218
bool fFlushOnClose
Definition: db.h:101
bool Salvage(const std::string &strFile, bool fAggressive, std::vector< KeyValPair > &vResult)
Definition: db.cpp:168
bool WriteVersion(int nVersion)
Definition: db.h:304
void Flush()
Definition: db.cpp:286
void SetType(int n)
Definition: streams.h:220
static const bool DEFAULT_WALLET_PRIVDB
Definition: db.h:24
bool ReadVersion(int &nVersion)
Definition: db.h:298
void CloseDb(const std::string &strFile)
Definition: db.cpp:317
VerifyResult
Definition: db.h:58
~CDBEnv()
Definition: db.cpp:62
size_type size() const
Definition: streams.h:122
Db * pdb
Definition: db.h:97
void MakeMock()
Definition: db.cpp:119
static const int CLIENT_VERSION
Definition: clientversion.h:54
bool fReadOnly
Definition: db.h:100
bool TxnBegin()
Definition: db.h:269
CCriticalSection cs_db
Definition: db.h:40
std::string strPath
Definition: db.h:35