Bitcoin Core  21.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-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_DB_H
7 #define BITCOIN_WALLET_DB_H
8 
9 #include <clientversion.h>
10 #include <fs.h>
11 #include <optional.h>
12 #include <streams.h>
14 #include <util/memory.h>
15 
16 #include <atomic>
17 #include <memory>
18 #include <string>
19 
20 struct bilingual_str;
21 
22 void SplitWalletPath(const fs::path& wallet_path, fs::path& env_directory, std::string& database_filename);
23 
26 {
27 private:
28  virtual bool ReadKey(CDataStream&& key, CDataStream& value) = 0;
29  virtual bool WriteKey(CDataStream&& key, CDataStream&& value, bool overwrite=true) = 0;
30  virtual bool EraseKey(CDataStream&& key) = 0;
31  virtual bool HasKey(CDataStream&& key) = 0;
32 
33 public:
34  explicit DatabaseBatch() {}
35  virtual ~DatabaseBatch() {}
36 
37  DatabaseBatch(const DatabaseBatch&) = delete;
38  DatabaseBatch& operator=(const DatabaseBatch&) = delete;
39 
40  virtual void Flush() = 0;
41  virtual void Close() = 0;
42 
43  template <typename K, typename T>
44  bool Read(const K& key, T& value)
45  {
47  ssKey.reserve(1000);
48  ssKey << key;
49 
51  if (!ReadKey(std::move(ssKey), ssValue)) return false;
52  try {
53  ssValue >> value;
54  return true;
55  } catch (const std::exception&) {
56  return false;
57  }
58  }
59 
60  template <typename K, typename T>
61  bool Write(const K& key, const T& value, bool fOverwrite = true)
62  {
64  ssKey.reserve(1000);
65  ssKey << key;
66 
68  ssValue.reserve(10000);
69  ssValue << value;
70 
71  return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
72  }
73 
74  template <typename K>
75  bool Erase(const K& key)
76  {
78  ssKey.reserve(1000);
79  ssKey << key;
80 
81  return EraseKey(std::move(ssKey));
82  }
83 
84  template <typename K>
85  bool Exists(const K& key)
86  {
88  ssKey.reserve(1000);
89  ssKey << key;
90 
91  return HasKey(std::move(ssKey));
92  }
93 
94  virtual bool StartCursor() = 0;
95  virtual bool ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete) = 0;
96  virtual void CloseCursor() = 0;
97  virtual bool TxnBegin() = 0;
98  virtual bool TxnCommit() = 0;
99  virtual bool TxnAbort() = 0;
100 };
101 
105 {
106 public:
108  WalletDatabase() : nUpdateCounter(0), nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0) {}
109  virtual ~WalletDatabase() {};
110 
112  virtual void Open() = 0;
113 
115  std::atomic<int> m_refcount{0};
117  virtual void AddRef() = 0;
119  virtual void RemoveRef() = 0;
120 
123  virtual bool Rewrite(const char* pszSkip=nullptr) = 0;
124 
127  virtual bool Backup(const std::string& strDest) const = 0;
128 
131  virtual void Flush() = 0;
135  virtual void Close() = 0;
136  /* flush the wallet passively (TRY_LOCK)
137  ideal to be called periodically */
138  virtual bool PeriodicFlush() = 0;
139 
140  virtual void IncrementUpdateCounter() = 0;
141 
142  virtual void ReloadDbEnv() = 0;
143 
145  virtual std::string Filename() = 0;
146 
147  virtual std::string Format() = 0;
148 
149  std::atomic<unsigned int> nUpdateCounter;
150  unsigned int nLastSeen;
151  unsigned int nLastFlushed;
153 
155  virtual std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) = 0;
156 };
157 
159 class DummyBatch : public DatabaseBatch
160 {
161 private:
162  bool ReadKey(CDataStream&& key, CDataStream& value) override { return true; }
163  bool WriteKey(CDataStream&& key, CDataStream&& value, bool overwrite=true) override { return true; }
164  bool EraseKey(CDataStream&& key) override { return true; }
165  bool HasKey(CDataStream&& key) override { return true; }
166 
167 public:
168  void Flush() override {}
169  void Close() override {}
170 
171  bool StartCursor() override { return true; }
172  bool ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete) override { return true; }
173  void CloseCursor() override {}
174  bool TxnBegin() override { return true; }
175  bool TxnCommit() override { return true; }
176  bool TxnAbort() override { return true; }
177 };
178 
182 {
183 public:
184  void Open() override {};
185  void AddRef() override {}
186  void RemoveRef() override {}
187  bool Rewrite(const char* pszSkip=nullptr) override { return true; }
188  bool Backup(const std::string& strDest) const override { return true; }
189  void Close() override {}
190  void Flush() override {}
191  bool PeriodicFlush() override { return true; }
192  void IncrementUpdateCounter() override { ++nUpdateCounter; }
193  void ReloadDbEnv() override {}
194  std::string Filename() override { return "dummy"; }
195  std::string Format() override { return "dummy"; }
196  std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override { return MakeUnique<DummyBatch>(); }
197 };
198 
199 enum class DatabaseFormat {
200  BERKELEY,
201  SQLITE,
202 };
203 
205  bool require_existing = false;
206  bool require_create = false;
208  uint64_t create_flags = 0;
210  bool verify = true;
211 };
212 
213 enum class DatabaseStatus {
214  SUCCESS,
221  FAILED_LOAD,
224 };
225 
227 std::vector<fs::path> ListDatabases(const fs::path& path);
228 
229 std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
230 
231 fs::path BDBDataFile(const fs::path& path);
232 fs::path SQLiteDataFile(const fs::path& path);
233 bool IsBDBFile(const fs::path& path);
234 bool IsSQLiteFile(const fs::path& path);
235 
236 #endif // BITCOIN_WALLET_DB_H
int64_t nLastWalletUpdate
Definition: db.h:152
WalletDatabase()
Create dummy DB handle.
Definition: db.h:108
virtual bool ReadKey(CDataStream &&key, CDataStream &value)=0
virtual bool HasKey(CDataStream &&key)=0
bool HasKey(CDataStream &&key) override
Definition: db.h:165
std::string Format() override
Definition: db.h:195
void RemoveRef() override
Indicate that database user has stopped using the database and that it could be flushed or closed...
Definition: db.h:186
Bilingual messages:
Definition: translation.h:16
bool IsSQLiteFile(const fs::path &path)
Definition: db.cpp:100
bool Erase(const K &key)
Definition: db.h:75
virtual bool TxnAbort()=0
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:60
virtual bool TxnBegin()=0
fs::path BDBDataFile(const fs::path &path)
Definition: db.cpp:56
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:202
virtual ~DatabaseBatch()
Definition: db.h:35
virtual bool EraseKey(CDataStream &&key)=0
bool TxnBegin() override
Definition: db.h:174
std::vector< fs::path > ListDatabases(const fs::path &path)
Recursively list database paths in directory.
Definition: db.cpp:13
unsigned int nLastSeen
Definition: db.h:150
void SplitWalletPath(const fs::path &wallet_path, fs::path &env_directory, std::string &database_filename)
bool Write(const K &key, const T &value, bool fOverwrite=true)
Definition: db.h:61
virtual void Flush()=0
bool StartCursor() override
Definition: db.h:171
void Close() override
Definition: db.h:169
bool ReadAtCursor(CDataStream &ssKey, CDataStream &ssValue, bool &complete) override
Definition: db.h:172
DatabaseBatch & operator=(const DatabaseBatch &)=delete
void CloseCursor() override
Definition: db.h:173
bool PeriodicFlush() override
Definition: db.h:191
fs::path SQLiteDataFile(const fs::path &path)
Definition: db.cpp:70
virtual bool ReadAtCursor(CDataStream &ssKey, CDataStream &ssValue, bool &complete)=0
bool Read(const K &key, T &value)
Definition: db.h:44
RAII class that provides access to a WalletDatabase.
Definition: db.h:25
void Close() override
Flush to the database file and close the database.
Definition: db.h:189
void AddRef() override
Indicate the a new database user has began using the database.
Definition: db.h:185
A dummy WalletDatabase that does nothing and never fails.
Definition: db.h:181
bool WriteKey(CDataStream &&key, CDataStream &&value, bool overwrite=true) override
Definition: db.h:163
virtual void Close()=0
void ReloadDbEnv() override
Definition: db.h:193
DatabaseBatch()
Definition: db.h:34
virtual void CloseCursor()=0
std::unique_ptr< DatabaseBatch > MakeBatch(bool flush_on_close=true) override
Make a DatabaseBatch connected to this database.
Definition: db.h:196
void Flush() override
Make sure all changes are flushed to database file.
Definition: db.h:190
void Flush() override
Definition: db.h:168
bool IsBDBFile(const fs::path &path)
Definition: db.cpp:75
bool EraseKey(CDataStream &&key) override
Definition: db.h:164
void IncrementUpdateCounter() override
Definition: db.h:192
void reserve(size_type n)
Definition: streams.h:296
std::atomic< unsigned int > nUpdateCounter
Definition: db.h:149
virtual bool TxnCommit()=0
unsigned int nLastFlushed
Definition: db.h:151
bool TxnAbort() override
Definition: db.h:176
virtual bool StartCursor()=0
virtual ~WalletDatabase()
Definition: db.h:109
bool TxnCommit() override
Definition: db.h:175
SecureString create_passphrase
Definition: db.h:209
virtual bool WriteKey(CDataStream &&key, CDataStream &&value, bool overwrite=true)=0
std::string Filename() override
Return path to main database file for logs and error messages.
Definition: db.h:194
Optional< DatabaseFormat > require_format
Definition: db.h:207
RAII class that provides access to a DummyDatabase.
Definition: db.h:159
bool Exists(const K &key)
Definition: db.h:85
bool ReadKey(CDataStream &&key, CDataStream &value) override
Definition: db.h:162
DatabaseStatus
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:38
DatabaseFormat
Definition: db.h:199
bool error(const char *fmt, const Args &... args)
Definition: system.h:52
std::unique_ptr< WalletDatabase > MakeDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
Definition: walletdb.cpp:1003
void Open() override
Open the database if it is not already opened.
Definition: db.h:184
std::optional< T > Optional
Substitute for C++17 std::optional DEPRECATED use std::optional in new code.
Definition: optional.h:14
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:187
bool Backup(const std::string &strDest) const override
Back up the entire database to a file.
Definition: db.h:188
An instance of this class represents one database.
Definition: db.h:104