Bitcoin Core 31.99.0
P2P Digital Currency
util.cpp
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#include <wallet/test/util.h>
6
7#include <chain.h>
8#include <key.h>
9#include <key_io.h>
11#include <validationinterface.h>
12#include <wallet/context.h>
13#include <wallet/wallet.h>
14#include <wallet/walletdb.h>
15
16#include <sqlite3.h>
17
18#include <memory>
19
20namespace wallet {
21std::unique_ptr<CWallet> CreateSyncedWallet(interfaces::Chain& chain, CChain& cchain, const CKey& key)
22{
23 auto wallet = std::make_unique<CWallet>(&chain, "", CreateMockableWalletDatabase());
24 {
25 LOCK2(wallet->cs_wallet, ::cs_main);
26 wallet->SetLastBlockProcessed(cchain.Height(), cchain.Tip()->GetBlockHash());
27 }
28 {
29 LOCK(wallet->cs_wallet);
30 wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
31 wallet->SetupDescriptorScriptPubKeyMans();
32
33 FlatSigningProvider provider;
34 std::string error;
35 auto descs = Parse("combo(" + EncodeSecret(key) + ")", provider, error, /* require_checksum=*/ false);
36 assert(descs.size() == 1);
37 auto& desc = descs.at(0);
38 WalletDescriptor w_desc(std::move(desc), 0, 0, 1, 1);
39 Assert(wallet->AddWalletDescriptor(w_desc, provider, "", false));
40 }
42 reserver.reserve();
43 CWallet::ScanResult result = wallet->ScanForWalletTransactions(cchain.Genesis()->GetBlockHash(), /*start_height=*/0, /*max_height=*/{}, reserver, /*save_progress=*/false);
45 assert(result.last_scanned_block == cchain.Tip()->GetBlockHash());
46 assert(*result.last_scanned_height == cchain.Height());
48 return wallet;
49}
50
51std::shared_ptr<CWallet> TestCreateWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, uint64_t create_flags)
52{
53 bilingual_str _error;
54 std::vector<bilingual_str> _warnings;
55 auto wallet = CWallet::CreateNew(context, "", std::move(database), create_flags, _error, _warnings);
56 NotifyWalletLoaded(context, wallet);
57 if (context.chain) {
58 wallet->postInitProcess();
59 }
60 return wallet;
61}
62
63std::shared_ptr<CWallet> TestCreateWallet(WalletContext& context)
64{
65 DatabaseOptions options;
66 options.require_create = true;
68 DatabaseStatus status;
69 bilingual_str error;
70 std::vector<bilingual_str> warnings;
71 auto database = MakeWalletDatabase("", options, status, error);
72 return TestCreateWallet(std::move(database), context, options.create_flags);
73}
74
75
76std::shared_ptr<CWallet> TestLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context)
77{
78 bilingual_str error;
79 std::vector<bilingual_str> warnings;
80 auto wallet = CWallet::LoadExisting(context, "", std::move(database), error, warnings);
81 NotifyWalletLoaded(context, wallet);
82 if (context.chain) {
83 wallet->postInitProcess();
84 }
85 return wallet;
86}
87
88std::shared_ptr<CWallet> TestLoadWallet(WalletContext& context)
89{
90 DatabaseOptions options;
91 options.require_existing = true;
92 DatabaseStatus status;
93 bilingual_str error;
94 std::vector<bilingual_str> warnings;
95 auto database = MakeWalletDatabase("", options, status, error);
96 return TestLoadWallet(std::move(database), context);
97}
98
99void TestUnloadWallet(std::shared_ptr<CWallet>&& wallet)
100{
101 // Calls SyncWithValidationInterfaceQueue
102 wallet->chain().waitForNotificationsIfTipChanged({});
103 wallet->m_chain_notifications_handler.reset();
104 WaitForDeleteWallet(std::move(wallet));
105}
106
107std::string getnewaddress(CWallet& w)
108{
109 constexpr auto output_type = OutputType::BECH32;
110 return EncodeDestination(getNewDestination(w, output_type));
111}
112
114{
115 return *Assert(w.GetNewDestination(output_type, ""));
116}
117
119 : SQLiteDatabase(fs::PathFromString("mock/"), fs::PathFromString("mock/wallet.dat"), DatabaseOptions(), SQLITE_OPEN_MEMORY)
120{}
121
122std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase()
123{
124 return std::make_unique<MockableSQLiteDatabase>();
125}
126
127wallet::DescriptorScriptPubKeyMan* CreateDescriptor(CWallet& keystore, const std::string& desc_str, const bool success)
128{
130
132 std::string error;
133 auto parsed_descs = Parse(desc_str, keys, error, false);
134 Assert(success == (!parsed_descs.empty()));
135 if (!success) return nullptr;
136 auto& desc = parsed_descs.at(0);
137
138 const int64_t range_start = 0, range_end = 1, next_index = 0, timestamp = 1;
139
140 WalletDescriptor w_desc(std::move(desc), timestamp, range_start, range_end, next_index);
141
142 LOCK(keystore.cs_wallet);
143 auto spkm = Assert(keystore.AddWalletDescriptor(w_desc, keys,/*label=*/"", /*internal=*/false));
144 return &spkm.value().get();
145};
146} // namespace wallet
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
Definition: addresstype.h:143
#define Assert(val)
Identity function.
Definition: check.h:116
uint256 GetBlockHash() const
Definition: chain.h:198
An in-memory indexed chain of blocks.
Definition: chain.h:380
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:396
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
Definition: chain.h:390
int Height() const
Return the maximal height in the chain.
Definition: chain.h:425
An encapsulated private key.
Definition: key.h:37
constexpr bool IsNull() const
Definition: uint256.h:49
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
Definition: chain.h:118
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:309
static std::shared_ptr< CWallet > LoadExisting(WalletContext &context, const std::string &name, std::unique_ptr< WalletDatabase > database, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:3169
util::Result< CTxDestination > GetNewDestination(OutputType type, const std::string &label)
Definition: wallet.cpp:2626
RecursiveMutex cs_wallet
Main wallet lock.
Definition: wallet.h:458
static std::shared_ptr< CWallet > CreateNew(WalletContext &context, const std::string &name, std::unique_ptr< WalletDatabase > database, uint64_t wallet_creation_flags, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:3115
util::Result< std::reference_wrapper< DescriptorScriptPubKeyMan > > AddWalletDescriptor(WalletDescriptor &desc, const FlatSigningProvider &signing_provider, const std::string &label, bool internal) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Add a descriptor to the wallet, return a ScriptPubKeyMan & associated output type.
Definition: wallet.cpp:3800
An instance of this class represents one SQLite3 database.
Definition: sqlite.h:104
Descriptor with some wallet metadata.
Definition: walletutil.h:64
RAII object to check and reserve a wallet rescan.
Definition: wallet.h:1087
bool reserve(bool with_passphrase=false)
Definition: wallet.h:1097
static UniValue Parse(std::string_view raw, ParamFormat format=ParamFormat::JSON)
Parse string to UniValue or throw runtime_error if string contains invalid JSON.
Definition: client.cpp:400
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: cs_main.cpp:8
void BlockUntilSyncedToCurrentChain() const LOCKS_EXCLUDED(void SetWalletFlag(uint64_t flags)
Blocks until the wallet state is up-to-date to /at least/ the current chain at the time this function...
Definition: wallet.cpp:1763
std::string EncodeSecret(const CKey &key)
Definition: key_io.cpp:232
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:295
wallet::DescriptorScriptPubKeyMan * CreateDescriptor(CWallet &keystore, const std::string &desc_str, const bool success)
Definition: util.cpp:127
std::unique_ptr< WalletDatabase > CreateMockableWalletDatabase()
Definition: util.cpp:122
std::unique_ptr< CWallet > CreateSyncedWallet(interfaces::Chain &chain, CChain &cchain, const CKey &key)
Definition: util.cpp:21
void TestUnloadWallet(std::shared_ptr< CWallet > &&wallet)
Definition: util.cpp:99
std::unique_ptr< WalletDatabase > MakeWalletDatabase(const std::string &name, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error_string)
Definition: wallet.cpp:2982
void NotifyWalletLoaded(WalletContext &context, const std::shared_ptr< CWallet > &wallet)
Definition: wallet.cpp:224
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:51
@ WALLET_FLAG_DESCRIPTORS
Indicate that this wallet supports DescriptorScriptPubKeyMan.
Definition: walletutil.h:53
void WaitForDeleteWallet(std::shared_ptr< CWallet > &&wallet)
Explicitly delete the wallet.
Definition: wallet.cpp:255
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:113
DatabaseStatus
Definition: db.h:186
OutputType
Definition: outputtype.h:18
Bilingual messages:
Definition: translation.h:24
std::optional< int > last_scanned_height
Definition: wallet.h:646
uint256 last_scanned_block
Hash and height of most recent block that was successfully scanned.
Definition: wallet.h:645
uint256 last_failed_block
Height of the most recent block that could not be scanned due to read errors or pruning.
Definition: wallet.h:652
enum wallet::CWallet::ScanResult::@18 status
bool require_existing
Definition: db.h:173
uint64_t create_flags
Definition: db.h:176
WalletContext struct containing references to state shared between CWallet instances,...
Definition: context.h:36
interfaces::Chain * chain
Definition: context.h:37
#define LOCK2(cs1, cs2)
Definition: sync.h:269
#define LOCK(cs)
Definition: sync.h:268
assert(!tx.IsCoinBase())