Bitcoin Core  24.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-2022 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 
37  uint8_t value[DB_FILE_ID_LEN];
38  bool operator==(const WalletDatabaseFileId& rhs) const;
39 };
40 
41 class BerkeleyDatabase;
42 
44 {
45 private:
46  bool fDbEnvInit;
47  bool fMockDb;
48  // Don't change into fs::path, as that can result in
49  // shutdown problems/crashes caused by a static initialized internal pointer.
50  std::string strPath;
51 
52 public:
53  std::unique_ptr<DbEnv> dbenv;
54  std::map<fs::path, std::reference_wrapper<BerkeleyDatabase>> m_databases;
55  std::unordered_map<std::string, WalletDatabaseFileId> m_fileids;
56  std::condition_variable_any m_db_in_use;
58 
59  explicit BerkeleyEnvironment(const fs::path& env_directory, bool use_shared_memory);
62  void Reset();
63 
64  bool IsMock() const { return fMockDb; }
65  bool IsInitialized() const { return fDbEnvInit; }
67 
68  bool Open(bilingual_str& error);
69  void Close();
70  void Flush(bool fShutdown);
71  void CheckpointLSN(const std::string& strFile);
72 
73  void CloseDb(const fs::path& filename);
74  void ReloadDbEnv();
75 
76  DbTxn* TxnBegin(int flags = DB_TXN_WRITE_NOSYNC)
77  {
78  DbTxn* ptxn = nullptr;
79  int ret = dbenv->txn_begin(nullptr, &ptxn, flags);
80  if (!ptxn || ret != 0)
81  return nullptr;
82  return ptxn;
83  }
84 };
85 
87 std::shared_ptr<BerkeleyEnvironment> GetBerkeleyEnv(const fs::path& env_directory, bool use_shared_memory);
88 
89 class BerkeleyBatch;
90 
95 {
96 public:
97  BerkeleyDatabase() = delete;
98 
100  BerkeleyDatabase(std::shared_ptr<BerkeleyEnvironment> env, fs::path filename, const DatabaseOptions& options) :
101  WalletDatabase(), env(std::move(env)), m_filename(std::move(filename)), m_max_log_mb(options.max_log_mb)
102  {
103  auto inserted = this->env->m_databases.emplace(m_filename, std::ref(*this));
104  assert(inserted.second);
105  }
106 
107  ~BerkeleyDatabase() override;
108 
110  void Open() override;
111 
114  bool Rewrite(const char* pszSkip=nullptr) override;
115 
117  void AddRef() override;
119  void RemoveRef() override;
120 
123  bool Backup(const std::string& strDest) const override;
124 
127  void Flush() override;
131  void Close() override;
132  /* flush the wallet passively (TRY_LOCK)
133  ideal to be called periodically */
134  bool PeriodicFlush() override;
135 
136  void IncrementUpdateCounter() override;
137 
138  void ReloadDbEnv() override;
139 
141  bool Verify(bilingual_str& error);
142 
144  std::string Filename() override { return fs::PathToString(env->Directory() / m_filename); }
145 
146  std::string Format() override { return "bdb"; }
156  std::shared_ptr<BerkeleyEnvironment> env;
157 
159  std::unique_ptr<Db> m_db;
160 
162  int64_t m_max_log_mb;
163 
165  std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override;
166 };
167 
169 class SafeDbt final
170 {
171  Dbt m_dbt;
172 
173 public:
174  // construct Dbt with internally-managed data
175  SafeDbt();
176  // construct Dbt with provided data
177  SafeDbt(void* data, size_t size);
178  ~SafeDbt();
179 
180  // delegate to Dbt
181  const void* get_data() const;
182  uint32_t get_size() const;
183 
184  // conversion operator to access the underlying Dbt
185  operator Dbt*();
186 };
187 
189 {
190 private:
191  Dbc* m_cursor;
192 
193 public:
194  explicit BerkeleyCursor(BerkeleyDatabase& database);
195  ~BerkeleyCursor() override;
196 
197  Status Next(DataStream& key, DataStream& value) override;
198 };
199 
202 {
203 private:
204  bool ReadKey(DataStream&& key, DataStream& value) override;
205  bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite = true) override;
206  bool EraseKey(DataStream&& key) override;
207  bool HasKey(DataStream&& key) override;
208 
209 protected:
210  Db* pdb;
211  std::string strFile;
212  DbTxn* activeTxn;
213  bool fReadOnly;
217 
218 public:
219  explicit BerkeleyBatch(BerkeleyDatabase& database, const bool fReadOnly, bool fFlushOnCloseIn=true);
220  ~BerkeleyBatch() override;
221 
222  BerkeleyBatch(const BerkeleyBatch&) = delete;
224 
225  void Flush() override;
226  void Close() override;
227 
228  std::unique_ptr<DatabaseCursor> GetNewCursor() override;
229  bool TxnBegin() override;
230  bool TxnCommit() override;
231  bool TxnAbort() override;
232 };
233 
234 std::string BerkeleyDatabaseVersion();
235 
239 
241 std::unique_ptr<BerkeleyDatabase> MakeBerkeleyDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
242 } // namespace wallet
243 
244 #endif // BITCOIN_WALLET_BDB_H
int ret
int flags
Definition: bitcoin-tx.cpp:525
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:186
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:31
RAII class that provides access to a Berkeley database.
Definition: bdb.h:202
bool fFlushOnClose
Definition: bdb.h:214
bool ReadKey(DataStream &&key, DataStream &value) override
Definition: bdb.cpp:756
void Close() override
Definition: bdb.cpp:394
bool HasKey(DataStream &&key) override
Definition: bdb.cpp:800
BerkeleyDatabase & m_database
Definition: bdb.h:216
bool EraseKey(DataStream &&key) override
Definition: bdb.cpp:787
BerkeleyBatch & operator=(const BerkeleyBatch &)=delete
~BerkeleyBatch() override
Definition: bdb.cpp:388
BerkeleyBatch(BerkeleyDatabase &database, const bool fReadOnly, bool fFlushOnCloseIn=true)
Definition: bdb.cpp:311
void Flush() override
Definition: bdb.cpp:368
bool TxnCommit() override
Definition: bdb.cpp:716
BerkeleyEnvironment * env
Definition: bdb.h:215
bool TxnAbort() override
Definition: bdb.cpp:725
std::unique_ptr< DatabaseCursor > GetNewCursor() override
Definition: bdb.cpp:699
BerkeleyBatch(const BerkeleyBatch &)=delete
std::string strFile
Definition: bdb.h:211
bool WriteKey(DataStream &&key, DataStream &&value, bool overwrite=true) override
Definition: bdb.cpp:772
DbTxn * activeTxn
Definition: bdb.h:212
bool TxnBegin() override
Definition: bdb.cpp:705
~BerkeleyCursor() override
Definition: bdb.cpp:692
BerkeleyCursor(BerkeleyDatabase &database)
Definition: bdb.cpp:659
Status Next(DataStream &key, DataStream &value) override
Definition: bdb.cpp:670
An instance of this class represents one database.
Definition: bdb.h:95
BerkeleyDatabase(std::shared_ptr< BerkeleyEnvironment > env, fs::path filename, const DatabaseOptions &options)
Create DB handle to real database.
Definition: bdb.h:100
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:449
void Open() override
Open the database if it is not already opened.
Definition: bdb.cpp:322
bool Backup(const std::string &strDest) const override
Back up the entire database to a file.
Definition: bdb.cpp:606
int64_t m_max_log_mb
Definition: bdb.h:162
fs::path m_filename
Definition: bdb.h:161
void RemoveRef() override
Indicate that database user has stopped using the database and that it could be flushed or closed.
Definition: bdb.cpp:821
std::string Format() override
Definition: bdb.h:146
std::shared_ptr< BerkeleyEnvironment > env
Pointer to shared database environment.
Definition: bdb.h:156
void IncrementUpdateCounter() override
Definition: bdb.cpp:383
void ReloadDbEnv() override
Definition: bdb.cpp:654
void AddRef() override
Indicate that a new database user has begun using the database.
Definition: bdb.cpp:811
std::string Filename() override
Return path to main database filename.
Definition: bdb.h:144
std::unique_ptr< Db > m_db
Database pointer.
Definition: bdb.h:159
void Flush() override
Make sure all changes are flushed to database file.
Definition: bdb.cpp:644
bool PeriodicFlush() override
Definition: bdb.cpp:578
std::unique_ptr< DatabaseBatch > MakeBatch(bool flush_on_close=true) override
Make a BerkeleyBatch connected to this database.
Definition: bdb.cpp:828
bool Verify(bilingual_str &error)
Verifies the environment and database file.
Definition: bdb.cpp:263
~BerkeleyDatabase() override
Definition: bdb.cpp:299
void Close() override
Flush to the database file and close the database.
Definition: bdb.cpp:649
fs::path Directory() const
Definition: bdb.h:66
std::condition_variable_any m_db_in_use
Definition: bdb.h:56
DbTxn * TxnBegin(int flags=DB_TXN_WRITE_NOSYNC)
Definition: bdb.h:76
void CloseDb(const fs::path &filename)
Definition: bdb.cpp:407
bool IsMock() const
Definition: bdb.h:64
std::unique_ptr< DbEnv > dbenv
Definition: bdb.h:53
BerkeleyEnvironment()
Construct an in-memory mock Berkeley environment for testing.
Definition: bdb.cpp:194
bool IsInitialized() const
Definition: bdb.h:65
void CheckpointLSN(const std::string &strFile)
Definition: bdb.cpp:291
std::unordered_map< std::string, WalletDatabaseFileId > m_fileids
Definition: bdb.h:55
void Flush(bool fShutdown)
Definition: bdb.cpp:534
std::string strPath
Definition: bdb.h:50
bool Open(bilingual_str &error)
Definition: bdb.cpp:130
std::map< fs::path, std::reference_wrapper< BerkeleyDatabase > > m_databases
Definition: bdb.h:54
RAII class that provides access to a WalletDatabase.
Definition: db.h:46
RAII class that automatically cleanses its data on destruction.
Definition: bdb.h:170
Dbt m_dbt
Definition: bdb.h:171
const void * get_data() const
Definition: bdb.cpp:248
uint32_t get_size() const
Definition: bdb.cpp:253
An instance of this class represents one database.
Definition: db.h:123
static std::string PathToString(const path &path)
Convert path object to a byte string.
Definition: fs.h:150
static path PathFromString(const std::string &string)
Convert byte string to path object.
Definition: fs.h:173
Definition: node.h:39
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:833
std::string BerkeleyDatabaseVersion()
Definition: bdb.cpp:751
std::shared_ptr< BerkeleyEnvironment > GetBerkeleyEnv(const fs::path &env_directory, bool use_shared_memory)
Get BerkeleyEnvironment given a directory path.
Definition: bdb.cpp:65
bool BerkeleyDatabaseSanityCheck()
Perform sanity check of runtime BDB version versus linked BDB version.
Definition: bdb.cpp:734
DatabaseStatus
Definition: db.h:239
Bilingual messages:
Definition: translation.h:18
bool operator==(const WalletDatabaseFileId &rhs) const
Definition: bdb.cpp:54
uint8_t value[DB_FILE_ID_LEN]
Definition: bdb.h:37
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
assert(!tx.IsCoinBase())