Bitcoin Core 32.99.0
P2P Digital Currency
util.h
Go to the documentation of this file.
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 <streams.h>
10#include <wallet/db.h>
12#include <wallet/sqlite.h>
13
14#include <memory>
15#include <optional>
16#include <string>
17#include <utility>
18
19class ArgsManager;
20class CChain;
21class CKey;
22enum class OutputType;
23namespace interfaces {
24class Chain;
25} // namespace interfaces
26
27namespace wallet {
28class CWallet;
29class WalletDatabase;
30struct WalletContext;
31
32inline constexpr DatabaseFormat DATABASE_FORMATS[] = {
34};
35
36inline const std::string ADDRESS_BCRT1_UNSPENDABLE = "bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj";
37
38std::unique_ptr<CWallet> CreateSyncedWallet(interfaces::Chain& chain, CChain& cchain, const CKey& key);
39
40std::shared_ptr<CWallet> TestCreateWallet(WalletContext& context);
41std::shared_ptr<CWallet> TestCreateWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, uint64_t create_flags);
42std::shared_ptr<CWallet> TestLoadWallet(WalletContext& context);
43std::shared_ptr<CWallet> TestLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context);
44void TestUnloadWallet(std::shared_ptr<CWallet>&& wallet);
45
47std::string getnewaddress(CWallet& w);
50
51using MockableData = std::map<SerializeData, SerializeData, std::less<>>;
52
53
55{
56public:
59};
60
64{
65public:
67
68 bool Backup(const std::string& strDest) const override { return true; }
69
70 std::string Filename() override { return "mockable"; }
71 std::string Format() override { return "sqlite-mock"; }
72 std::unique_ptr<DatabaseBatch> MakeBatch() override { return std::make_unique<MockableSQLiteBatch>(*this); }
73};
74
77{
78public:
79 void FailNextWrite(std::string record_type, size_t match_skip_count = 0)
80 {
81 m_fail_write = {std::move(record_type), match_skip_count};
82 }
83 void FailNextErase(std::string record_type) { m_fail_erase = {std::move(record_type)}; }
84 void FailNextCommit() { m_fail_commit = true; }
85
86 std::optional<SerializeData> GetRecordValue(const std::string& record_type)
87 {
88 auto batch{MakeBatch()};
89 if (auto cursor{batch->GetNewPrefixCursor(DataStream() << record_type)}) {
90 DataStream key, value;
91 if (cursor->Next(key, value) == DatabaseCursor::Status::MORE) {
92 return SerializeData{value.begin(), value.end()};
93 }
94 }
95 return std::nullopt;
96 }
97
98 bool HasRecordType(const std::string& record_type) { return GetRecordValue(record_type).has_value(); }
99
100 std::unique_ptr<DatabaseBatch> MakeBatch() override { return std::make_unique<Batch>(*this); }
101
102private:
103 struct Failure {
104 std::string record_type;
106 };
107
108 static bool ShouldFail(std::optional<Failure>& failure, const DataStream& key)
109 {
110 if (!failure) return false;
111 std::string record_type;
112 SpanReader{MakeByteSpan(key)} >> record_type;
113 if (failure->record_type != record_type) return false;
114 if (failure->match_skip_count > 0) {
115 --failure->match_skip_count;
116 return false;
117 }
118 failure.reset();
119 return true;
120 }
121
123 explicit Batch(FaultInjectingDatabase& database) : SQLiteBatch(database), m_owner{database} {}
124
125 bool TxnCommit() override
126 {
127 if (std::exchange(m_owner.m_fail_commit, false)) return false;
128 return SQLiteBatch::TxnCommit();
129 }
130
131 bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite = true) override
132 {
133 if (ShouldFail(m_owner.m_fail_write, key)) return false;
134 return SQLiteBatch::WriteKey(std::move(key), std::move(value), overwrite);
135 }
136
137 bool EraseKey(DataStream&& key) override
138 {
139 if (ShouldFail(m_owner.m_fail_erase, key)) return false;
140 return SQLiteBatch::EraseKey(std::move(key));
141 }
142
144 };
145
146 std::optional<Failure> m_fail_write;
147 std::optional<Failure> m_fail_erase;
148 bool m_fail_commit{false};
149};
150
151std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase();
153
154DescriptorScriptPubKeyMan* CreateDescriptor(CWallet& keystore, const std::string& desc_str, bool success);
155} // namespace wallet
156
157#endif // BITCOIN_WALLET_TEST_UTIL_H
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
Definition: addresstype.h:143
An in-memory indexed chain of blocks.
Definition: chain.h:380
An encapsulated private key.
Definition: key.h:46
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:165
const_iterator begin() const
Definition: streams.h:194
const_iterator end() const
Definition: streams.h:196
Minimal stream for reading from an existing byte array by std::span.
Definition: streams.h:83
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
Definition: chain.h:117
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:318
A SQLite wallet database that can fail selected operations for testing.
Definition: util.h:77
void FailNextWrite(std::string record_type, size_t match_skip_count=0)
Definition: util.h:79
std::unique_ptr< DatabaseBatch > MakeBatch() override
Make a SQLiteBatch connected to this database.
Definition: util.h:100
std::optional< Failure > m_fail_write
Definition: util.h:146
std::optional< Failure > m_fail_erase
Definition: util.h:147
bool HasRecordType(const std::string &record_type)
Definition: util.h:98
static bool ShouldFail(std::optional< Failure > &failure, const DataStream &key)
Definition: util.h:108
std::optional< SerializeData > GetRecordValue(const std::string &record_type)
Definition: util.h:86
void FailNextErase(std::string record_type)
Definition: util.h:83
An in-memory SQLiteDatabase.
Definition: sqlite.h:181
A WalletDatabase whose contents and return values can be modified as needed for testing.
Definition: util.h:64
std::string Filename() override
Return path to main database file for logs and error messages.
Definition: util.h:70
bool Backup(const std::string &strDest) const override
Back up the entire database to a file.
Definition: util.h:68
std::unique_ptr< DatabaseBatch > MakeBatch() override
Make a SQLiteBatch connected to this database.
Definition: util.h:72
std::string Format() override
Definition: util.h:71
RAII class that provides access to a WalletDatabase.
Definition: sqlite.h:52
bool TxnCommit() override
Definition: sqlite.cpp:679
SQLiteBatch(SQLiteDatabase &database)
Definition: sqlite.cpp:409
bool EraseKey(DataStream &&key) override
Definition: sqlite.cpp:553
bool WriteKey(DataStream &&key, DataStream &&value, bool overwrite=true) override
Definition: sqlite.cpp:496
wallet::DescriptorScriptPubKeyMan * CreateDescriptor(CWallet &keystore, const std::string &desc_str, const bool success)
Definition: util.cpp:126
std::unique_ptr< WalletDatabase > CreateMockableWalletDatabase()
Definition: util.cpp:121
const std::string ADDRESS_BCRT1_UNSPENDABLE
Definition: util.h:36
DatabaseFormat
Definition: db.h:163
MockableSQLiteDatabase & GetMockableDatabase(CWallet &wallet)
std::unique_ptr< CWallet > CreateSyncedWallet(interfaces::Chain &chain, CChain &cchain, const CKey &key)
Definition: util.cpp:22
void TestUnloadWallet(std::shared_ptr< CWallet > &&wallet)
Definition: util.cpp:98
constexpr DatabaseFormat DATABASE_FORMATS[]
Definition: util.h:32
std::shared_ptr< CWallet > TestLoadWallet(std::unique_ptr< WalletDatabase > database, WalletContext &context)
Definition: util.cpp:76
std::shared_ptr< CWallet > TestCreateWallet(std::unique_ptr< WalletDatabase > database, WalletContext &context, uint64_t create_flags)
Definition: util.cpp:52
std::map< SerializeData, SerializeData, std::less<> > MockableData
Definition: util.h:51
RPCMethod getnewaddress()
Definition: addresses.cpp:21
CTxDestination getNewDestination(CWallet &w, OutputType output_type)
Returns a new destination, of an specific type, from the wallet.
Definition: util.cpp:112
OutputType
Definition: outputtype.h:18
auto MakeByteSpan(const V &v) noexcept
Definition: span.h:84
bool WriteKey(DataStream &&key, DataStream &&value, bool overwrite=true) override
Definition: util.h:131
Batch(FaultInjectingDatabase &database)
Definition: util.h:123
FaultInjectingDatabase & m_owner
Definition: util.h:143
bool EraseKey(DataStream &&key) override
Definition: util.h:137
WalletContext struct containing references to state shared between CWallet instances,...
Definition: context.h:36
WalletContext context
std::vector< std::byte, zero_after_free_allocator< std::byte > > SerializeData
Byte-vector that clears its contents before deletion.
Definition: zeroafterfree.h:44