diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index 669ae692c..b8b483dfd 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -1,41 +1,42 @@ # Copyright (c) 2017 The Bitcoin developers project(wallet) # Add Berkeley DB dependency. find_package(BerkeleyDB 5.3 REQUIRED COMPONENTS CXX) # Add SQLite3 dependency. find_package(SQLite3 3.7.17 REQUIRED) # PR15638(https://reviews.bitcoinabc.org/D6000) moved some wallet load # functions to wallet/load.cpp, the others in wallet/init.cpp remain in # the server target_sources(server PRIVATE init.cpp) add_library(wallet ../interfaces/wallet.cpp bdb.cpp coincontrol.cpp coinselection.cpp context.cpp crypter.cpp db.cpp fees.cpp load.cpp rpcdump.cpp rpcwallet.cpp salvage.cpp scriptpubkeyman.cpp + sqlite.cpp wallet.cpp walletdb.cpp walletutil.cpp ) # There is a circular dependency between wallet and server, see: # https://github.com/bitcoin/bitcoin/pull/14437#discussion_r226237048 target_link_libraries(wallet bitcoinconsensus univalue BerkeleyDB::CXX SQLite::SQLite3) # wallet-tool library add_library(wallet-tool wallettool.cpp) target_link_libraries(wallet-tool wallet) diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp new file mode 100644 index 000000000..642596bd6 --- /dev/null +++ b/src/wallet/sqlite.cpp @@ -0,0 +1,89 @@ +// Copyright (c) 2020 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 + +static const char *const DATABASE_FILENAME = "wallet.dat"; + +SQLiteDatabase::SQLiteDatabase(const fs::path &dir_path, + const fs::path &file_path, bool mock) + // FIXME: uncomment m_mock when backporting commit a0de833 + : WalletDatabase(), /* m_mock(mock), */ m_dir_path(dir_path.string()), + m_file_path(file_path.string()) {} + +SQLiteDatabase::~SQLiteDatabase() {} + +void SQLiteDatabase::Open() {} + +bool SQLiteDatabase::Rewrite(const char *skip) { + return false; +} + +bool SQLiteDatabase::Backup(const std::string &dest) const { + return false; +} + +void SQLiteDatabase::Close() {} + +std::unique_ptr SQLiteDatabase::MakeBatch(bool flush_on_close) { + return nullptr; +} + +void SQLiteBatch::Close() {} + +bool SQLiteBatch::ReadKey(CDataStream &&key, CDataStream &value) { + return false; +} + +bool SQLiteBatch::WriteKey(CDataStream &&key, CDataStream &&value, + bool overwrite) { + return false; +} + +bool SQLiteBatch::EraseKey(CDataStream &&key) { + return false; +} + +bool SQLiteBatch::HasKey(CDataStream &&key) { + return false; +} + +bool SQLiteBatch::StartCursor() { + return false; +} + +bool SQLiteBatch::ReadAtCursor(CDataStream &key, CDataStream &value, + bool &complete) { + return false; +} + +void SQLiteBatch::CloseCursor() {} + +bool SQLiteBatch::TxnBegin() { + return false; +} + +bool SQLiteBatch::TxnCommit() { + return false; +} + +bool SQLiteBatch::TxnAbort() { + return false; +} + +bool ExistsSQLiteDatabase(const fs::path &path) { + return false; +} + +std::unique_ptr +MakeSQLiteDatabase(const fs::path &path, const DatabaseOptions &options, + DatabaseStatus &status, bilingual_str &error) { + return std::make_unique(path, path / DATABASE_FILENAME); +} diff --git a/src/wallet/sqlite.h b/src/wallet/sqlite.h new file mode 100644 index 000000000..aca692c61 --- /dev/null +++ b/src/wallet/sqlite.h @@ -0,0 +1,104 @@ +// Copyright (c) 2020 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_SQLITE_H +#define BITCOIN_WALLET_SQLITE_H + +#include + +struct bilingual_str; +class SQLiteDatabase; + +/** RAII class that provides access to a WalletDatabase */ +class SQLiteBatch : public DatabaseBatch { +private: + SQLiteDatabase &m_database; + + bool ReadKey(CDataStream &&key, CDataStream &value) override; + bool WriteKey(CDataStream &&key, CDataStream &&value, + bool overwrite = true) override; + bool EraseKey(CDataStream &&key) override; + bool HasKey(CDataStream &&key) override; + +public: + explicit SQLiteBatch(SQLiteDatabase &database); + + /** No-op. See comment on SQLiteDatabase::Flush */ + void Flush() override {} + + void Close() override; + + bool StartCursor() override; + bool ReadAtCursor(CDataStream &key, CDataStream &value, + bool &complete) override; + void CloseCursor() override; + bool TxnBegin() override; + bool TxnCommit() override; + bool TxnAbort() override; +}; + +/** An instance of this class represents one SQLite3 database. */ +class SQLiteDatabase : public WalletDatabase { +private: + // FIXME: uncomment this line when m_mock is used in commit a0de833 + // const bool m_mock{false}; + + const std::string m_dir_path; + + const std::string m_file_path; + +public: + SQLiteDatabase() = delete; + + /** Create DB handle to real database */ + SQLiteDatabase(const fs::path &dir_path, const fs::path &file_path, + bool mock = false); + + ~SQLiteDatabase(); + + /** Open the database if it is not already opened */ + void Open() override; + + /** Close the database */ + void Close() override; + + /* These functions are unused */ + void AddRef() override { assert(false); } + void RemoveRef() override { assert(false); } + + /** Rewrite the entire database on disk */ + bool Rewrite(const char *skip = nullptr) override; + + /** Back up the entire database to a file. */ + bool Backup(const std::string &dest) const override; + + /** + * No-ops + * + * SQLite always flushes everything to the database file after each + * transaction (each Read/Write/Erase that we do is its own transaction + * unless we called TxnBegin) so there is no need to have Flush or Periodic + * Flush. + * + * There is no DB env to reload, so ReloadDbEnv has nothing to do + */ + void Flush() override {} + bool PeriodicFlush() override { return false; } + void ReloadDbEnv() override {} + + void IncrementUpdateCounter() override { ++nUpdateCounter; } + + std::string Filename() override { return m_file_path; } + + /** Make a SQLiteBatch connected to this database */ + std::unique_ptr + MakeBatch(bool flush_on_close = true) override; +}; + +bool ExistsSQLiteDatabase(const fs::path &path); +std::unique_ptr +MakeSQLiteDatabase(const fs::path &path, const DatabaseOptions &options, + DatabaseStatus &status, bilingual_str &error); + +#endif // BITCOIN_WALLET_SQLITE_H