Branch data Line data Source code
1 : : // Copyright (c) 2024-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_TEST_FUZZ_UTIL_WALLET_H
6 : : #define BITCOIN_TEST_FUZZ_UTIL_WALLET_H
7 : :
8 : : #include <test/fuzz/FuzzedDataProvider.h>
9 : : #include <test/fuzz/fuzz.h>
10 : : #include <test/fuzz/util.h>
11 : : #include <policy/policy.h>
12 : : #include <wallet/coincontrol.h>
13 : : #include <wallet/fees.h>
14 : : #include <wallet/spend.h>
15 : : #include <wallet/test/util.h>
16 : : #include <wallet/wallet.h>
17 : :
18 : : namespace wallet {
19 : :
20 : : /**
21 : : * Wraps a descriptor wallet for fuzzing.
22 : : */
23 [ + - + - : 3670 : struct FuzzedWallet {
- - ]
24 : : std::shared_ptr<CWallet> wallet;
25 : 1835 : FuzzedWallet(interfaces::Chain& chain, const std::string& name, const std::string& seed_insecure)
26 [ + - ]: 1835 : {
27 [ + - + - : 1835 : wallet = std::make_shared<CWallet>(&chain, name, CreateMockableWalletDatabase());
- + ]
28 : 1835 : {
29 [ + - ]: 1835 : LOCK(wallet->cs_wallet);
30 [ + - ]: 1835 : wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
31 [ + - + - : 1835 : auto height{*Assert(chain.getHeight())};
+ - ]
32 [ + - + - ]: 1835 : wallet->SetLastBlockProcessed(height, chain.getBlockHash(height));
33 : 0 : }
34 [ + - ]: 1835 : wallet->m_keypool_size = 1; // Avoid timeout in TopUp()
35 [ + - - + ]: 1835 : assert(wallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
36 [ + - ]: 1835 : ImportDescriptors(seed_insecure);
37 [ - - ]: 1835 : }
38 : 1835 : void ImportDescriptors(const std::string& seed_insecure)
39 : : {
40 : 1835 : const std::vector<std::string> DESCS{
41 : : "pkh(%s/%s/*)",
42 : : "sh(wpkh(%s/%s/*))",
43 : : "tr(%s/%s/*)",
44 : : "wpkh(%s/%s/*)",
45 [ + - - + : 11010 : };
+ + - - ]
46 : :
47 [ + + ]: 9175 : for (const std::string& desc_fmt : DESCS) {
48 [ + + ]: 22020 : for (bool internal : {true, false}) {
49 [ + - + - ]: 14680 : const auto descriptor{strprintf(tfm::RuntimeFormat{desc_fmt}, "[5aa9973a/66h/4h/2h]" + seed_insecure, int{internal})};
50 : :
51 : 14680 : FlatSigningProvider keys;
52 [ + - ]: 14680 : std::string error;
53 [ + - ]: 29360 : auto parsed_desc = std::move(Parse(descriptor, keys, error, /*require_checksum=*/false).at(0));
54 [ - + ]: 14680 : assert(parsed_desc);
55 [ - + ]: 14680 : assert(error.empty());
56 [ + - - + ]: 14680 : assert(parsed_desc->IsRange());
57 [ + - - + ]: 14680 : assert(parsed_desc->IsSingleType());
58 [ - + ]: 14680 : assert(!keys.keys.empty());
59 [ + - + - ]: 14680 : WalletDescriptor w_desc{std::move(parsed_desc), /*creation_time=*/0, /*range_start=*/0, /*range_end=*/1, /*next_index=*/0};
60 [ + - - + ]: 14680 : assert(!wallet->GetDescriptorScriptPubKeyMan(w_desc));
61 [ + - ]: 14680 : LOCK(wallet->cs_wallet);
62 [ + - + - : 14680 : auto& spk_manager = Assert(wallet->AddWalletDescriptor(w_desc, keys, /*label=*/"", internal))->get();
+ - ]
63 [ + - + - : 14680 : wallet->AddActiveScriptPubKeyMan(spk_manager.GetID(), *Assert(w_desc.descriptor->GetOutputType()), internal);
+ - + - ]
64 : 14680 : }
65 : : }
66 [ + - + - : 3670 : }
+ - + - -
- ]
67 : 143317 : CTxDestination GetDestination(FuzzedDataProvider& fuzzed_data_provider)
68 : : {
69 : 143317 : auto type{fuzzed_data_provider.PickValueInArray(OUTPUT_TYPES)};
70 [ + + ]: 143317 : if (fuzzed_data_provider.ConsumeBool()) {
71 [ + - + - : 196420 : return *Assert(wallet->GetNewDestination(type, ""));
+ - ]
72 : : } else {
73 [ + - + - ]: 90214 : return *Assert(wallet->GetNewChangeDestination(type));
74 : : }
75 : : }
76 : : CScript GetScriptPubKey(FuzzedDataProvider& fuzzed_data_provider) { return GetScriptForDestination(GetDestination(fuzzed_data_provider)); }
77 : : };
78 : : }
79 : :
80 : : #endif // BITCOIN_TEST_FUZZ_UTIL_WALLET_H
|