Bitcoin ABC  0.24.7
P2P Digital Currency
bdb.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2020 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_BDB_H
7 #define BITCOIN_WALLET_BDB_H
8 
9 #include <clientversion.h>
10 #include <fs.h>
11 #include <serialize.h>
12 #include <streams.h>
13 #include <util/system.h>
14 #include <wallet/db.h>
15 
16 #include <db_cxx.h>
17 
18 #include <atomic>
19 #include <map>
20 #include <memory>
21 #include <string>
22 #include <unordered_map>
23 #include <vector>
24 
25 struct bilingual_str;
26 
27 static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100;
28 static const bool DEFAULT_WALLET_PRIVDB = true;
29 
31  u_int8_t value[DB_FILE_ID_LEN];
32  bool operator==(const WalletDatabaseFileId &rhs) const;
33 };
34 
35 class BerkeleyDatabase;
36 
38 private:
39  bool fDbEnvInit;
40  bool fMockDb;
41  // Don't change into fs::path, as that can result in
42  // shutdown problems/crashes caused by a static initialized internal
43  // pointer.
44  std::string strPath;
45 
46 public:
47  std::unique_ptr<DbEnv> dbenv;
48  std::map<std::string, std::reference_wrapper<BerkeleyDatabase>> m_databases;
49  std::unordered_map<std::string, WalletDatabaseFileId> m_fileids;
50  std::condition_variable_any m_db_in_use;
51 
52  BerkeleyEnvironment(const fs::path &env_directory);
55  void Reset();
56 
57  void MakeMock();
58  bool IsMock() const { return fMockDb; }
59  bool IsInitialized() const { return fDbEnvInit; }
60  fs::path Directory() const { return strPath; }
61 
62  bool Open(bilingual_str &error);
63  void Close();
64  void Flush(bool fShutdown);
65  void CheckpointLSN(const std::string &strFile);
66 
67  void CloseDb(const std::string &strFile);
68  void ReloadDbEnv();
69 
70  DbTxn *TxnBegin(int flags = DB_TXN_WRITE_NOSYNC) {
71  DbTxn *ptxn = nullptr;
72  int ret = dbenv->txn_begin(nullptr, &ptxn, flags);
73  if (!ptxn || ret != 0) {
74  return nullptr;
75  }
76  return ptxn;
77  }
78 };
79 
81 std::shared_ptr<BerkeleyEnvironment>
82 GetWalletEnv(const fs::path &wallet_path, std::string &database_filename);
83 
85 bool IsBerkeleyBtree(const fs::path &path);
86 
87 class BerkeleyBatch;
88 
94 public:
95  BerkeleyDatabase() = delete;
96 
98  BerkeleyDatabase(std::shared_ptr<BerkeleyEnvironment> envIn,
99  std::string filename)
100  : WalletDatabase(), env(std::move(envIn)),
101  strFile(std::move(filename)) {
102  auto inserted =
103  this->env->m_databases.emplace(strFile, std::ref(*this));
104  assert(inserted.second);
105  }
106 
107  ~BerkeleyDatabase() override;
108 
110  void Open() override;
111 
116  bool Rewrite(const char *pszSkip = nullptr) override;
117 
119  void AddRef() override;
120 
125  void RemoveRef() override;
126 
130  bool Backup(const std::string &strDest) const override;
131 
135  void Flush() override;
136 
141  void Close() override;
142 
147  bool PeriodicFlush() override;
148 
149  void IncrementUpdateCounter() override;
150 
151  void ReloadDbEnv() override;
152 
154  bool Verify(bilingual_str &error);
155 
157  std::string Filename() override {
158  return (env->Directory() / strFile).string();
159  }
160 
170  std::shared_ptr<BerkeleyEnvironment> env;
171 
176  std::unique_ptr<Db> m_db;
177 
178  std::string strFile;
179 
181  std::unique_ptr<DatabaseBatch>
182  MakeBatch(bool flush_on_close = true) override;
183 };
184 
186 class BerkeleyBatch : public DatabaseBatch {
188  class SafeDbt final {
189  Dbt m_dbt;
190 
191  public:
192  // construct Dbt with internally-managed data
193  SafeDbt();
194  // construct Dbt with provided data
195  SafeDbt(void *data, size_t size);
196  ~SafeDbt();
197 
198  // delegate to Dbt
199  const void *get_data() const;
200  u_int32_t get_size() const;
201 
202  // conversion operator to access the underlying Dbt
203  operator Dbt *();
204  };
205 
206 private:
207  bool ReadKey(CDataStream &&key, CDataStream &value) override;
208  bool WriteKey(CDataStream &&key, CDataStream &&value,
209  bool overwrite = true) override;
210  bool EraseKey(CDataStream &&key) override;
211  bool HasKey(CDataStream &&key) override;
212 
213 protected:
214  Db *pdb;
215  std::string strFile;
216  DbTxn *activeTxn;
217  Dbc *m_cursor;
218  bool fReadOnly;
222 
223 public:
224  explicit BerkeleyBatch(BerkeleyDatabase &database, const bool fReadOnly,
225  bool fFlushOnCloseIn = true);
226  ~BerkeleyBatch() override;
227 
228  BerkeleyBatch(const BerkeleyBatch &) = delete;
229  BerkeleyBatch &operator=(const BerkeleyBatch &) = delete;
230 
231  void Flush() override;
232  void Close() override;
233 
234  bool StartCursor() override;
235  bool ReadAtCursor(CDataStream &ssKey, CDataStream &ssValue,
236  bool &complete) override;
237  void CloseCursor() override;
238  bool TxnBegin() override;
239  bool TxnCommit() override;
240  bool TxnAbort() override;
241 };
242 
243 std::string BerkeleyDatabaseVersion();
244 
246 bool ExistsBerkeleyDatabase(const fs::path &path);
247 
249 std::unique_ptr<BerkeleyDatabase>
250 MakeBerkeleyDatabase(const fs::path &path, const DatabaseOptions &options,
252 
253 #endif // BITCOIN_WALLET_BDB_H
BerkeleyEnvironment::BerkeleyEnvironment
BerkeleyEnvironment()
Construct an in-memory mock Berkeley environment for testing.
Definition: bdb.cpp:222
DatabaseOptions
Definition: db.h:221
BerkeleyBatch::SafeDbt::SafeDbt
SafeDbt()
Definition: bdb.cpp:250
BerkeleyEnvironment::dbenv
std::unique_ptr< DbEnv > dbenv
Definition: bdb.h:47
fs.h
flags
int flags
Definition: bitcoin-tx.cpp:532
BerkeleyDatabase::Flush
void Flush() override
Make sure all changes are flushed to database file.
Definition: bdb.cpp:718
streams.h
ExistsBerkeleyDatabase
bool ExistsBerkeleyDatabase(const fs::path &path)
Check if Berkeley database exists at specified path.
Definition: bdb.cpp:892
bilingual_str
Bilingual messages:
Definition: translation.h:17
BerkeleyDatabase::Open
void Open() override
Open the database if it is not already opened.
Definition: bdb.cpp:347
BerkeleyBatch::SafeDbt
RAII class that automatically cleanses its data on destruction.
Definition: bdb.h:188
BerkeleyBatch::fFlushOnClose
bool fFlushOnClose
Definition: bdb.h:219
IsBerkeleyBtree
bool IsBerkeleyBtree(const fs::path &path)
Check format of database file.
Definition: walletutil.cpp:32
BerkeleyBatch::activeTxn
DbTxn * activeTxn
Definition: bdb.h:216
clientversion.h
WalletDatabase
An instance of this class represents one database.
Definition: db.h:100
BerkeleyDatabase::AddRef
void AddRef() override
Indicate the a new database user has began using the database.
Definition: bdb.cpp:870
BerkeleyBatch::operator=
BerkeleyBatch & operator=(const BerkeleyBatch &)=delete
BerkeleyEnvironment::~BerkeleyEnvironment
~BerkeleyEnvironment()
Definition: bdb.cpp:143
BerkeleyDatabase::Rewrite
bool Rewrite(const char *pszSkip=nullptr) override
Rewrite the entire database on disk, with the exception of key pszSkip if non-zero.
Definition: bdb.cpp:488
BerkeleyEnvironment::fMockDb
bool fMockDb
Definition: bdb.h:40
BerkeleyBatch::ReadKey
bool ReadKey(CDataStream &&key, CDataStream &value) override
Definition: bdb.cpp:810
BerkeleyEnvironment::m_db_in_use
std::condition_variable_any m_db_in_use
Definition: bdb.h:50
BerkeleyBatch::TxnAbort
bool TxnAbort() override
Definition: bdb.cpp:797
BerkeleyDatabase::BerkeleyDatabase
BerkeleyDatabase(std::shared_ptr< BerkeleyEnvironment > envIn, std::string filename)
Create DB handle to real database.
Definition: bdb.h:98
BerkeleyDatabase::m_db
std::unique_ptr< Db > m_db
Database pointer.
Definition: bdb.h:176
BerkeleyBatch::SafeDbt::m_dbt
Dbt m_dbt
Definition: bdb.h:189
BerkeleyEnvironment::ReloadDbEnv
void ReloadDbEnv()
Definition: bdb.cpp:459
WalletDatabaseFileId::operator==
bool operator==(const WalletDatabaseFileId &rhs) const
Definition: bdb.cpp:60
BerkeleyBatch::Flush
void Flush() override
Definition: bdb.cpp:400
BerkeleyEnvironment::fDbEnvInit
bool fDbEnvInit
Definition: bdb.h:39
BerkeleyDatabase::strFile
std::string strFile
Definition: bdb.h:178
BerkeleyBatch::BerkeleyBatch
BerkeleyBatch(BerkeleyDatabase &database, const bool fReadOnly, bool fFlushOnCloseIn=true)
Definition: bdb.cpp:328
BerkeleyDatabase::env
std::shared_ptr< BerkeleyEnvironment > env
Pointer to shared database environment.
Definition: bdb.h:170
BerkeleyBatch::~BerkeleyBatch
~BerkeleyBatch() override
Definition: bdb.cpp:426
BerkeleyEnvironment::m_fileids
std::unordered_map< std::string, WalletDatabaseFileId > m_fileids
Definition: bdb.h:49
BerkeleyDatabase
An instance of this class represents one database.
Definition: bdb.h:93
db.h
BerkeleyEnvironment::Flush
void Flush(bool fShutdown)
Definition: bdb.cpp:587
BerkeleyBatch::SafeDbt::get_data
const void * get_data() const
Definition: bdb.cpp:269
BerkeleyDatabase::Verify
bool Verify(bilingual_str &error)
Verifies the environment and database file.
Definition: bdb.cpp:281
BerkeleyBatch::WriteKey
bool WriteKey(CDataStream &&key, CDataStream &&value, bool overwrite=true) override
Definition: bdb.cpp:826
BerkeleyBatch::fReadOnly
bool fReadOnly
Definition: bdb.h:218
BerkeleyDatabase::~BerkeleyDatabase
~BerkeleyDatabase() override
Definition: bdb.cpp:317
BerkeleyBatch::strFile
std::string strFile
Definition: bdb.h:215
BerkeleyBatch::Close
void Close() override
Definition: bdb.cpp:431
BerkeleyDatabase::ReloadDbEnv
void ReloadDbEnv() override
Definition: bdb.cpp:726
BerkeleyEnvironment::IsInitialized
bool IsInitialized() const
Definition: bdb.h:59
BerkeleyEnvironment::Directory
fs::path Directory() const
Definition: bdb.h:60
BerkeleyDatabaseVersion
std::string BerkeleyDatabaseVersion()
Definition: bdb.cpp:806
BerkeleyEnvironment::Reset
void Reset()
Definition: bdb.cpp:132
DatabaseBatch
RAII class that provides access to a WalletDatabase.
Definition: db.h:24
WalletDatabaseFileId
Definition: bdb.h:30
BerkeleyBatch::HasKey
bool HasKey(CDataStream &&key) override
Definition: bdb.cpp:859
BerkeleyBatch::EraseKey
bool EraseKey(CDataStream &&key) override
Definition: bdb.cpp:845
DEFAULT_WALLET_PRIVDB
static const bool DEFAULT_WALLET_PRIVDB
Definition: bdb.h:28
BerkeleyBatch::SafeDbt::~SafeDbt
~SafeDbt()
Definition: bdb.cpp:256
BerkeleyBatch::m_cursor
Dbc * m_cursor
Definition: bdb.h:217
system.h
GetWalletEnv
std::shared_ptr< BerkeleyEnvironment > GetWalletEnv(const fs::path &wallet_path, std::string &database_filename)
Get BerkeleyEnvironment and database filename given a wallet path.
Definition: bdb.cpp:77
BerkeleyEnvironment::MakeMock
void MakeMock()
BerkeleyBatch::m_database
BerkeleyDatabase & m_database
Definition: bdb.h:221
WalletDatabaseFileId::value
u_int8_t value[DB_FILE_ID_LEN]
Definition: bdb.h:31
BerkeleyDatabase::PeriodicFlush
bool PeriodicFlush() override
flush the wallet passively (TRY_LOCK) ideal to be called periodically
Definition: bdb.cpp:646
BerkeleyBatch
RAII class that provides access to a Berkeley database.
Definition: bdb.h:186
BerkeleyBatch::StartCursor
bool StartCursor() override
Definition: bdb.cpp:730
BerkeleyEnvironment::m_databases
std::map< std::string, std::reference_wrapper< BerkeleyDatabase > > m_databases
Definition: bdb.h:48
MakeBerkeleyDatabase
std::unique_ptr< BerkeleyDatabase > MakeBerkeleyDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
Return object giving access to Berkeley database at specified path.
Definition: bdb.cpp:900
BerkeleyEnvironment::CheckpointLSN
void CheckpointLSN(const std::string &strFile)
Definition: bdb.cpp:309
BerkeleyEnvironment::Close
void Close()
Definition: bdb.cpp:96
BerkeleyBatch::SafeDbt::get_size
u_int32_t get_size() const
Definition: bdb.cpp:273
BerkeleyEnvironment::IsMock
bool IsMock() const
Definition: bdb.h:58
DatabaseStatus
DatabaseStatus
Definition: db.h:229
BerkeleyEnvironment::strPath
std::string strPath
Definition: bdb.h:44
BerkeleyDatabase::Backup
bool Backup(const std::string &strDest) const override
Back up the entire database to a file.
Definition: bdb.cpp:679
serialize.h
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:197
BerkeleyBatch::env
BerkeleyEnvironment * env
Definition: bdb.h:220
BerkeleyBatch::TxnCommit
bool TxnCommit() override
Definition: bdb.cpp:788
BerkeleyBatch::pdb
Db * pdb
Definition: bdb.h:214
BerkeleyDatabase::BerkeleyDatabase
BerkeleyDatabase()=delete
BerkeleyDatabase::IncrementUpdateCounter
void IncrementUpdateCounter() override
Definition: bdb.cpp:422
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
BerkeleyEnvironment::Open
bool Open(bilingual_str &error)
Definition: bdb.cpp:149
BerkeleyBatch::CloseCursor
void CloseCursor() override
Definition: bdb.cpp:768
BerkeleyDatabase::Filename
std::string Filename() override
Return path to main database filename.
Definition: bdb.h:157
BerkeleyDatabase::Close
void Close() override
Flush to the database file and close the database.
Definition: bdb.cpp:722
BerkeleyBatch::TxnBegin
bool TxnBegin() override
Definition: bdb.cpp:776
BerkeleyDatabase::RemoveRef
void RemoveRef() override
Indicate that database user has stopped using the database and that it could be flushed or closed.
Definition: bdb.cpp:879
DEFAULT_WALLET_DBLOGSIZE
static const unsigned int DEFAULT_WALLET_DBLOGSIZE
Definition: bdb.h:27
BerkeleyEnvironment::CloseDb
void CloseDb(const std::string &strFile)
Definition: bdb.cpp:447
BerkeleyBatch::ReadAtCursor
bool ReadAtCursor(CDataStream &ssKey, CDataStream &ssValue, bool &complete) override
Definition: bdb.cpp:739
BerkeleyDatabase::MakeBatch
std::unique_ptr< DatabaseBatch > MakeBatch(bool flush_on_close=true) override
Make a BerkeleyBatch connected to this database.
Definition: bdb.cpp:888
BerkeleyEnvironment
Definition: bdb.h:37
BerkeleyEnvironment::TxnBegin
DbTxn * TxnBegin(int flags=DB_TXN_WRITE_NOSYNC)
Definition: bdb.h:70