Bitcoin Core  24.1.0
P2P Digital Currency
db.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_DB_H
7 #define BITCOIN_WALLET_DB_H
8 
9 #include <clientversion.h>
10 #include <fs.h>
11 #include <streams.h>
13 
14 #include <atomic>
15 #include <memory>
16 #include <optional>
17 #include <string>
18 
19 class ArgsManager;
20 struct bilingual_str;
21 
22 namespace wallet {
23 void SplitWalletPath(const fs::path& wallet_path, fs::path& env_directory, std::string& database_filename);
24 
27 {
28 private:
29  virtual bool ReadKey(CDataStream&& key, CDataStream& value) = 0;
30  virtual bool WriteKey(CDataStream&& key, CDataStream&& value, bool overwrite=true) = 0;
31  virtual bool EraseKey(CDataStream&& key) = 0;
32  virtual bool HasKey(CDataStream&& key) = 0;
33 
34 public:
35  explicit DatabaseBatch() {}
36  virtual ~DatabaseBatch() {}
37 
38  DatabaseBatch(const DatabaseBatch&) = delete;
39  DatabaseBatch& operator=(const DatabaseBatch&) = delete;
40 
41  virtual void Flush() = 0;
42  virtual void Close() = 0;
43 
44  template <typename K, typename T>
45  bool Read(const K& key, T& value)
46  {
48  ssKey.reserve(1000);
49  ssKey << key;
50 
52  if (!ReadKey(std::move(ssKey), ssValue)) return false;
53  try {
54  ssValue >> value;
55  return true;
56  } catch (const std::exception&) {
57  return false;
58  }
59  }
60 
61  template <typename K, typename T>
62  bool Write(const K& key, const T& value, bool fOverwrite = true)
63  {
65  ssKey.reserve(1000);
66  ssKey << key;
67 
69  ssValue.reserve(10000);
70  ssValue << value;
71 
72  return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
73  }
74 
75  template <typename K>
76  bool Erase(const K& key)
77  {
79  ssKey.reserve(1000);
80  ssKey << key;
81 
82  return EraseKey(std::move(ssKey));
83  }
84 
85  template <typename K>
86  bool Exists(const K& key)
87  {
89  ssKey.reserve(1000);
90  ssKey << key;
91 
92  return HasKey(std::move(ssKey));
93  }
94 
95  virtual bool StartCursor() = 0;
96  virtual bool ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete) = 0;
97  virtual void CloseCursor() = 0;
98  virtual bool TxnBegin() = 0;
99  virtual bool TxnCommit() = 0;
100  virtual bool TxnAbort() = 0;
101 };
102 
106 {
107 public:
110  virtual ~WalletDatabase() {};
111 
113  virtual void Open() = 0;
114 
116  std::atomic<int> m_refcount{0};
118  virtual void AddRef() = 0;
120  virtual void RemoveRef() = 0;
121 
124  virtual bool Rewrite(const char* pszSkip=nullptr) = 0;
125 
128  virtual bool Backup(const std::string& strDest) const = 0;
129 
132  virtual void Flush() = 0;
136  virtual void Close() = 0;
137  /* flush the wallet passively (TRY_LOCK)
138  ideal to be called periodically */
139  virtual bool PeriodicFlush() = 0;
140 
141  virtual void IncrementUpdateCounter() = 0;
142 
143  virtual void ReloadDbEnv() = 0;
144 
146  virtual std::string Filename() = 0;
147 
148  virtual std::string Format() = 0;
149 
150  std::atomic<unsigned int> nUpdateCounter;
151  unsigned int nLastSeen;
152  unsigned int nLastFlushed;
154 
156  virtual std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) = 0;
157 };
158 
160 class DummyBatch : public DatabaseBatch
161 {
162 private:
163  bool ReadKey(CDataStream&& key, CDataStream& value) override { return true; }
164  bool WriteKey(CDataStream&& key, CDataStream&& value, bool overwrite=true) override { return true; }
165  bool EraseKey(CDataStream&& key) override { return true; }
166  bool HasKey(CDataStream&& key) override { return true; }
167 
168 public:
169  void Flush() override {}
170  void Close() override {}
171 
172  bool StartCursor() override { return true; }
173  bool ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete) override { return true; }
174  void CloseCursor() override {}
175  bool TxnBegin() override { return true; }
176  bool TxnCommit() override { return true; }
177  bool TxnAbort() override { return true; }
178 };
179 
183 {
184 public:
185  void Open() override {};
186  void AddRef() override {}
187  void RemoveRef() override {}
188  bool Rewrite(const char* pszSkip=nullptr) override { return true; }
189  bool Backup(const std::string& strDest) const override { return true; }
190  void Close() override {}
191  void Flush() override {}
192  bool PeriodicFlush() override { return true; }
193  void IncrementUpdateCounter() override { ++nUpdateCounter; }
194  void ReloadDbEnv() override {}
195  std::string Filename() override { return "dummy"; }
196  std::string Format() override { return "dummy"; }
197  std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override { return std::make_unique<DummyBatch>(); }
198 };
199 
200 enum class DatabaseFormat {
201  BERKELEY,
202  SQLITE,
203 };
204 
206  bool require_existing = false;
207  bool require_create = false;
208  std::optional<DatabaseFormat> require_format;
209  uint64_t create_flags = 0;
211 
212  // Specialized options. Not every option is supported by every backend.
213  bool verify = true;
214  bool use_unsafe_sync = false;
215  bool use_shared_memory = false;
216  int64_t max_log_mb = 100;
217 };
218 
219 enum class DatabaseStatus {
220  SUCCESS,
227  FAILED_LOAD,
231 };
232 
234 std::vector<fs::path> ListDatabases(const fs::path& path);
235 
236 void ReadDatabaseArgs(const ArgsManager& args, DatabaseOptions& options);
237 std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
238 
239 fs::path BDBDataFile(const fs::path& path);
240 fs::path SQLiteDataFile(const fs::path& path);
241 bool IsBDBFile(const fs::path& path);
242 bool IsSQLiteFile(const fs::path& path);
243 } // namespace wallet
244 
245 #endif // BITCOIN_WALLET_DB_H
std::unique_ptr< WalletDatabase > MakeDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
Definition: walletdb.cpp:1156
std::optional< DatabaseFormat > require_format
Definition: db.h:208
void ReadDatabaseArgs(const ArgsManager &args, DatabaseOptions &options)
Definition: db.cpp:142
bool Backup(const std::string &strDest) const override
Back up the entire database to a file.
Definition: db.h:189
virtual bool Backup(const std::string &strDest) const =0
Back up the entire database to a file.
virtual bool TxnAbort()=0
virtual bool WriteKey(CDataStream &&key, CDataStream &&value, bool overwrite=true)=0
Bilingual messages:
Definition: translation.h:18
virtual void CloseCursor()=0
virtual void Flush()=0
Make sure all changes are flushed to database file.
bool use_unsafe_sync
Disable file sync for faster performance.
Definition: db.h:214
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:59
virtual void Open()=0
Open the database if it is not already opened.
void Close() override
Flush to the database file and close the database.
Definition: db.h:190
WalletDatabase()
Create dummy DB handle.
Definition: db.h:109
virtual void Close()=0
Flush to the database file and close the database.
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:185
std::string Filename() override
Return path to main database file for logs and error messages.
Definition: db.h:195
bool Write(const K &key, const T &value, bool fOverwrite=true)
Definition: db.h:62
std::atomic< unsigned int > nUpdateCounter
Definition: db.h:150
virtual bool Rewrite(const char *pszSkip=nullptr)=0
Rewrite the entire database on disk, with the exception of key pszSkip if non-zero.
std::unique_ptr< DatabaseBatch > MakeBatch(bool flush_on_close=true) override
Make a DatabaseBatch connected to this database.
Definition: db.h:197
RAII class that provides access to a WalletDatabase.
Definition: db.h:26
bool TxnCommit() override
Definition: db.h:176
ArgsManager args
fs::path SQLiteDataFile(const fs::path &path)
Definition: db.cpp:78
virtual bool TxnBegin()=0
virtual void RemoveRef()=0
Indicate that database user has stopped using the database and that it could be flushed or closed...
int64_t nLastWalletUpdate
Definition: db.h:153
bool PeriodicFlush() override
Definition: db.h:192
virtual bool ReadKey(CDataStream &&key, CDataStream &value)=0
std::atomic< int > m_refcount
Counts the number of active database users to be sure that the database is not closed while someone i...
Definition: db.h:116
bool Read(const K &key, T &value)
Definition: db.h:45
SecureString create_passphrase
Definition: db.h:210
bool IsBDBFile(const fs::path &path)
Definition: db.cpp:83
virtual bool EraseKey(CDataStream &&key)=0
uint64_t create_flags
Definition: db.h:209
bool Exists(const K &key)
Definition: db.h:86
bool StartCursor() override
Definition: db.h:172
bool ReadKey(CDataStream &&key, CDataStream &value) override
Definition: db.h:163
bool TxnAbort() override
Definition: db.h:177
unsigned int nLastFlushed
Definition: db.h:152
virtual std::string Filename()=0
Return path to main database file for logs and error messages.
virtual void ReloadDbEnv()=0
RAII class that provides access to a DummyDatabase.
Definition: db.h:160
virtual void IncrementUpdateCounter()=0
virtual bool StartCursor()=0
virtual void AddRef()=0
Indicate the a new database user has began using the database.
void Flush() override
Make sure all changes are flushed to database file.
Definition: db.h:191
virtual ~WalletDatabase()
Definition: db.h:110
bool EraseKey(CDataStream &&key) override
Definition: db.h:165
void ReloadDbEnv() override
Definition: db.h:194
void IncrementUpdateCounter() override
Definition: db.h:193
bool Erase(const K &key)
Definition: db.h:76
virtual bool TxnCommit()=0
Definition: node.h:39
virtual bool PeriodicFlush()=0
void Flush() override
Definition: db.h:169
bool use_shared_memory
Let other processes access the database.
Definition: db.h:215
void AddRef() override
Indicate the a new database user has began using the database.
Definition: db.h:186
virtual bool HasKey(CDataStream &&key)=0
DatabaseStatus
Definition: db.h:219
A dummy WalletDatabase that does nothing and never fails.
Definition: db.h:182
int64_t max_log_mb
Max log size to allow before consolidating.
Definition: db.h:216
void CloseCursor() override
Definition: db.h:174
void reserve(size_type n)
Definition: streams.h:240
DatabaseFormat
Definition: db.h:200
fs::path BDBDataFile(const fs::path &wallet_path)
Definition: db.cpp:64
virtual void Close()=0
bool IsSQLiteFile(const fs::path &path)
Definition: db.cpp:108
bool require_existing
Definition: db.h:206
bool TxnBegin() override
Definition: db.h:175
virtual bool ReadAtCursor(CDataStream &ssKey, CDataStream &ssValue, bool &complete)=0
virtual std::unique_ptr< DatabaseBatch > MakeBatch(bool flush_on_close=true)=0
Make a DatabaseBatch connected to this database.
bool Rewrite(const char *pszSkip=nullptr) override
Rewrite the entire database on disk, with the exception of key pszSkip if non-zero.
Definition: db.h:188
bool HasKey(CDataStream &&key) override
Definition: db.h:166
void SplitWalletPath(const fs::path &wallet_path, fs::path &env_directory, std::string &database_filename)
std::vector< fs::path > ListDatabases(const fs::path &wallet_dir)
Recursively list database paths in directory.
Definition: db.cpp:19
std::string Format() override
Definition: db.h:196
virtual std::string Format()=0
virtual void Flush()=0
void RemoveRef() override
Indicate that database user has stopped using the database and that it could be flushed or closed...
Definition: db.h:187
bool WriteKey(CDataStream &&key, CDataStream &&value, bool overwrite=true) override
Definition: db.h:164
void Close() override
Definition: db.h:170
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:30
bool verify
Check data integrity on load.
Definition: db.h:213
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:33
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
DatabaseBatch & operator=(const DatabaseBatch &)=delete
virtual ~DatabaseBatch()
Definition: db.h:36
unsigned int nLastSeen
Definition: db.h:151
An instance of this class represents one database.
Definition: db.h:105
bool ReadAtCursor(CDataStream &ssKey, CDataStream &ssValue, bool &complete) override
Definition: db.h:173
void Open() override
Open the database if it is not already opened.
Definition: db.h:185