Bitcoin Core 32.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/scan.h>
14#include <wallet/wallet.h>
15#include <wallet/walletdb.h>
16
17#include <sqlite3.h>
18
19#include <memory>
20
21namespace wallet {
22std::unique_ptr<CWallet> CreateSyncedWallet(interfaces::Chain& chain, CChain& cchain, const CKey& key)
23{
24 auto wallet = std::make_unique<CWallet>(&chain, "", CreateMockableWalletDatabase());
25 {
26 LOCK2(wallet->cs_wallet, ::cs_main);
27 wallet->SetLastBlockProcessed(cchain.Height(), cchain.Tip()->GetBlockHash());
28 }
29 {
30 LOCK(wallet->cs_wallet);
31 wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
32 wallet->SetupDescriptorScriptPubKeyMans();
33
35 std::string error;
36 auto descs = Parse("combo(" + EncodeSecret(key) + ")", provider, error, /* require_checksum=*/ false);
37 assert(descs.size() == 1);
38 auto& desc = descs.at(0);
39 WalletDescriptor w_desc(std::move(desc), 0, 0, 1, 1);
40 Assert(wallet->AddWalletDescriptor(w_desc, provider, "", false));
41 }
43 reserver.reserve();
44 ScanResult result = wallet->Scanner().Scan(cchain.Genesis()->GetBlockHash(), /*start_height=*/0, /*max_height=*/{}, reserver, /*save_progress=*/false);
46 assert(result.last_scanned_block == cchain.Tip()->GetBlockHash());
47 assert(*result.last_scanned_height == cchain.Height());
49 return wallet;
50}
51
52std::shared_ptr<CWallet> TestCreateWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, uint64_t create_flags)
53{
54 bilingual_str _error;
55 std::vector<bilingual_str> _warnings;
56 auto wallet = CWallet::CreateNew(context, "", std::move(database), create_flags, /*born_encrypted=*/false, _error, _warnings);
58 if (context.chain) {
59 wallet->postInitProcess();
60 }
61 return wallet;
62}
63
64std::shared_ptr<CWallet> TestCreateWallet(WalletContext& context)
65{
66 DatabaseOptions options;
67 options.require_create = true;
69 DatabaseStatus status;
70 bilingual_str error;
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);
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 auto database = MakeWalletDatabase("", options, status, error);
95 return TestLoadWallet(std::move(database), context);
96}
97
98void TestUnloadWallet(std::shared_ptr<CWallet>&& wallet)
99{
100 // Calls SyncWithValidationInterfaceQueue
101 wallet->chain().waitForNotificationsIfTipChanged({});
102 wallet->m_chain_notifications_handler.reset();
103 WaitForDeleteWallet(std::move(wallet));
104}
105
106std::string getnewaddress(CWallet& w)
107{
108 constexpr auto output_type = OutputType::BECH32;
109 return EncodeDestination(getNewDestination(w, output_type));
110}
111
113{
114 return *Assert(w.GetNewDestination(output_type, ""));
115}
116
119{}
120
121std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase()
122{
123 return std::make_unique<MockableSQLiteDatabase>();
124}
125
126wallet::DescriptorScriptPubKeyMan* CreateDescriptor(CWallet& keystore, const std::string& desc_str, const bool success)
127{
129
131 std::string error;
132 auto parsed_descs = Parse(desc_str, keys, error, false);
133 Assert(success == (!parsed_descs.empty()));
134 if (!success) return nullptr;
135 auto& desc = parsed_descs.at(0);
136
137 const int64_t range_start = 0, range_end = 1, next_index = 0, timestamp = 1;
138
139 WalletDescriptor w_desc(std::move(desc), timestamp, range_start, range_end, next_index);
140
141 LOCK(keystore.cs_wallet);
142 auto spkm = Assert(keystore.AddWalletDescriptor(w_desc, keys,/*label=*/"", /*internal=*/false));
143 return &spkm.value().get();
144};
145} // 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:40
constexpr bool IsNull() const
Definition: uint256.h:50
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:313
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:2958
static std::shared_ptr< CWallet > CreateNew(WalletContext &context, const std::string &name, std::unique_ptr< WalletDatabase > database, uint64_t wallet_creation_flags, bool born_encrypted, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:2903
util::Result< CTxDestination > GetNewDestination(OutputType type, const std::string &label)
Definition: wallet.cpp:2410
RecursiveMutex cs_wallet
Main wallet lock.
Definition: wallet.h:463
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:3592
An in-memory SQLiteDatabase.
Definition: sqlite.h:181
Descriptor with some wallet metadata.
Definition: walletutil.h:64
RAII object to check and reserve a wallet rescan.
Definition: scan.h:37
bool reserve(bool with_passphrase=false)
Definition: scan.cpp:40
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:408
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:1741
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:126
std::unique_ptr< WalletDatabase > CreateMockableWalletDatabase()
Definition: util.cpp:121
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
std::unique_ptr< WalletDatabase > MakeWalletDatabase(const std::string &name, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error_string)
Definition: wallet.cpp:2766
void NotifyWalletLoaded(WalletContext &context, const std::shared_ptr< CWallet > &wallet)
Definition: wallet.cpp:235
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
@ 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:266
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
DatabaseStatus
Definition: db.h:180
OutputType
Definition: outputtype.h:18
Bilingual messages:
Definition: translation.h:24
bool require_existing
Definition: db.h:169
uint64_t create_flags
Definition: db.h:172
Result of a wallet scan.
Definition: scan.h:19
uint256 last_scanned_block
Hash and height of most recent block that was successfully scanned.
Definition: scan.h:25
enum wallet::ScanResult::@19 status
std::optional< int > last_scanned_height
Definition: scan.h:26
uint256 last_failed_block
Height of the most recent block that could not be scanned due to read errors or pruning.
Definition: scan.h:32
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
std::vector< uint16_t > keys
Definition: dbwrapper.cpp:376
FuzzedDataProvider provider
Definition: dbwrapper.cpp:366
assert(!tx.IsCoinBase())
std::shared_ptr< CWallet > wallet
WalletContext context