Bitcoin Core  24.99.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 
26 {
27 public:
28  explicit DatabaseCursor() {}
29  virtual ~DatabaseCursor() {}
30 
31  DatabaseCursor(const DatabaseCursor&) = delete;
33 
34  enum class Status
35  {
36  FAIL,
37  MORE,
38  DONE,
39  };
40 
41  virtual Status Next(DataStream& key, DataStream& value) { return Status::FAIL; }
42 };
43 
46 {
47 private:
48  virtual bool ReadKey(DataStream&& key, DataStream& value) = 0;
49  virtual bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite = true) = 0;
50  virtual bool EraseKey(DataStream&& key) = 0;
51  virtual bool HasKey(DataStream&& key) = 0;
52 
53 public:
54  explicit DatabaseBatch() {}
55  virtual ~DatabaseBatch() {}
56 
57  DatabaseBatch(const DatabaseBatch&) = delete;
59 
60  virtual void Flush() = 0;
61  virtual void Close() = 0;
62 
63  template <typename K, typename T>
64  bool Read(const K& key, T& value)
65  {
66  DataStream ssKey{};
67  ssKey.reserve(1000);
68  ssKey << key;
69 
71  if (!ReadKey(std::move(ssKey), ssValue)) return false;
72  try {
73  ssValue >> value;
74  return true;
75  } catch (const std::exception&) {
76  return false;
77  }
78  }
79 
80  template <typename K, typename T>
81  bool Write(const K& key, const T& value, bool fOverwrite = true)
82  {
83  DataStream ssKey{};
84  ssKey.reserve(1000);
85  ssKey << key;
86 
88  ssValue.reserve(10000);
89  ssValue << value;
90 
91  return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
92  }
93 
94  template <typename K>
95  bool Erase(const K& key)
96  {
97  DataStream ssKey{};
98  ssKey.reserve(1000);
99  ssKey << key;
100 
101  return EraseKey(std::move(ssKey));
102  }
103 
104  template <typename K>
105  bool Exists(const K& key)
106  {
107  DataStream ssKey{};
108  ssKey.reserve(1000);
109  ssKey << key;
110 
111  return HasKey(std::move(ssKey));
112  }
113 
114  virtual std::unique_ptr<DatabaseCursor> GetNewCursor() = 0;
115  virtual bool TxnBegin() = 0;
116  virtual bool TxnCommit() = 0;
117  virtual bool TxnAbort() = 0;
118 };
119 
123 {
124 public:
127  virtual ~WalletDatabase() {};
128 
130  virtual void Open() = 0;
131 
133  std::atomic<int> m_refcount{0};
135  virtual void AddRef() = 0;
137  virtual void RemoveRef() = 0;
138 
141  virtual bool Rewrite(const char* pszSkip=nullptr) = 0;
142 
145  virtual bool Backup(const std::string& strDest) const = 0;
146 
149  virtual void Flush() = 0;
153  virtual void Close() = 0;
154  /* flush the wallet passively (TRY_LOCK)
155  ideal to be called periodically */
156  virtual bool PeriodicFlush() = 0;
157 
158  virtual void IncrementUpdateCounter() = 0;
159 
160  virtual void ReloadDbEnv() = 0;
161 
163  virtual std::string Filename() = 0;
164 
165  virtual std::string Format() = 0;
166 
167  std::atomic<unsigned int> nUpdateCounter;
168  unsigned int nLastSeen{0};
169  unsigned int nLastFlushed{0};
170  int64_t nLastWalletUpdate{0};
171 
173  virtual std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) = 0;
174 };
175 
177 {
178  Status Next(DataStream& key, DataStream& value) override { return Status::FAIL; }
179 };
180 
182 class DummyBatch : public DatabaseBatch
183 {
184 private:
185  bool ReadKey(DataStream&& key, DataStream& value) override { return true; }
186  bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite = true) override { return true; }
187  bool EraseKey(DataStream&& key) override { return true; }
188  bool HasKey(DataStream&& key) override { return true; }
189 
190 public:
191  void Flush() override {}
192  void Close() override {}
193 
194  std::unique_ptr<DatabaseCursor> GetNewCursor() override { return std::make_unique<DummyCursor>(); }
195  bool TxnBegin() override { return true; }
196  bool TxnCommit() override { return true; }
197  bool TxnAbort() override { return true; }
198 };
199 
203 {
204 public:
205  void Open() override {};
206  void AddRef() override {}
207  void RemoveRef() override {}
208  bool Rewrite(const char* pszSkip=nullptr) override { return true; }
209  bool Backup(const std::string& strDest) const override { return true; }
210  void Close() override {}
211  void Flush() override {}
212  bool PeriodicFlush() override { return true; }
213  void IncrementUpdateCounter() override { ++nUpdateCounter; }
214  void ReloadDbEnv() override {}
215  std::string Filename() override { return "dummy"; }
216  std::string Format() override { return "dummy"; }
217  std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override { return std::make_unique<DummyBatch>(); }
218 };
219 
220 enum class DatabaseFormat {
221  BERKELEY,
222  SQLITE,
223 };
224 
226  bool require_existing = false;
227  bool require_create = false;
228  std::optional<DatabaseFormat> require_format;
229  uint64_t create_flags = 0;
231 
232  // Specialized options. Not every option is supported by every backend.
233  bool verify = true;
234  bool use_unsafe_sync = false;
235  bool use_shared_memory = false;
236  int64_t max_log_mb = 100;
237 };
238 
239 enum class DatabaseStatus {
240  SUCCESS,
247  FAILED_LOAD,
251 };
252 
254 std::vector<fs::path> ListDatabases(const fs::path& path);
255 
256 void ReadDatabaseArgs(const ArgsManager& args, DatabaseOptions& options);
257 std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
258 
259 fs::path BDBDataFile(const fs::path& path);
260 fs::path SQLiteDataFile(const fs::path& path);
261 bool IsBDBFile(const fs::path& path);
262 bool IsSQLiteFile(const fs::path& path);
263 } // namespace wallet
264 
265 #endif // BITCOIN_WALLET_DB_H
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:186
void reserve(size_type n)
Definition: streams.h:223
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 WalletDatabase.
Definition: db.h:46
bool Erase(const K &key)
Definition: db.h:95
bool Write(const K &key, const T &value, bool fOverwrite=true)
Definition: db.h:81
virtual bool TxnAbort()=0
DatabaseBatch(const DatabaseBatch &)=delete
virtual void Flush()=0
virtual void Close()=0
bool Read(const K &key, T &value)
Definition: db.h:64
virtual bool EraseKey(DataStream &&key)=0
virtual bool WriteKey(DataStream &&key, DataStream &&value, bool overwrite=true)=0
virtual bool TxnBegin()=0
virtual std::unique_ptr< DatabaseCursor > GetNewCursor()=0
DatabaseBatch & operator=(const DatabaseBatch &)=delete
virtual bool ReadKey(DataStream &&key, DataStream &value)=0
bool Exists(const K &key)
Definition: db.h:105
virtual bool HasKey(DataStream &&key)=0
virtual bool TxnCommit()=0
virtual ~DatabaseBatch()
Definition: db.h:55
DatabaseCursor & operator=(const DatabaseCursor &)=delete
virtual ~DatabaseCursor()
Definition: db.h:29
DatabaseCursor(const DatabaseCursor &)=delete
virtual Status Next(DataStream &key, DataStream &value)
Definition: db.h:41
RAII class that provides access to a DummyDatabase.
Definition: db.h:183
bool EraseKey(DataStream &&key) override
Definition: db.h:187
bool HasKey(DataStream &&key) override
Definition: db.h:188
std::unique_ptr< DatabaseCursor > GetNewCursor() override
Definition: db.h:194
bool TxnAbort() override
Definition: db.h:197
void Close() override
Definition: db.h:192
bool ReadKey(DataStream &&key, DataStream &value) override
Definition: db.h:185
bool TxnCommit() override
Definition: db.h:196
void Flush() override
Definition: db.h:191
bool WriteKey(DataStream &&key, DataStream &&value, bool overwrite=true) override
Definition: db.h:186
bool TxnBegin() override
Definition: db.h:195
Status Next(DataStream &key, DataStream &value) override
Definition: db.h:178
A dummy WalletDatabase that does nothing and never fails.
Definition: db.h:203
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:208
void AddRef() override
Indicate the a new database user has began using the database.
Definition: db.h:206
void ReloadDbEnv() override
Definition: db.h:214
bool PeriodicFlush() override
Definition: db.h:212
void IncrementUpdateCounter() override
Definition: db.h:213
void Flush() override
Make sure all changes are flushed to database file.
Definition: db.h:211
std::unique_ptr< DatabaseBatch > MakeBatch(bool flush_on_close=true) override
Make a DatabaseBatch connected to this database.
Definition: db.h:217
std::string Filename() override
Return path to main database file for logs and error messages.
Definition: db.h:215
void Open() override
Open the database if it is not already opened.
Definition: db.h:205
std::string Format() override
Definition: db.h:216
void RemoveRef() override
Indicate that database user has stopped using the database and that it could be flushed or closed.
Definition: db.h:207
bool Backup(const std::string &strDest) const override
Back up the entire database to a file.
Definition: db.h:209
void Close() override
Flush to the database file and close the database.
Definition: db.h:210
An instance of this class represents one database.
Definition: db.h:123
virtual bool PeriodicFlush()=0
virtual void AddRef()=0
Indicate the a new database user has began using the database.
virtual std::string Format()=0
virtual void IncrementUpdateCounter()=0
virtual void Open()=0
Open the database if it is not already opened.
int64_t nLastWalletUpdate
Definition: db.h:170
virtual bool Rewrite(const char *pszSkip=nullptr)=0
Rewrite the entire database on disk, with the exception of key pszSkip if non-zero.
virtual void ReloadDbEnv()=0
virtual std::unique_ptr< DatabaseBatch > MakeBatch(bool flush_on_close=true)=0
Make a DatabaseBatch connected to this database.
virtual void Close()=0
Flush to the database file and close the database.
virtual bool Backup(const std::string &strDest) const =0
Back up the entire database to a file.
std::atomic< unsigned int > nUpdateCounter
Definition: db.h:167
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:133
virtual void RemoveRef()=0
Indicate that database user has stopped using the database and that it could be flushed or closed.
virtual ~WalletDatabase()
Definition: db.h:127
unsigned int nLastFlushed
Definition: db.h:169
WalletDatabase()
Create dummy DB handle.
Definition: db.h:126
virtual std::string Filename()=0
Return path to main database file for logs and error messages.
unsigned int nLastSeen
Definition: db.h:168
virtual void Flush()=0
Make sure all changes are flushed to database file.
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: logging.h:261
Definition: node.h:39
void SplitWalletPath(const fs::path &wallet_path, fs::path &env_directory, std::string &database_filename)
void ReadDatabaseArgs(const ArgsManager &args, DatabaseOptions &options)
Definition: db.cpp:142
std::unique_ptr< WalletDatabase > MakeDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
Definition: walletdb.cpp:1156
fs::path SQLiteDataFile(const fs::path &path)
Definition: db.cpp:78
std::vector< fs::path > ListDatabases(const fs::path &wallet_dir)
Recursively list database paths in directory.
Definition: db.cpp:19
DatabaseFormat
Definition: db.h:220
bool IsBDBFile(const fs::path &path)
Definition: db.cpp:83
fs::path BDBDataFile(const fs::path &wallet_path)
Definition: db.cpp:64
bool IsSQLiteFile(const fs::path &path)
Definition: db.cpp:108
DatabaseStatus
Definition: db.h:239
ArgsManager args
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:60
@ SER_DISK
Definition: serialize.h:132
Bilingual messages:
Definition: translation.h:18
bool require_existing
Definition: db.h:226
bool verify
Check data integrity on load.
Definition: db.h:233
bool use_shared_memory
Let other processes access the database.
Definition: db.h:235
SecureString create_passphrase
Definition: db.h:230
std::optional< DatabaseFormat > require_format
Definition: db.h:228
bool use_unsafe_sync
Disable file sync for faster performance.
Definition: db.h:234
int64_t max_log_mb
Max log size to allow before consolidating.
Definition: db.h:236
uint64_t create_flags
Definition: db.h:229