Bitcoin Core  0.20.99
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 <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 static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100;
35 static const bool DEFAULT_WALLET_PRIVDB = true;
36 
38  u_int8_t value[DB_FILE_ID_LEN];
39  bool operator==(const WalletDatabaseFileId& rhs) const;
40 };
41 
42 class BerkeleyDatabase;
43 
45 {
46 private:
47  bool fDbEnvInit;
48  bool fMockDb;
49  // Don't change into fs::path, as that can result in
50  // shutdown problems/crashes caused by a static initialized internal pointer.
51  std::string strPath;
52 
53 public:
54  std::unique_ptr<DbEnv> dbenv;
55  std::map<std::string, std::reference_wrapper<BerkeleyDatabase>> m_databases;
56  std::unordered_map<std::string, WalletDatabaseFileId> m_fileids;
57  std::condition_variable_any m_db_in_use;
58 
59  BerkeleyEnvironment(const fs::path& env_directory);
62  void Reset();
63 
64  bool IsMock() const { return fMockDb; }
65  bool IsInitialized() const { return fDbEnvInit; }
66  fs::path Directory() const { return strPath; }
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 std::string& strFile);
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> GetWalletEnv(const fs::path& wallet_path, std::string& database_filename);
88 
90 bool IsBDBFile(const fs::path& path);
91 
92 class BerkeleyBatch;
93 
98 {
99 public:
100  BerkeleyDatabase() = delete;
101 
103  BerkeleyDatabase(std::shared_ptr<BerkeleyEnvironment> env, std::string filename) :
104  WalletDatabase(), env(std::move(env)), strFile(std::move(filename))
105  {
106  auto inserted = this->env->m_databases.emplace(strFile, std::ref(*this));
107  assert(inserted.second);
108  }
109 
110  ~BerkeleyDatabase() override;
111 
113  void Open() override;
114 
117  bool Rewrite(const char* pszSkip=nullptr) override;
118 
120  void AddRef() override;
122  void RemoveRef() override;
123 
126  bool Backup(const std::string& strDest) const override;
127 
130  void Flush() override;
134  void Close() override;
135  /* flush the wallet passively (TRY_LOCK)
136  ideal to be called periodically */
137  bool PeriodicFlush() override;
138 
139  void IncrementUpdateCounter() override;
140 
141  void ReloadDbEnv() override;
142 
144  bool Verify(bilingual_str& error);
145 
147  std::string Filename() override { return (env->Directory() / strFile).string(); }
148 
149  std::string Format() override { return "bdb"; }
159  std::shared_ptr<BerkeleyEnvironment> env;
160 
162  std::unique_ptr<Db> m_db;
163 
164  std::string strFile;
165 
167  std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override;
168 };
169 
172 {
174  class SafeDbt final
175  {
176  Dbt m_dbt;
177 
178  public:
179  // construct Dbt with internally-managed data
180  SafeDbt();
181  // construct Dbt with provided data
182  SafeDbt(void* data, size_t size);
183  ~SafeDbt();
184 
185  // delegate to Dbt
186  const void* get_data() const;
187  u_int32_t get_size() const;
188 
189  // conversion operator to access the underlying Dbt
190  operator Dbt*();
191  };
192 
193 private:
194  bool ReadKey(CDataStream&& key, CDataStream& value) override;
195  bool WriteKey(CDataStream&& key, CDataStream&& value, bool overwrite = true) override;
196  bool EraseKey(CDataStream&& key) override;
197  bool HasKey(CDataStream&& key) override;
198 
199 protected:
200  Db* pdb;
201  std::string strFile;
202  DbTxn* activeTxn;
203  Dbc* m_cursor;
204  bool fReadOnly;
208 
209 public:
210  explicit BerkeleyBatch(BerkeleyDatabase& database, const bool fReadOnly, bool fFlushOnCloseIn=true);
211  ~BerkeleyBatch() override;
212 
213  BerkeleyBatch(const BerkeleyBatch&) = delete;
214  BerkeleyBatch& operator=(const BerkeleyBatch&) = delete;
215 
216  void Flush() override;
217  void Close() override;
218 
219  bool StartCursor() override;
220  bool ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete) override;
221  void CloseCursor() override;
222  bool TxnBegin() override;
223  bool TxnCommit() override;
224  bool TxnAbort() override;
225 };
226 
227 std::string BerkeleyDatabaseVersion();
228 
230 bool ExistsBerkeleyDatabase(const fs::path& path);
231 
233 std::unique_ptr<BerkeleyDatabase> MakeBerkeleyDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
234 
235 #endif // BITCOIN_WALLET_BDB_H
bool ExistsBerkeleyDatabase(const fs::path &path)
Check if Berkeley database exists at specified path.
Definition: bdb.cpp:811
bool fReadOnly
Definition: bdb.h:204
bool IsInitialized() const
Definition: bdb.h:65
bool fDbEnvInit
Definition: bdb.h:47
std::unordered_map< std::string, WalletDatabaseFileId > m_fileids
Definition: bdb.h:56
Bilingual messages:
Definition: translation.h:16
bool fFlushOnClose
Definition: bdb.h:205
BerkeleyDatabase & m_database
Definition: bdb.h:207
An instance of this class represents one database.
Definition: bdb.h:97
bool IsBDBFile(const fs::path &path)
Check format of database file.
Definition: bdb.cpp:843
static const unsigned int DEFAULT_WALLET_DBLOGSIZE
Definition: bdb.h:34
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:202
static const bool DEFAULT_WALLET_PRIVDB
Definition: bdb.h:35
fs::path Directory() const
Definition: bdb.h:66
std::string Format() override
Definition: bdb.h:149
DbTxn * TxnBegin(int flags=DB_TXN_WRITE_NOSYNC)
Definition: bdb.h:76
std::shared_ptr< BerkeleyEnvironment > env
Pointer to shared database environment.
Definition: bdb.h:159
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:62
std::map< std::string, std::reference_wrapper< BerkeleyDatabase > > m_databases
Definition: bdb.h:55
std::unique_ptr< DbEnv > dbenv
Definition: bdb.h:54
BerkeleyDatabase(std::shared_ptr< BerkeleyEnvironment > env, std::string filename)
Create DB handle to real database.
Definition: bdb.h:103
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:819
std::string strFile
Definition: bdb.h:201
RAII class that provides access to a WalletDatabase.
Definition: db.h:25
DbTxn * activeTxn
Definition: bdb.h:202
RAII class that provides access to a Berkeley database.
Definition: bdb.h:171
std::string strFile
Definition: bdb.h:164
bool operator==(const WalletDatabaseFileId &rhs) const
Definition: bdb.cpp:50
int flags
Definition: bitcoin-tx.cpp:506
Dbc * m_cursor
Definition: bdb.h:203
std::string strPath
Definition: bdb.h:51
std::string Filename() override
Return path to main database filename.
Definition: bdb.h:147
BerkeleyEnvironment * env
Definition: bdb.h:206
u_int8_t value[DB_FILE_ID_LEN]
Definition: bdb.h:38
Db * pdb
Definition: bdb.h:200
std::string BerkeleyDatabaseVersion()
Definition: bdb.cpp:729
bool IsMock() const
Definition: bdb.h:64
DatabaseStatus
Definition: db.h:213
bool fMockDb
Definition: bdb.h:48
std::unique_ptr< Db > m_db
Database pointer.
Definition: bdb.h:162
bool error(const char *fmt, const Args &... args)
Definition: system.h:52
RAII class that automatically cleanses its data on destruction.
Definition: bdb.h:174
An instance of this class represents one database.
Definition: db.h:104
std::condition_variable_any m_db_in_use
Definition: bdb.h:57