diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -23,7 +23,6 @@ #include #ifdef ENABLE_WALLET -#include #include #include diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h --- a/src/wallet/bdb.h +++ b/src/wallet/bdb.h @@ -96,83 +96,75 @@ * An instance of this class represents one database. * For BerkeleyDB this is just a (env, strFile) tuple. */ -class BerkeleyDatabase { +class BerkeleyDatabase : public WalletDatabase { friend class BerkeleyBatch; public: /** Create dummy DB handle */ - BerkeleyDatabase() - : nUpdateCounter(0), nLastSeen(0), nLastFlushed(0), - nLastWalletUpdate(0), env(nullptr) {} + BerkeleyDatabase() : WalletDatabase(), env(nullptr) {} /** Create DB handle to real database */ BerkeleyDatabase(std::shared_ptr envIn, std::string filename) - : nUpdateCounter(0), nLastSeen(0), nLastFlushed(0), - nLastWalletUpdate(0), env(std::move(envIn)), + : WalletDatabase(), env(std::move(envIn)), strFile(std::move(filename)) { auto inserted = this->env->m_databases.emplace(strFile, std::ref(*this)); assert(inserted.second); } - ~BerkeleyDatabase(); + ~BerkeleyDatabase() override; /** * Open the database if it is not already opened. * Dummy function, doesn't do anything right now, but is needed for class * abstraction */ - void Open(const char *mode); + void Open(const char *mode) override; /** * Rewrite the entire database on disk, with the exception of key pszSkip if * non-zero */ - bool Rewrite(const char *pszSkip = nullptr); + bool Rewrite(const char *pszSkip = nullptr) override; /** Indicate the a new database user has began using the database. */ - void AddRef(); + void AddRef() override; /** * Indicate that database user has stopped using the database and that it * could be flushed or closed. */ - void RemoveRef(); + void RemoveRef() override; /** * Back up the entire database to a file. */ - bool Backup(const std::string &strDest) const; + bool Backup(const std::string &strDest) const override; /** * Make sure all changes are flushed to database file. */ - void Flush(); + void Flush() override; /** * Flush to the database file and close the database. * Also close the environment if no other databases are open in it. */ - void Close(); + void Close() override; /** * flush the wallet passively (TRY_LOCK) * ideal to be called periodically */ - bool PeriodicFlush(); + bool PeriodicFlush() override; - void IncrementUpdateCounter(); - - void ReloadDbEnv(); + void IncrementUpdateCounter() override; - std::atomic nUpdateCounter; - unsigned int nLastSeen; - unsigned int nLastFlushed; - int64_t nLastWalletUpdate; + void ReloadDbEnv() override; /** Verifies the environment and database file */ - bool Verify(bilingual_str &error); + bool Verify(bilingual_str &error) override; /** * Pointer to shared database environment. @@ -192,8 +184,8 @@ std::unique_ptr m_db; /** Make a BerkeleyBatch connected to this database */ - std::unique_ptr MakeBatch(const char *mode, - bool flush_on_close); + std::unique_ptr + MakeBatch(const char *mode = "r+", bool flush_on_close = true) override; private: std::string strFile; diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp --- a/src/wallet/bdb.cpp +++ b/src/wallet/bdb.cpp @@ -935,7 +935,7 @@ env->m_db_in_use.notify_all(); } -std::unique_ptr +std::unique_ptr BerkeleyDatabase::MakeBatch(const char *mode, bool flush_on_close) { return std::make_unique(*this, mode, flush_on_close); } diff --git a/src/wallet/db.h b/src/wallet/db.h --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -10,8 +10,12 @@ #include #include +#include +#include #include +struct bilingual_str; + /** * Given a wallet directory path or legacy file path, return path to main data * file in the wallet database. */ @@ -93,4 +97,75 @@ virtual bool TxnAbort() = 0; }; +/** + * An instance of this class represents one database. + */ +class WalletDatabase { +public: + /** Create dummy DB handle */ + WalletDatabase() + : nUpdateCounter(0), nLastSeen(0), nLastFlushed(0), + nLastWalletUpdate(0) {} + virtual ~WalletDatabase(){}; + + /** Open the database if it is not already opened. */ + virtual void Open(const char *mode) = 0; + + //! Counts the number of active database users to be sure that the database + //! is not closed while someone is using it + std::atomic m_refcount{0}; + /** + * Indicate the a new database user has began using the database. + * Increments m_refcount + */ + virtual void AddRef() = 0; + /** + * Indicate that database user has stopped using the database and that it + * could be flushed or closed. Decrement m_refcount + */ + virtual void RemoveRef() = 0; + + /** + * Rewrite the entire database on disk, with the exception of key pszSkip + * if non-zero + */ + virtual bool Rewrite(const char *pszSkip = nullptr) = 0; + + /** + * Back up the entire database to a file. + */ + virtual bool Backup(const std::string &strDest) const = 0; + + /** + * Make sure all changes are flushed to database file. + */ + virtual void Flush() = 0; + /** + * Flush to the database file and close the database. + * Also close the environment if no other databases are open in it. + */ + virtual void Close() = 0; + /* flush the wallet passively (TRY_LOCK) + ideal to be called periodically */ + virtual bool PeriodicFlush() = 0; + + virtual void IncrementUpdateCounter() = 0; + + virtual void ReloadDbEnv() = 0; + + std::atomic nUpdateCounter; + unsigned int nLastSeen; + unsigned int nLastFlushed; + int64_t nLastWalletUpdate; + + /** Verifies the environment and database file */ + virtual bool Verify(bilingual_str &error) = 0; + + std::string m_file_path; + + /** Make a DatabaseBatch connected to this database */ + virtual std::unique_ptr + MakeBatch(const char *mode = "r+", bool flush_on_close = true) = 0; +}; + #endif // BITCOIN_WALLET_DB_H diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -42,9 +42,6 @@ class uint160; class uint256; -/** Backend-agnostic database type. */ -using WalletDatabase = BerkeleyDatabase; - /** Error statuses for the wallet database */ enum class DBErrors { LOAD_OK, @@ -289,7 +286,7 @@ bool TxnAbort(); private: - std::unique_ptr m_batch; + std::unique_ptr m_batch; WalletDatabase &m_database; }; @@ -305,14 +302,14 @@ bool IsWalletLoaded(const fs::path &wallet_path); /** Return object for accessing database at specified path. */ -std::unique_ptr CreateWalletDatabase(const fs::path &path); +std::unique_ptr CreateWalletDatabase(const fs::path &path); /** * Return object for accessing dummy database with no read/write capabilities. */ -std::unique_ptr CreateDummyWalletDatabase(); +std::unique_ptr CreateDummyWalletDatabase(); /** Return object for accessing temporary in-memory database. */ -std::unique_ptr CreateMockWalletDatabase(); +std::unique_ptr CreateMockWalletDatabase(); #endif // BITCOIN_WALLET_WALLETDB_H diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -1125,7 +1125,7 @@ } /** Return object for accessing database at specified path. */ -std::unique_ptr CreateWalletDatabase(const fs::path &path) { +std::unique_ptr CreateWalletDatabase(const fs::path &path) { std::string filename; return std::make_unique(GetWalletEnv(path, filename), std::move(filename)); @@ -1134,12 +1134,12 @@ /** * Return object for accessing dummy database with no read/write capabilities. */ -std::unique_ptr CreateDummyWalletDatabase() { +std::unique_ptr CreateDummyWalletDatabase() { return std::make_unique(); } /** Return object for accessing temporary in-memory database. */ -std::unique_ptr CreateMockWalletDatabase() { +std::unique_ptr CreateMockWalletDatabase() { return std::make_unique( std::make_shared(), ""); }