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