18
18
#include < test/fuzz/FuzzedDataProvider.h>
19
19
#include < test/fuzz/fuzz.h>
20
20
#include < test/fuzz/util.h>
21
+ #include < test/fuzz/util/wallet.h>
21
22
#include < test/util/setup_common.h>
22
23
#include < tinyformat.h>
23
24
#include < uint256.h>
@@ -53,121 +54,6 @@ void initialize_setup()
53
54
g_setup = testing_setup.get ();
54
55
}
55
56
56
- void ImportDescriptors (CWallet& wallet, const std::string& seed_insecure)
57
- {
58
- const std::vector<std::string> DESCS{
59
- " pkh(%s/%s/*)" ,
60
- " sh(wpkh(%s/%s/*))" ,
61
- " tr(%s/%s/*)" ,
62
- " wpkh(%s/%s/*)" ,
63
- };
64
-
65
- for (const std::string& desc_fmt : DESCS) {
66
- for (bool internal : {true , false }) {
67
- const auto descriptor{(strprintf)(desc_fmt, " [5aa9973a/66h/4h/2h]" + seed_insecure, int {internal})};
68
-
69
- FlatSigningProvider keys;
70
- std::string error;
71
- auto parsed_desc = std::move (Parse (descriptor, keys, error, /* require_checksum=*/ false ).at (0 ));
72
- assert (parsed_desc);
73
- assert (error.empty ());
74
- assert (parsed_desc->IsRange ());
75
- assert (parsed_desc->IsSingleType ());
76
- assert (!keys.keys .empty ());
77
- WalletDescriptor w_desc{std::move (parsed_desc), /* creation_time=*/ 0 , /* range_start=*/ 0 , /* range_end=*/ 1 , /* next_index=*/ 0 };
78
- assert (!wallet.GetDescriptorScriptPubKeyMan (w_desc));
79
- LOCK (wallet.cs_wallet );
80
- auto spk_manager{wallet.AddWalletDescriptor (w_desc, keys, /* label=*/ " " , internal)};
81
- assert (spk_manager);
82
- wallet.AddActiveScriptPubKeyMan (spk_manager->GetID (), *Assert (w_desc.descriptor ->GetOutputType ()), internal);
83
- }
84
- }
85
- }
86
-
87
- /* *
88
- * Wraps a descriptor wallet for fuzzing.
89
- */
90
- struct FuzzedWallet {
91
- std::shared_ptr<CWallet> wallet;
92
- FuzzedWallet (const std::string& name, const std::string& seed_insecure)
93
- {
94
- auto & chain{*Assert (g_setup->m_node .chain )};
95
- wallet = std::make_shared<CWallet>(&chain, name, CreateMockableWalletDatabase ());
96
- {
97
- LOCK (wallet->cs_wallet );
98
- wallet->SetWalletFlag (WALLET_FLAG_DESCRIPTORS);
99
- auto height{*Assert (chain.getHeight ())};
100
- wallet->SetLastBlockProcessed (height, chain.getBlockHash (height));
101
- }
102
- wallet->m_keypool_size = 1 ; // Avoid timeout in TopUp()
103
- assert (wallet->IsWalletFlagSet (WALLET_FLAG_DESCRIPTORS));
104
- ImportDescriptors (*wallet, seed_insecure);
105
- }
106
- CTxDestination GetDestination (FuzzedDataProvider& fuzzed_data_provider)
107
- {
108
- auto type{fuzzed_data_provider.PickValueInArray (OUTPUT_TYPES)};
109
- if (fuzzed_data_provider.ConsumeBool ()) {
110
- return *Assert (wallet->GetNewDestination (type, " " ));
111
- } else {
112
- return *Assert (wallet->GetNewChangeDestination (type));
113
- }
114
- }
115
- CScript GetScriptPubKey (FuzzedDataProvider& fuzzed_data_provider) { return GetScriptForDestination (GetDestination (fuzzed_data_provider)); }
116
- void FundTx (FuzzedDataProvider& fuzzed_data_provider, CMutableTransaction tx)
117
- {
118
- // The fee of "tx" is 0, so this is the total input and output amount
119
- const CAmount total_amt{
120
- std::accumulate (tx.vout .begin (), tx.vout .end (), CAmount{}, [](CAmount t, const CTxOut& out) { return t + out.nValue ; })};
121
- const uint32_t tx_size (GetVirtualTransactionSize (CTransaction{tx}));
122
- std::set<int > subtract_fee_from_outputs;
123
- if (fuzzed_data_provider.ConsumeBool ()) {
124
- for (size_t i{}; i < tx.vout .size (); ++i) {
125
- if (fuzzed_data_provider.ConsumeBool ()) {
126
- subtract_fee_from_outputs.insert (i);
127
- }
128
- }
129
- }
130
- std::vector<CRecipient> recipients;
131
- for (size_t idx = 0 ; idx < tx.vout .size (); idx++) {
132
- const CTxOut& tx_out = tx.vout [idx];
133
- CTxDestination dest;
134
- ExtractDestination (tx_out.scriptPubKey , dest);
135
- CRecipient recipient = {dest, tx_out.nValue , subtract_fee_from_outputs.count (idx) == 1 };
136
- recipients.push_back (recipient);
137
- }
138
- CCoinControl coin_control;
139
- coin_control.m_allow_other_inputs = fuzzed_data_provider.ConsumeBool ();
140
- CallOneOf (
141
- fuzzed_data_provider, [&] { coin_control.destChange = GetDestination (fuzzed_data_provider); },
142
- [&] { coin_control.m_change_type .emplace (fuzzed_data_provider.PickValueInArray (OUTPUT_TYPES)); },
143
- [&] { /* no op (leave uninitialized) */ });
144
- coin_control.fAllowWatchOnly = fuzzed_data_provider.ConsumeBool ();
145
- coin_control.m_include_unsafe_inputs = fuzzed_data_provider.ConsumeBool ();
146
- {
147
- auto & r{coin_control.m_signal_bip125_rbf };
148
- CallOneOf (
149
- fuzzed_data_provider, [&] { r = true ; }, [&] { r = false ; }, [&] { r = std::nullopt; });
150
- }
151
- coin_control.m_feerate = CFeeRate{
152
- // A fee of this range should cover all cases
153
- fuzzed_data_provider.ConsumeIntegralInRange <CAmount>(0 , 2 * total_amt),
154
- tx_size,
155
- };
156
- if (fuzzed_data_provider.ConsumeBool ()) {
157
- *coin_control.m_feerate += GetMinimumFeeRate (*wallet, coin_control, nullptr );
158
- }
159
- coin_control.fOverrideFeeRate = fuzzed_data_provider.ConsumeBool ();
160
- // Add solving data (m_external_provider and SelectExternal)?
161
-
162
- int change_position{fuzzed_data_provider.ConsumeIntegralInRange <int >(-1 , tx.vout .size () - 1 )};
163
- bilingual_str error;
164
- // Clear tx.vout since it is not meant to be used now that we are passing outputs directly.
165
- // This sets us up for a future PR to completely remove tx from the function signature in favor of passing inputs directly
166
- tx.vout .clear ();
167
- (void )FundTransaction (*wallet, tx, recipients, change_position, /* lockUnspents=*/ false , coin_control);
168
- }
169
- };
170
-
171
57
FUZZ_TARGET (wallet_notifications, .init = initialize_setup)
172
58
{
173
59
FuzzedDataProvider fuzzed_data_provider{buffer.data (), buffer.size ()};
@@ -176,10 +62,12 @@ FUZZ_TARGET(wallet_notifications, .init = initialize_setup)
176
62
// total amount.
177
63
const auto total_amount{ConsumeMoney (fuzzed_data_provider, /* max=*/ MAX_MONEY / 100000 )};
178
64
FuzzedWallet a{
65
+ *g_setup->m_node .chain ,
179
66
" fuzzed_wallet_a" ,
180
67
" tprv8ZgxMBicQKsPd1QwsGgzfu2pcPYbBosZhJknqreRHgsWx32nNEhMjGQX2cgFL8n6wz9xdDYwLcs78N4nsCo32cxEX8RBtwGsEGgybLiQJfk" ,
181
68
};
182
69
FuzzedWallet b{
70
+ *g_setup->m_node .chain ,
183
71
" fuzzed_wallet_b" ,
184
72
" tprv8ZgxMBicQKsPfCunYTF18sEmEyjz8TfhGnZ3BoVAhkqLv7PLkQgmoG2Ecsp4JuqciWnkopuEwShit7st743fdmB9cMD4tznUkcs33vK51K9" ,
185
73
};
0 commit comments