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