Bitcoin Core  22.99.0
P2P Digital Currency
bdb.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2021 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 <atomic>
17 #include <map>
18 #include <memory>
19 #include <string>
20 #include <unordered_map>
21 #include <vector>
22 
23 #if defined(__GNUC__) && !defined(__clang__)
24 #pragma GCC diagnostic push
25 #pragma GCC diagnostic ignored "-Wsuggest-override"
26 #endif
27 #include <db_cxx.h>
28 #if defined(__GNUC__) && !defined(__clang__)
29 #pragma GCC diagnostic pop
30 #endif
31 
32 struct bilingual_str;
33 
34 namespace wallet {
35 static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100;
36 static const bool DEFAULT_WALLET_PRIVDB = true;
37 
39  u_int8_t value[DB_FILE_ID_LEN];
40  bool operator==(const WalletDatabaseFileId& rhs) const;
41 };
42 
43 class BerkeleyDatabase;
44 
46 {
47 private:
48  bool fDbEnvInit;
49  bool fMockDb;
50  // Don't change into fs::path, as that can result in
51  // shutdown problems/crashes caused by a static initialized internal pointer.
52  std::string strPath;
53 
54 public:
55  std::unique_ptr<DbEnv> dbenv;
56  std::map<std::string, std::reference_wrapper<BerkeleyDatabase>> m_databases;
57  std::unordered_map<std::string, WalletDatabaseFileId> m_fileids;
58  std::condition_variable_any m_db_in_use;
59 
60  explicit BerkeleyEnvironment(const fs::path& env_directory);
63  void Reset();
64 
65  bool IsMock() const { return fMockDb; }
66  bool IsInitialized() const { return fDbEnvInit; }
68 
69  bool Open(bilingual_str& error);
70  void Close();
71  void Flush(bool fShutdown);
72  void CheckpointLSN(const std::string& strFile);
73 
74  void CloseDb(const std::string& strFile);
75  void ReloadDbEnv();
76 
77  DbTxn* TxnBegin(int flags = DB_TXN_WRITE_NOSYNC)
78  {
79  DbTxn* ptxn = nullptr;
80  int ret = dbenv->txn_begin(nullptr, &ptxn, flags);
81  if (!ptxn || ret != 0)
82  return nullptr;
83  return ptxn;
84  }
85 };
86 
88 std::shared_ptr<BerkeleyEnvironment> GetBerkeleyEnv(const fs::path& env_directory);
89 
90 class BerkeleyBatch;
91 
96 {
97 public:
98  BerkeleyDatabase() = delete;
99 
101  BerkeleyDatabase(std::shared_ptr<BerkeleyEnvironment> env, std::string filename) :
102  WalletDatabase(), env(std::move(env)), strFile(std::move(filename))
103  {
104  auto inserted = this->env->m_databases.emplace(strFile, std::ref(*this));
105  assert(inserted.second);
106  }
107 
108  ~BerkeleyDatabase() override;
109 
111  void Open() override;
112 
115  bool Rewrite(const char* pszSkip=nullptr) override;
116 
118  void AddRef() override;
120  void RemoveRef() override;
121 
124  bool Backup(const std::string& strDest) const override;
125 
128  void Flush() override;
132  void Close() override;
133  /* flush the wallet passively (TRY_LOCK)
134  ideal to be called periodically */
135  bool PeriodicFlush() override;
136 
137  void IncrementUpdateCounter() override;
138 
139  void ReloadDbEnv() override;
140 
142  bool Verify(bilingual_str& error);
143 
145  std::string Filename() override { return fs::PathToString(env->Directory() / strFile); }
146 
147  std::string Format() override { return "bdb"; }
157  std::shared_ptr<BerkeleyEnvironment> env;
158 
160  std::unique_ptr<Db> m_db;
161 
162  std::string strFile;
163 
165  std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override;
166 };
167 
170 {
172  class SafeDbt final
173  {
174  Dbt m_dbt;
175 
176  public:
177  // construct Dbt with internally-managed data
178  SafeDbt();
179  // construct Dbt with provided data
180  SafeDbt(void* data, size_t size);
181  ~SafeDbt();
182 
183  // delegate to Dbt
184  const void* get_data() const;
185  u_int32_t get_size() const;
186 
187  // conversion operator to access the underlying Dbt
188  operator Dbt*();
189  };
190 
191 private:
192  bool ReadKey(CDataStream&& key, CDataStream& value) override;
193  bool WriteKey(CDataStream&& key, CDataStream&& value, bool overwrite = true) override;
194  bool EraseKey(CDataStream&& key) override;
195  bool HasKey(CDataStream&& key) override;
196 
197 protected:
198  Db* pdb;
199  std::string strFile;
200  DbTxn* activeTxn;
201  Dbc* m_cursor;
202  bool fReadOnly;
206 
207 public:
208  explicit BerkeleyBatch(BerkeleyDatabase& database, const bool fReadOnly, bool fFlushOnCloseIn=true);
209  ~BerkeleyBatch() override;
210 
211  BerkeleyBatch(const BerkeleyBatch&) = delete;
212  BerkeleyBatch& operator=(const BerkeleyBatch&) = delete;
213 
214  void Flush() override;
215  void Close() override;
216 
217  bool StartCursor() override;
218  bool ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete) override;
219  void CloseCursor() override;
220  bool TxnBegin() override;
221  bool TxnCommit() override;
222  bool TxnAbort() override;
223 };
224 
225 std::string BerkeleyDatabaseVersion();
226 
230 
232 std::unique_ptr<BerkeleyDatabase> MakeBerkeleyDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
233 } // namespace wallet
234 
235 #endif // BITCOIN_WALLET_BDB_H
wallet::DEFAULT_WALLET_PRIVDB
static const bool DEFAULT_WALLET_PRIVDB
Definition: bdb.h:36
wallet::WalletDatabase
An instance of this class represents one database.
Definition: db.h:104
wallet::BerkeleyEnvironment::m_databases
std::map< std::string, std::reference_wrapper< BerkeleyDatabase > > m_databases
Definition: bdb.h:56
wallet::BerkeleyDatabase::Verify
bool Verify(bilingual_str &error)
Verifies the environment and database file.
Definition: bdb.cpp:259
wallet::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:826
wallet::BerkeleyDatabase::BerkeleyDatabase
BerkeleyDatabase()=delete
wallet::BerkeleyEnvironment::CheckpointLSN
void CheckpointLSN(const std::string &strFile)
Definition: bdb.cpp:286
assert
assert(!tx.IsCoinBase())
wallet::BerkeleyBatch::ReadKey
bool ReadKey(CDataStream &&key, CDataStream &value) override
Definition: bdb.cpp:749
wallet::WalletDatabaseFileId::operator==
bool operator==(const WalletDatabaseFileId &rhs) const
Definition: bdb.cpp:51
wallet::DEFAULT_WALLET_DBLOGSIZE
static const unsigned int DEFAULT_WALLET_DBLOGSIZE
Definition: bdb.h:35
wallet::BerkeleyBatch::SafeDbt::SafeDbt
SafeDbt()
Definition: bdb.cpp:220
wallet::BerkeleyDatabase::Flush
void Flush() override
Make sure all changes are flushed to database file.
Definition: bdb.cpp:641
fs.h
flags
int flags
Definition: bitcoin-tx.cpp:525
wallet::BerkeleyDatabase::Open
void Open() override
Open the database if it is not already opened.
Definition: bdb.cpp:323
streams.h
wallet::DatabaseStatus
DatabaseStatus
Definition: db.h:213
wallet::DatabaseBatch
RAII class that provides access to a WalletDatabase.
Definition: db.h:25
bilingual_str
Bilingual messages:
Definition: translation.h:16
wallet::BerkeleyEnvironment::strPath
std::string strPath
Definition: bdb.h:52
wallet::BerkeleyEnvironment::ReloadDbEnv
void ReloadDbEnv()
Definition: bdb.cpp:423
wallet::BerkeleyDatabase::Filename
std::string Filename() override
Return path to main database filename.
Definition: bdb.h:145
wallet::BerkeleyDatabase::~BerkeleyDatabase
~BerkeleyDatabase() override
Definition: bdb.cpp:294
wallet::BerkeleyBatch::TxnAbort
bool TxnAbort() override
Definition: bdb.cpp:718
clientversion.h
wallet
Definition: node.h:38
wallet::BerkeleyBatch::TxnBegin
bool TxnBegin() override
Definition: bdb.cpp:698
fs::PathToString
static std::string PathToString(const path &path)
Convert path object to byte string.
Definition: fs.h:120
wallet::BerkeleyEnvironment::Reset
void Reset()
Definition: bdb.cpp:108
db.h
wallet::BerkeleyDatabase
An instance of this class represents one database.
Definition: bdb.h:95
wallet::BerkeleyBatch::fReadOnly
bool fReadOnly
Definition: bdb.h:202
wallet::BerkeleyEnvironment::BerkeleyEnvironment
BerkeleyEnvironment()
Construct an in-memory mock Berkeley environment for testing.
Definition: bdb.cpp:190
wallet::WalletDatabaseFileId
Definition: bdb.h:38
wallet::BerkeleyBatch::operator=
BerkeleyBatch & operator=(const BerkeleyBatch &)=delete
wallet::BerkeleyBatch::SafeDbt
RAII class that automatically cleanses its data on destruction.
Definition: bdb.h:172
wallet::GetBerkeleyEnv
std::shared_ptr< BerkeleyEnvironment > GetBerkeleyEnv(const fs::path &env_directory)
Get BerkeleyEnvironment given a directory path.
Definition: bdb.cpp:62
wallet::BerkeleyBatch::m_database
BerkeleyDatabase & m_database
Definition: bdb.h:205
wallet::BerkeleyDatabase::m_db
std::unique_ptr< Db > m_db
Database pointer.
Definition: bdb.h:160
wallet::BerkeleyEnvironment
Definition: bdb.h:45
fs::path
Path class wrapper to prepare application code for transition from boost::filesystem library to std::...
Definition: fs.h:33
wallet::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:450
wallet::BerkeleyEnvironment::IsMock
bool IsMock() const
Definition: bdb.h:65
wallet::BerkeleyBatch::pdb
Db * pdb
Definition: bdb.h:198
wallet::BerkeleyEnvironment::~BerkeleyEnvironment
~BerkeleyEnvironment()
Definition: bdb.cpp:120
wallet::BerkeleyEnvironment::fMockDb
bool fMockDb
Definition: bdb.h:49
wallet::BerkeleyBatch::SafeDbt::get_data
const void * get_data() const
Definition: bdb.cpp:244
wallet::BerkeleyEnvironment::fDbEnvInit
bool fDbEnvInit
Definition: bdb.h:48
wallet::BerkeleyDatabase::Close
void Close() override
Flush to the database file and close the database.
Definition: bdb.cpp:646
fs::PathFromString
static path PathFromString(const std::string &string)
Convert byte string to path object.
Definition: fs.h:143
wallet::BerkeleyEnvironment::m_db_in_use
std::condition_variable_any m_db_in_use
Definition: bdb.h:58
wallet::BerkeleyEnvironment::Directory
fs::path Directory() const
Definition: bdb.h:67
wallet::BerkeleyBatch::m_cursor
Dbc * m_cursor
Definition: bdb.h:201
wallet::BerkeleyDatabase::IncrementUpdateCounter
void IncrementUpdateCounter() override
Definition: bdb.cpp:383
wallet::BerkeleyBatch::strFile
std::string strFile
Definition: bdb.h:199
wallet::WalletDatabaseFileId::value
u_int8_t value[DB_FILE_ID_LEN]
Definition: bdb.h:39
wallet::BerkeleyDatabase::PeriodicFlush
bool PeriodicFlush() override
Definition: bdb.cpp:577
wallet::BerkeleyBatch::CloseCursor
void CloseCursor() override
Definition: bdb.cpp:691
wallet::BerkeleyDatabase::env
std::shared_ptr< BerkeleyEnvironment > env
Pointer to shared database environment.
Definition: bdb.h:157
wallet::BerkeleyBatch::~BerkeleyBatch
~BerkeleyBatch() override
Definition: bdb.cpp:388
wallet::BerkeleyBatch::Flush
void Flush() override
Definition: bdb.cpp:368
system.h
wallet::BerkeleyBatch::activeTxn
DbTxn * activeTxn
Definition: bdb.h:200
wallet::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:814
wallet::BerkeleyEnvironment::Flush
void Flush(bool fShutdown)
Definition: bdb.cpp:534
wallet::BerkeleyDatabaseSanityCheck
bool BerkeleyDatabaseSanityCheck()
Perform sanity check of runtime BDB version versus linked BDB version.
Definition: bdb.cpp:727
wallet::BerkeleyBatch::fFlushOnClose
bool fFlushOnClose
Definition: bdb.h:203
wallet::BerkeleyEnvironment::Close
void Close()
Definition: bdb.cpp:78
wallet::BerkeleyBatch::Close
void Close() override
Definition: bdb.cpp:394
wallet::BerkeleyBatch::HasKey
bool HasKey(CDataStream &&key) override
Definition: bdb.cpp:793
std
Definition: setup_common.h:33
wallet::BerkeleyDatabase::BerkeleyDatabase
BerkeleyDatabase(std::shared_ptr< BerkeleyEnvironment > env, std::string filename)
Create DB handle to real database.
Definition: bdb.h:101
wallet::BerkeleyEnvironment::dbenv
std::unique_ptr< DbEnv > dbenv
Definition: bdb.h:55
wallet::BerkeleyEnvironment::CloseDb
void CloseDb(const std::string &strFile)
Definition: bdb.cpp:408
wallet::BerkeleyDatabaseVersion
std::string BerkeleyDatabaseVersion()
Definition: bdb.cpp:744
wallet::BerkeleyBatch::StartCursor
bool StartCursor() override
Definition: bdb.cpp:656
serialize.h
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:184
wallet::BerkeleyBatch::SafeDbt::~SafeDbt
~SafeDbt()
Definition: bdb.cpp:230
wallet::BerkeleyBatch
RAII class that provides access to a Berkeley database.
Definition: bdb.h:169
wallet::BerkeleyBatch::WriteKey
bool WriteKey(CDataStream &&key, CDataStream &&value, bool overwrite=true) override
Definition: bdb.cpp:765
wallet::BerkeleyBatch::SafeDbt::m_dbt
Dbt m_dbt
Definition: bdb.h:174
wallet::BerkeleyEnvironment::TxnBegin
DbTxn * TxnBegin(int flags=DB_TXN_WRITE_NOSYNC)
Definition: bdb.h:77
wallet::BerkeleyBatch::EraseKey
bool EraseKey(CDataStream &&key) override
Definition: bdb.cpp:780
wallet::BerkeleyDatabase::AddRef
void AddRef() override
Indicate that a new database user has begun using the database.
Definition: bdb.cpp:804
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
wallet::BerkeleyDatabase::Format
std::string Format() override
Definition: bdb.h:147
wallet::BerkeleyEnvironment::Open
bool Open(bilingual_str &error)
Definition: bdb.cpp:127
wallet::DatabaseOptions
Definition: db.h:204
wallet::BerkeleyBatch::BerkeleyBatch
BerkeleyBatch(BerkeleyDatabase &database, const bool fReadOnly, bool fFlushOnCloseIn=true)
Definition: bdb.cpp:306
wallet::BerkeleyBatch::SafeDbt::get_size
u_int32_t get_size() const
Definition: bdb.cpp:249
wallet::BerkeleyEnvironment::m_fileids
std::unordered_map< std::string, WalletDatabaseFileId > m_fileids
Definition: bdb.h:57
wallet::BerkeleyDatabase::ReloadDbEnv
void ReloadDbEnv() override
Definition: bdb.cpp:651
wallet::BerkeleyDatabase::MakeBatch
std::unique_ptr< DatabaseBatch > MakeBatch(bool flush_on_close=true) override
Make a BerkeleyBatch connected to this database.
Definition: bdb.cpp:821
wallet::BerkeleyEnvironment::IsInitialized
bool IsInitialized() const
Definition: bdb.h:66
wallet::BerkeleyBatch::TxnCommit
bool TxnCommit() override
Definition: bdb.cpp:709
wallet::BerkeleyBatch::ReadAtCursor
bool ReadAtCursor(CDataStream &ssKey, CDataStream &ssValue, bool &complete) override
Definition: bdb.cpp:665
wallet::BerkeleyDatabase::strFile
std::string strFile
Definition: bdb.h:162
wallet::BerkeleyDatabase::Backup
bool Backup(const std::string &strDest) const override
Back up the entire database to a file.
Definition: bdb.cpp:604
wallet::BerkeleyBatch::env
BerkeleyEnvironment * env
Definition: bdb.h:204