util.h
1 // Copyright (c) 2021-present 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 #include <wallet/scriptpubkeyman.h> 11 12 #include <memory> 13 14 class ArgsManager; 15 class CChain; 16 class CKey; 17 enum class OutputType; 18 namespace interfaces { 19 class Chain; 20 } // namespace interfaces 21 22 namespace wallet { 23 class CWallet; 24 class WalletDatabase; 25 struct WalletContext; 26 27 static const DatabaseFormat DATABASE_FORMATS[] = { 28 DatabaseFormat::SQLITE, 29 }; 30 31 const std::string ADDRESS_BCRT1_UNSPENDABLE = "bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj"; 32 33 std::unique_ptr<CWallet> CreateSyncedWallet(interfaces::Chain& chain, CChain& cchain, const CKey& key); 34 35 std::shared_ptr<CWallet> TestCreateWallet(WalletContext& context); 36 std::shared_ptr<CWallet> TestCreateWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, uint64_t create_flags); 37 std::shared_ptr<CWallet> TestLoadWallet(WalletContext& context); 38 std::shared_ptr<CWallet> TestLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context); 39 void TestUnloadWallet(std::shared_ptr<CWallet>&& wallet); 40 41 // Creates a copy of the provided database 42 std::unique_ptr<WalletDatabase> DuplicateMockDatabase(WalletDatabase& database); 43 44 /** Returns a new encoded destination from the wallet (hardcoded to BECH32) */ 45 std::string getnewaddress(CWallet& w); 46 /** Returns a new destination, of an specific type, from the wallet */ 47 CTxDestination getNewDestination(CWallet& w, OutputType output_type); 48 49 using MockableData = std::map<SerializeData, SerializeData, std::less<>>; 50 51 class MockableCursor: public DatabaseCursor 52 { 53 public: 54 MockableData::const_iterator m_cursor; 55 MockableData::const_iterator m_cursor_end; 56 bool m_pass; 57 58 explicit MockableCursor(const MockableData& records, bool pass) : m_cursor(records.begin()), m_cursor_end(records.end()), m_pass(pass) {} 59 MockableCursor(const MockableData& records, bool pass, std::span<const std::byte> prefix); 60 ~MockableCursor() = default; 61 62 Status Next(DataStream& key, DataStream& value) override; 63 }; 64 65 class MockableBatch : public DatabaseBatch 66 { 67 private: 68 MockableData& m_records; 69 bool m_pass; 70 71 bool ReadKey(DataStream&& key, DataStream& value) override; 72 bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite=true) override; 73 bool EraseKey(DataStream&& key) override; 74 bool HasKey(DataStream&& key) override; 75 bool ErasePrefix(std::span<const std::byte> prefix) override; 76 77 public: 78 explicit MockableBatch(MockableData& records, bool pass) : m_records(records), m_pass(pass) {} 79 ~MockableBatch() = default; 80 81 void Close() override {} 82 83 std::unique_ptr<DatabaseCursor> GetNewCursor() override 84 { 85 return std::make_unique<MockableCursor>(m_records, m_pass); 86 } 87 std::unique_ptr<DatabaseCursor> GetNewPrefixCursor(std::span<const std::byte> prefix) override { 88 return std::make_unique<MockableCursor>(m_records, m_pass, prefix); 89 } 90 bool TxnBegin() override { return m_pass; } 91 bool TxnCommit() override { return m_pass; } 92 bool TxnAbort() override { return m_pass; } 93 bool HasActiveTxn() override { return false; } 94 }; 95 96 /** A WalletDatabase whose contents and return values can be modified as needed for testing 97 **/ 98 class MockableDatabase : public WalletDatabase 99 { 100 public: 101 MockableData m_records; 102 bool m_pass{true}; 103 104 MockableDatabase(MockableData records = {}) : WalletDatabase(), m_records(records) {} 105 ~MockableDatabase() = default; 106 107 void Open() override {} 108 109 bool Rewrite() override { return m_pass; } 110 bool Backup(const std::string& strDest) const override { return m_pass; } 111 void Close() override {} 112 113 std::string Filename() override { return "mockable"; } 114 std::vector<fs::path> Files() override { return {}; } 115 std::string Format() override { return "mock"; } 116 std::unique_ptr<DatabaseBatch> MakeBatch() override { return std::make_unique<MockableBatch>(m_records, m_pass); } 117 }; 118 119 std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase(MockableData records = {}); 120 MockableDatabase& GetMockableDatabase(CWallet& wallet); 121 122 DescriptorScriptPubKeyMan* CreateDescriptor(CWallet& keystore, const std::string& desc_str, bool success); 123 } // namespace wallet 124 125 #endif // BITCOIN_WALLET_TEST_UTIL_H