Bitcoin Core  26.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 <streams.h>
12 #include <util/fs.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;
32  DatabaseCursor& operator=(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;
58  DatabaseBatch& operator=(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  virtual bool ErasePrefix(Span<const std::byte> prefix) = 0;
114 
115  virtual std::unique_ptr<DatabaseCursor> GetNewCursor() = 0;
116  virtual std::unique_ptr<DatabaseCursor> GetNewPrefixCursor(Span<const std::byte> prefix) = 0;
117  virtual bool TxnBegin() = 0;
118  virtual bool TxnCommit() = 0;
119  virtual bool TxnAbort() = 0;
120 };
121 
125 {
126 public:
129  virtual ~WalletDatabase() {};
130 
132  virtual void Open() = 0;
133 
135  std::atomic<int> m_refcount{0};
137  virtual void AddRef() = 0;
139  virtual void RemoveRef() = 0;
140 
143  virtual bool Rewrite(const char* pszSkip=nullptr) = 0;
144 
147  virtual bool Backup(const std::string& strDest) const = 0;
148 
151  virtual void Flush() = 0;
155  virtual void Close() = 0;
156  /* flush the wallet passively (TRY_LOCK)
157  ideal to be called periodically */
158  virtual bool PeriodicFlush() = 0;
159 
160  virtual void IncrementUpdateCounter() = 0;
161 
162  virtual void ReloadDbEnv() = 0;
163 
165  virtual std::string Filename() = 0;
166 
167  virtual std::string Format() = 0;
168 
169  std::atomic<unsigned int> nUpdateCounter;
170  unsigned int nLastSeen{0};
171  unsigned int nLastFlushed{0};
172  int64_t nLastWalletUpdate{0};
173 
175  virtual std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) = 0;
176 };
177 
178 enum class DatabaseFormat {
179  BERKELEY,
180  SQLITE,
181 };
182 
184  bool require_existing = false;
185  bool require_create = false;
186  std::optional<DatabaseFormat> require_format;
187  uint64_t create_flags = 0;
189 
190  // Specialized options. Not every option is supported by every backend.
191  bool verify = true;
192  bool use_unsafe_sync = false;
193  bool use_shared_memory = false;
194  int64_t max_log_mb = 100;
195 };
196 
197 enum class DatabaseStatus {
198  SUCCESS,
205  FAILED_LOAD,
209 };
210 
212 std::vector<fs::path> ListDatabases(const fs::path& path);
213 
214 void ReadDatabaseArgs(const ArgsManager& args, DatabaseOptions& options);
215 std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
216 
217 fs::path BDBDataFile(const fs::path& path);
218 fs::path SQLiteDataFile(const fs::path& path);
219 bool IsBDBFile(const fs::path& path);
220 bool IsSQLiteFile(const fs::path& path);
221 } // namespace wallet
222 
223 #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:1437
std::optional< DatabaseFormat > require_format
Definition: db.h:186
void ReadDatabaseArgs(const ArgsManager &args, DatabaseOptions &options)
Definition: db.cpp:142
virtual std::unique_ptr< DatabaseCursor > GetNewCursor()=0
void reserve(size_type n)
Definition: streams.h:230
virtual bool HasKey(DataStream &&key)=0
virtual bool Backup(const std::string &strDest) const =0
Back up the entire database to a file.
virtual bool TxnAbort()=0
Bilingual messages:
Definition: translation.h:18
virtual void Flush()=0
Make sure all changes are flushed to database file.
const char * prefix
Definition: rest.cpp:1004
bool use_unsafe_sync
Disable file sync for faster performance.
Definition: db.h:192
virtual bool ErasePrefix(Span< const std::byte > prefix)=0
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:58
virtual void Open()=0
Open the database if it is not already opened.
virtual std::unique_ptr< DatabaseCursor > GetNewPrefixCursor(Span< const std::byte > prefix)=0
WalletDatabase()
Create dummy DB handle.
Definition: db.h:128
virtual void Close()=0
Flush to the database file and close the database.
bool Write(const K &key, const T &value, bool fOverwrite=true)
Definition: db.h:81
std::atomic< unsigned int > nUpdateCounter
Definition: db.h:169
virtual bool Rewrite(const char *pszSkip=nullptr)=0
Rewrite the entire database on disk, with the exception of key pszSkip if non-zero.
RAII class that provides access to a WalletDatabase.
Definition: db.h:45
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:172
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:135
DatabaseCursor & operator=(const DatabaseCursor &)=delete
bool Read(const K &key, T &value)
Definition: db.h:64
SecureString create_passphrase
Definition: db.h:188
ArgsManager & args
Definition: bitcoind.cpp:269
bool IsBDBFile(const fs::path &path)
Definition: db.cpp:83
uint64_t create_flags
Definition: db.h:187
bool Exists(const K &key)
Definition: db.h:105
virtual bool WriteKey(DataStream &&key, DataStream &&value, bool overwrite=true)=0
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:192
unsigned int nLastFlushed
Definition: db.h:171
virtual std::string Filename()=0
Return path to main database file for logs and error messages.
virtual void ReloadDbEnv()=0
virtual void IncrementUpdateCounter()=0
virtual void AddRef()=0
Indicate the a new database user has began using the database.
virtual bool ReadKey(DataStream &&key, DataStream &value)=0
virtual ~WalletDatabase()
Definition: db.h:129
bool Erase(const K &key)
Definition: db.h:95
virtual bool EraseKey(DataStream &&key)=0
virtual bool TxnCommit()=0
virtual bool PeriodicFlush()=0
bool use_shared_memory
Let other processes access the database.
Definition: db.h:193
virtual ~DatabaseCursor()
Definition: db.h:29
virtual Status Next(DataStream &key, DataStream &value)
Definition: db.h:41
DatabaseStatus
Definition: db.h:197
int64_t max_log_mb
Max log size to allow before consolidating.
Definition: db.h:194
DatabaseFormat
Definition: db.h:178
bool error(const char *fmt, const Args &... args)
Definition: logging.h:262
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:184
virtual std::unique_ptr< DatabaseBatch > MakeBatch(bool flush_on_close=true)=0
Make a DatabaseBatch connected to this database.
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
virtual std::string Format()=0
virtual void Flush()=0
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:191
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:33
DatabaseBatch & operator=(const DatabaseBatch &)=delete
virtual ~DatabaseBatch()
Definition: db.h:55
unsigned int nLastSeen
Definition: db.h:170
An instance of this class represents one database.
Definition: db.h:124