Feathercoin  0.5.0
P2P Digital Currency
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
db.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #ifndef BITCOIN_DB_H
6 #define BITCOIN_DB_H
7 
8 #include "main.h"
9 
10 #include <map>
11 #include <string>
12 #include <vector>
13 
14 #include <db_cxx.h>
15 
16 class CAddress;
17 class CAddrMan;
18 class CBlockLocator;
19 class CDiskBlockIndex;
20 class CMasterKey;
21 class COutPoint;
22 class CWallet;
23 class CWalletTx;
24 
25 extern unsigned int nWalletDBUpdated;
26 
27 void ThreadFlushWalletDB(const std::string& strWalletFile);
28 bool BackupWallet(const CWallet& wallet, const std::string& strDest);
29 
30 
31 class CDBEnv
32 {
33 private:
34  bool fDbEnvInit;
35  bool fMockDb;
36  boost::filesystem::path path;
37 
38  void EnvShutdown();
39 
40 public:
42  DbEnv dbenv;
43  std::map<std::string, int> mapFileUseCount;
44  std::map<std::string, Db*> mapDb;
45 
46  CDBEnv();
47  ~CDBEnv();
48  void MakeMock();
49  bool IsMock() { return fMockDb; }
50 
51  /*
52  * Verify that database file strFile is OK. If it is not,
53  * call the callback to try to recover.
54  * This must be called BEFORE strFile is opened.
55  * Returns true if strFile is OK.
56  */
58  VerifyResult Verify(std::string strFile, bool (*recoverFunc)(CDBEnv& dbenv, std::string strFile));
59  /*
60  * Salvage data from a file that Verify says is bad.
61  * fAggressive sets the DB_AGGRESSIVE flag (see berkeley DB->verify() method documentation).
62  * Appends binary key/value pairs to vResult, returns true if successful.
63  * NOTE: reads the entire database into memory, so cannot be used
64  * for huge databases.
65  */
66  typedef std::pair<std::vector<unsigned char>, std::vector<unsigned char> > KeyValPair;
67  bool Salvage(std::string strFile, bool fAggressive, std::vector<KeyValPair>& vResult);
68 
69  bool Open(const boost::filesystem::path &path);
70  void Close();
71  void Flush(bool fShutdown);
72  void CheckpointLSN(std::string strFile);
73 
74  void CloseDb(const std::string& strFile);
75  bool RemoveDb(const std::string& strFile);
76 
77  DbTxn *TxnBegin(int flags=DB_TXN_WRITE_NOSYNC)
78  {
79  DbTxn* ptxn = NULL;
80  int ret = dbenv.txn_begin(NULL, &ptxn, flags);
81  if (!ptxn || ret != 0)
82  return NULL;
83  return ptxn;
84  }
85 };
86 
87 extern CDBEnv bitdb;
88 
89 
91 class CDB
92 {
93 protected:
94  Db* pdb;
95  std::string strFile;
96  DbTxn *activeTxn;
97  bool fReadOnly;
98 
99  explicit CDB(const char* pszFile, const char* pszMode="r+");
100  ~CDB() { Close(); }
101 public:
102  void Flush();
103  void Close();
104 private:
105  CDB(const CDB&);
106  void operator=(const CDB&);
107 
108 protected:
109  template<typename K, typename T>
110  bool Read(const K& key, T& value)
111  {
112  if (!pdb)
113  return false;
114 
115  // Key
116  CDataStream ssKey(SER_DISK, CLIENT_VERSION);
117  ssKey.reserve(1000);
118  ssKey << key;
119  Dbt datKey(&ssKey[0], ssKey.size());
120 
121  // Read
122  Dbt datValue;
123  datValue.set_flags(DB_DBT_MALLOC);
124  int ret = pdb->get(activeTxn, &datKey, &datValue, 0);
125  memset(datKey.get_data(), 0, datKey.get_size());
126  if (datValue.get_data() == NULL)
127  return false;
128 
129  // Unserialize value
130  try {
131  CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION);
132  ssValue >> value;
133  }
134  catch (std::exception &e) {
135  return false;
136  }
137 
138  // Clear and free memory
139  memset(datValue.get_data(), 0, datValue.get_size());
140  free(datValue.get_data());
141  return (ret == 0);
142  }
143 
144  template<typename K, typename T>
145  bool Write(const K& key, const T& value, bool fOverwrite=true)
146  {
147  if (!pdb)
148  return false;
149  if (fReadOnly)
150  assert(!"Write called on database in read-only mode");
151 
152  // Key
153  CDataStream ssKey(SER_DISK, CLIENT_VERSION);
154  ssKey.reserve(1000);
155  ssKey << key;
156  Dbt datKey(&ssKey[0], ssKey.size());
157 
158  // Value
159  CDataStream ssValue(SER_DISK, CLIENT_VERSION);
160  ssValue.reserve(10000);
161  ssValue << value;
162  Dbt datValue(&ssValue[0], ssValue.size());
163 
164  // Write
165  int ret = pdb->put(activeTxn, &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
166 
167  // Clear memory in case it was a private key
168  memset(datKey.get_data(), 0, datKey.get_size());
169  memset(datValue.get_data(), 0, datValue.get_size());
170  return (ret == 0);
171  }
172 
173  template<typename K>
174  bool Erase(const K& key)
175  {
176  if (!pdb)
177  return false;
178  if (fReadOnly)
179  assert(!"Erase called on database in read-only mode");
180 
181  // Key
182  CDataStream ssKey(SER_DISK, CLIENT_VERSION);
183  ssKey.reserve(1000);
184  ssKey << key;
185  Dbt datKey(&ssKey[0], ssKey.size());
186 
187  // Erase
188  int ret = pdb->del(activeTxn, &datKey, 0);
189 
190  // Clear memory
191  memset(datKey.get_data(), 0, datKey.get_size());
192  return (ret == 0 || ret == DB_NOTFOUND);
193  }
194 
195  template<typename K>
196  bool Exists(const K& key)
197  {
198  if (!pdb)
199  return false;
200 
201  // Key
202  CDataStream ssKey(SER_DISK, CLIENT_VERSION);
203  ssKey.reserve(1000);
204  ssKey << key;
205  Dbt datKey(&ssKey[0], ssKey.size());
206 
207  // Exists
208  int ret = pdb->exists(activeTxn, &datKey, 0);
209 
210  // Clear memory
211  memset(datKey.get_data(), 0, datKey.get_size());
212  return (ret == 0);
213  }
214 
215  Dbc* GetCursor()
216  {
217  if (!pdb)
218  return NULL;
219  Dbc* pcursor = NULL;
220  int ret = pdb->cursor(NULL, &pcursor, 0);
221  if (ret != 0)
222  return NULL;
223  return pcursor;
224  }
225 
226  int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
227  {
228  // Read at cursor
229  Dbt datKey;
230  if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
231  {
232  datKey.set_data(&ssKey[0]);
233  datKey.set_size(ssKey.size());
234  }
235  Dbt datValue;
236  if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
237  {
238  datValue.set_data(&ssValue[0]);
239  datValue.set_size(ssValue.size());
240  }
241  datKey.set_flags(DB_DBT_MALLOC);
242  datValue.set_flags(DB_DBT_MALLOC);
243  int ret = pcursor->get(&datKey, &datValue, fFlags);
244  if (ret != 0)
245  return ret;
246  else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
247  return 99999;
248 
249  // Convert to streams
250  ssKey.SetType(SER_DISK);
251  ssKey.clear();
252  ssKey.write((char*)datKey.get_data(), datKey.get_size());
253  ssValue.SetType(SER_DISK);
254  ssValue.clear();
255  ssValue.write((char*)datValue.get_data(), datValue.get_size());
256 
257  // Clear and free memory
258  memset(datKey.get_data(), 0, datKey.get_size());
259  memset(datValue.get_data(), 0, datValue.get_size());
260  free(datKey.get_data());
261  free(datValue.get_data());
262  return 0;
263  }
264 
265 public:
266  bool TxnBegin()
267  {
268  if (!pdb || activeTxn)
269  return false;
270  DbTxn* ptxn = bitdb.TxnBegin();
271  if (!ptxn)
272  return false;
273  activeTxn = ptxn;
274  return true;
275  }
276 
277  bool TxnCommit()
278  {
279  if (!pdb || !activeTxn)
280  return false;
281  int ret = activeTxn->commit(0);
282  activeTxn = NULL;
283  return (ret == 0);
284  }
285 
286  bool TxnAbort()
287  {
288  if (!pdb || !activeTxn)
289  return false;
290  int ret = activeTxn->abort();
291  activeTxn = NULL;
292  return (ret == 0);
293  }
294 
295  bool ReadVersion(int& nVersion)
296  {
297  nVersion = 0;
298  return Read(std::string("version"), nVersion);
299  }
300 
301  bool WriteVersion(int nVersion)
302  {
303  return Write(std::string("version"), nVersion);
304  }
305 
306  bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
307 };
308 
309 
310 
311 
312 
313 
314 
315 
317 class CAddrDB
318 {
319 private:
320  boost::filesystem::path pathAddr;
321 public:
322  CAddrDB();
323  bool Write(const CAddrMan& addr);
324  bool Read(CAddrMan& addr);
325 };
326 
327 #endif // BITCOIN_DB_H
bool Erase(const K &key)
Definition: db.h:174
Access to the (IP) address database (peers.dat)
Definition: db.h:317
std::map< std::string, int > mapFileUseCount
Definition: db.h:43
DbTxn * activeTxn
Definition: db.h:96
void CheckpointLSN(std::string strFile)
Definition: db.cpp:209
std::string * value
Definition: version_set.cc:270
DbTxn * TxnBegin(int flags=DB_TXN_WRITE_NOSYNC)
Definition: db.h:77
int ReadAtCursor(Dbc *pcursor, CDataStream &ssKey, CDataStream &ssValue, unsigned int fFlags=DB_NEXT)
Definition: db.h:226
static bool Rewrite(const std::string &strFile, const char *pszSkip=NULL)
Definition: db.cpp:335
std::string strFile
Definition: db.h:95
CAddrDB()
Definition: db.cpp:490
Master key for wallet encryption.
Definition: crypter.h:30
bool Write(const K &key, const T &value, bool fOverwrite=true)
Definition: db.h:145
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
Definition: main.h:1968
void Close()
Definition: db.cpp:294
bool fReadOnly
Definition: db.h:97
Dbc * GetCursor()
Definition: db.h:215
void Flush(bool fShutdown)
Definition: db.cpp:429
CDBEnv bitdb
Definition: db.cpp:29
void EnvShutdown()
Definition: db.cpp:31
bool Exists(const K &key)
Definition: db.h:196
Double ended buffer combining vector and stream-like interfaces.
Definition: serialize.h:799
unsigned int nWalletDBUpdated
Definition: db.cpp:21
~CDBEnv()
Definition: db.cpp:50
bool fDbEnvInit
Definition: db.h:34
bool TxnBegin()
Definition: db.h:266
boost::filesystem::path path
Definition: db.h:36
Stochastical (IP) address manager.
Definition: addrman.h:165
void MakeMock()
Definition: db.cpp:105
VerifyResult
Definition: db.h:57
bool Write(const CAddrMan &addr)
Definition: db.cpp:495
std::map< std::string, Db * > mapDb
Definition: db.h:44
size_type size() const
Definition: serialize.h:888
bool ReadVersion(int &nVersion)
Definition: db.h:295
bool TxnCommit()
Definition: db.h:277
A CService with information about it as peer.
Definition: protocol.h:76
bool TxnAbort()
Definition: db.h:286
RAII class that provides access to a Berkeley database.
Definition: db.h:91
Used to marshal pointers into hashes for db storage.
Definition: main.h:1840
CCriticalSection cs_db
Definition: db.h:41
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: main.h:278
bool IsMock()
Definition: db.h:49
bool RemoveDb(const std::string &strFile)
Definition: db.cpp:326
bool Read(const K &key, T &value)
Definition: db.h:110
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:367
void operator=(const CDB &)
void Close()
Definition: db.cpp:55
bool Salvage(std::string strFile, bool fAggressive, std::vector< KeyValPair > &vResult)
Definition: db.cpp:154
CDataStream & write(const char *pch, int nSize)
Definition: serialize.h:1048
void reserve(size_type n)
Definition: serialize.h:891
boost::filesystem::path pathAddr
Definition: db.h:320
void CloseDb(const std::string &strFile)
Definition: db.cpp:311
bool WriteVersion(int nVersion)
Definition: db.h:301
Definition: db.h:31
CDB(const char *pszFile, const char *pszMode="r+")
Definition: db.cpp:218
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:69
bool fMockDb
Definition: db.h:35
VerifyResult Verify(std::string strFile, bool(*recoverFunc)(CDBEnv &dbenv, std::string strFile))
Definition: db.cpp:137
bool BackupWallet(const CWallet &wallet, const std::string &strDest)
DbEnv dbenv
Definition: db.h:42
void clear()
Definition: serialize.h:894
Db * pdb
Definition: db.h:94
std::pair< std::vector< unsigned char >, std::vector< unsigned char > > KeyValPair
Definition: db.h:66
CDBEnv()
Definition: db.cpp:44
bool Open(const boost::filesystem::path &path)
Definition: db.cpp:60
~CDB()
Definition: db.h:100
bool Read(CAddrMan &addr)
Definition: db.cpp:533
void ThreadFlushWalletDB(const std::string &strWalletFile)
void Flush()
Definition: db.cpp:281
void SetType(int n)
Definition: serialize.h:998