Branch data Line data Source code
1 : : // Copyright (c) 2021-2022 The Bitcoin Core developers 2 : : // Distributed under the MIT software license, see the accompanying 3 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : : 5 : : #ifndef BITCOIN_WALLET_TEST_UTIL_H 6 : : #define BITCOIN_WALLET_TEST_UTIL_H 7 : : 8 : : #include <addresstype.h> 9 : : #include <wallet/db.h> 10 : : 11 : : #include <memory> 12 : : 13 : : class ArgsManager; 14 : : class CChain; 15 : : class CKey; 16 : : enum class OutputType; 17 : : namespace interfaces { 18 : : class Chain; 19 : : } // namespace interfaces 20 : : 21 : : namespace wallet { 22 : : class CWallet; 23 : : class WalletDatabase; 24 : : struct WalletContext; 25 : : 26 : : static const DatabaseFormat DATABASE_FORMATS[] = { 27 : : #ifdef USE_SQLITE 28 : : DatabaseFormat::SQLITE, 29 : : #endif 30 : : #ifdef USE_BDB 31 : : DatabaseFormat::BERKELEY, 32 : : #endif 33 : : }; 34 : : 35 : : const std::string ADDRESS_BCRT1_UNSPENDABLE = "bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj"; 36 : : 37 : : std::unique_ptr<CWallet> CreateSyncedWallet(interfaces::Chain& chain, CChain& cchain, const CKey& key); 38 : : 39 : : std::shared_ptr<CWallet> TestLoadWallet(WalletContext& context); 40 : : std::shared_ptr<CWallet> TestLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, uint64_t create_flags); 41 : : void TestUnloadWallet(std::shared_ptr<CWallet>&& wallet); 42 : : 43 : : // Creates a copy of the provided database 44 : : std::unique_ptr<WalletDatabase> DuplicateMockDatabase(WalletDatabase& database); 45 : : 46 : : /** Returns a new encoded destination from the wallet (hardcoded to BECH32) */ 47 : : std::string getnewaddress(CWallet& w); 48 : : /** Returns a new destination, of an specific type, from the wallet */ 49 : : CTxDestination getNewDestination(CWallet& w, OutputType output_type); 50 : : 51 : : using MockableData = std::map<SerializeData, SerializeData, std::less<>>; 52 : : 53 : : class MockableCursor: public DatabaseCursor 54 : : { 55 : : public: 56 : : MockableData::const_iterator m_cursor; 57 : : MockableData::const_iterator m_cursor_end; 58 : : bool m_pass; 59 : : 60 : 0 : explicit MockableCursor(const MockableData& records, bool pass) : m_cursor(records.begin()), m_cursor_end(records.end()), m_pass(pass) {} 61 : : MockableCursor(const MockableData& records, bool pass, Span<const std::byte> prefix); 62 : 0 : ~MockableCursor() {} 63 : : 64 : : Status Next(DataStream& key, DataStream& value) override; 65 : : }; 66 : : 67 : : class MockableBatch : public DatabaseBatch 68 : : { 69 : : private: 70 : : MockableData& m_records; 71 : : bool m_pass; 72 : : 73 : : bool ReadKey(DataStream&& key, DataStream& value) override; 74 : : bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite=true) override; 75 : : bool EraseKey(DataStream&& key) override; 76 : : bool HasKey(DataStream&& key) override; 77 : : bool ErasePrefix(Span<const std::byte> prefix) override; 78 : : 79 : : public: 80 : 0 : explicit MockableBatch(MockableData& records, bool pass) : m_records(records), m_pass(pass) {} 81 : 0 : ~MockableBatch() {} 82 : : 83 : 0 : void Flush() override {} 84 : 0 : void Close() override {} 85 : : 86 : 0 : std::unique_ptr<DatabaseCursor> GetNewCursor() override 87 : : { 88 : 0 : return std::make_unique<MockableCursor>(m_records, m_pass); 89 : : } 90 : 0 : std::unique_ptr<DatabaseCursor> GetNewPrefixCursor(Span<const std::byte> prefix) override { 91 : 0 : return std::make_unique<MockableCursor>(m_records, m_pass, prefix); 92 : : } 93 : 0 : bool TxnBegin() override { return m_pass; } 94 : 0 : bool TxnCommit() override { return m_pass; } 95 : 0 : bool TxnAbort() override { return m_pass; } 96 : : }; 97 : : 98 : : /** A WalletDatabase whose contents and return values can be modified as needed for testing 99 : : **/ 100 : : class MockableDatabase : public WalletDatabase 101 : : { 102 : : public: 103 : : MockableData m_records; 104 : 1 : bool m_pass{true}; 105 : : 106 [ + - ]: 1 : MockableDatabase(MockableData records = {}) : WalletDatabase(), m_records(records) {} 107 : 2 : ~MockableDatabase() {}; 108 : : 109 : 0 : void Open() override {} 110 : 0 : void AddRef() override {} 111 : 0 : void RemoveRef() override {} 112 : : 113 : 0 : bool Rewrite(const char* pszSkip=nullptr) override { return m_pass; } 114 : 0 : bool Backup(const std::string& strDest) const override { return m_pass; } 115 : 0 : void Flush() override {} 116 : 0 : void Close() override {} 117 : 0 : bool PeriodicFlush() override { return m_pass; } 118 : 0 : void IncrementUpdateCounter() override {} 119 : 0 : void ReloadDbEnv() override {} 120 : : 121 [ # # ]: 0 : std::string Filename() override { return "mockable"; } 122 [ # # ]: 0 : std::string Format() override { return "mock"; } 123 : 0 : std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override { return std::make_unique<MockableBatch>(m_records, m_pass); } 124 : : }; 125 : : 126 : : std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase(MockableData records = {}); 127 : : 128 : : MockableDatabase& GetMockableDatabase(CWallet& wallet); 129 : : } // namespace wallet 130 : : 131 : : #endif // BITCOIN_WALLET_TEST_UTIL_H