diff --git a/src/wallet/db.h b/src/wallet/db.h index 62b3e59ef..6baa72f7f 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -1,246 +1,247 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_WALLET_DB_H #define BITCOIN_WALLET_DB_H #include #include #include #include #include #include #include struct bilingual_str; void SplitWalletPath(const fs::path &wallet_path, fs::path &env_directory, std::string &database_filename); /** RAII class that provides access to a WalletDatabase */ class DatabaseBatch { private: virtual bool ReadKey(CDataStream &&key, CDataStream &value) = 0; virtual bool WriteKey(CDataStream &&key, CDataStream &&value, bool overwrite = true) = 0; virtual bool EraseKey(CDataStream &&key) = 0; virtual bool HasKey(CDataStream &&key) = 0; public: explicit DatabaseBatch() {} virtual ~DatabaseBatch() {} DatabaseBatch(const DatabaseBatch &) = delete; DatabaseBatch &operator=(const DatabaseBatch &) = delete; virtual void Flush() = 0; virtual void Close() = 0; template bool Read(const K &key, T &value) { CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(1000); ssKey << key; CDataStream ssValue(SER_DISK, CLIENT_VERSION); if (!ReadKey(std::move(ssKey), ssValue)) { return false; } try { ssValue >> value; return true; } catch (const std::exception &) { return false; } } template bool Write(const K &key, const T &value, bool fOverwrite = true) { CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(1000); ssKey << key; CDataStream ssValue(SER_DISK, CLIENT_VERSION); ssValue.reserve(10000); ssValue << value; return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite); } template bool Erase(const K &key) { CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(1000); ssKey << key; return EraseKey(std::move(ssKey)); } template bool Exists(const K &key) { CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(1000); ssKey << key; return HasKey(std::move(ssKey)); } virtual bool StartCursor() = 0; virtual bool ReadAtCursor(CDataStream &ssKey, CDataStream &ssValue, bool &complete) = 0; virtual void CloseCursor() = 0; virtual bool TxnBegin() = 0; virtual bool TxnCommit() = 0; 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; /** Return path to main database file for logs and error messages. */ virtual std::string Filename() = 0; std::atomic nUpdateCounter; unsigned int nLastSeen; unsigned int nLastFlushed; int64_t nLastWalletUpdate; /** Make a DatabaseBatch connected to this database */ virtual std::unique_ptr MakeBatch(const char *mode = "r+", bool flush_on_close = true) = 0; }; /** RAII class that provides access to a DummyDatabase. Never fails. */ class DummyBatch : public DatabaseBatch { private: bool ReadKey(CDataStream &&key, CDataStream &value) override { return true; } bool WriteKey(CDataStream &&key, CDataStream &&value, bool overwrite = true) override { return true; } bool EraseKey(CDataStream &&key) override { return true; } bool HasKey(CDataStream &&key) override { return true; } public: void Flush() override {} void Close() override {} bool StartCursor() override { return true; } bool ReadAtCursor(CDataStream &ssKey, CDataStream &ssValue, bool &complete) override { return true; } void CloseCursor() override {} bool TxnBegin() override { return true; } bool TxnCommit() override { return true; } bool TxnAbort() override { return true; } }; /** * A dummy WalletDatabase that does nothing and never fails. Only used by unit * tests. */ class DummyDatabase : public WalletDatabase { public: void Open(const char *mode) override{}; void AddRef() override {} void RemoveRef() override {} bool Rewrite(const char *pszSkip = nullptr) override { return true; } bool Backup(const std::string &strDest) const override { return true; } void Close() override {} void Flush() override {} bool PeriodicFlush() override { return true; } void IncrementUpdateCounter() override { ++nUpdateCounter; } void ReloadDbEnv() override {} std::string Filename() override { return "dummy"; } std::unique_ptr MakeBatch(const char *mode = "r+", bool flush_on_close = true) override { return std::make_unique(); } }; enum class DatabaseFormat { BERKELEY, }; struct DatabaseOptions { bool require_existing = false; bool require_create = false; uint64_t create_flags = 0; SecureString create_passphrase; bool verify = true; }; enum class DatabaseStatus { SUCCESS, FAILED_BAD_PATH, FAILED_BAD_FORMAT, FAILED_ALREADY_LOADED, FAILED_ALREADY_EXISTS, FAILED_NOT_FOUND, FAILED_CREATE, + FAILED_LOAD, FAILED_VERIFY, FAILED_ENCRYPT, }; std::unique_ptr MakeDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error); #endif // BITCOIN_WALLET_DB_H diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 852d1bb4a..70adf1cc2 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1,5088 +1,5091 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include