50 void initialize_setup()
52 static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
53 g_setup = testing_setup.get();
56 void ImportDescriptors(CWallet&
wallet,
const std::string& seed_insecure)
58 const std::vector<std::string> DESCS{
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})};
71 auto parsed_desc =
Parse(descriptor, keys, error,
false);
74 assert(parsed_desc->IsRange());
75 assert(parsed_desc->IsSingleType());
77 WalletDescriptor w_desc{std::move(parsed_desc), 0, 0, 1, 0};
80 auto spk_manager{
wallet.AddWalletDescriptor(w_desc, keys,
"",
internal)};
82 wallet.AddActiveScriptPubKeyMan(spk_manager->GetID(), *
Assert(w_desc.descriptor->GetOutputType()),
internal);
92 FuzzedWallet(
const std::string&
name,
const std::string& seed_insecure)
99 auto height{*
Assert(chain.getHeight())};
100 wallet->SetLastBlockProcessed(height, chain.getBlockHash(height));
102 wallet->m_keypool_size = 1;
104 ImportDescriptors(*
wallet, seed_insecure);
111 op_dest =
wallet->GetNewDestination(type,
"");
113 op_dest =
wallet->GetNewChangeDestination(type);
124 std::set<int> subtract_fee_from_outputs;
126 for (
size_t i{}; i < tx.
vout.size(); ++i) {
128 subtract_fee_from_outputs.insert(i);
132 std::vector<CRecipient> recipients;
133 for (
size_t idx = 0; idx < tx.
vout.size(); idx++) {
137 CRecipient recipient = {dest, tx_out.
nValue, subtract_fee_from_outputs.count(idx) == 1};
138 recipients.push_back(recipient);
140 CCoinControl coin_control;
141 coin_control.m_allow_other_inputs = fuzzed_data_provider.
ConsumeBool();
143 fuzzed_data_provider, [&] { coin_control.destChange = GetDestination(fuzzed_data_provider); },
146 coin_control.fAllowWatchOnly = fuzzed_data_provider.
ConsumeBool();
147 coin_control.m_include_unsafe_inputs = fuzzed_data_provider.
ConsumeBool();
149 auto& r{coin_control.m_signal_bip125_rbf};
151 fuzzed_data_provider, [&] { r =
true; }, [&] { r =
false; }, [&] { r = std::nullopt; });
161 coin_control.fOverrideFeeRate = fuzzed_data_provider.
ConsumeBool();
182 "tprv8ZgxMBicQKsPd1QwsGgzfu2pcPYbBosZhJknqreRHgsWx32nNEhMjGQX2cgFL8n6wz9xdDYwLcs78N4nsCo32cxEX8RBtwGsEGgybLiQJfk",
186 "tprv8ZgxMBicQKsPfCunYTF18sEmEyjz8TfhGnZ3BoVAhkqLv7PLkQgmoG2Ecsp4JuqciWnkopuEwShit7st743fdmB9cMD4tznUkcs33vK51K9",
193 using Coins = std::set<std::tuple<CAmount, COutPoint>>;
194 std::vector<std::tuple<Coins, CBlock>> chain;
197 chain.emplace_back();
198 auto& [coins, block]{chain.back()};
204 fuzzed_data_provider,
206 auto& [coins_orig, block]{chain.back()};
208 Coins coins = coins_orig;
209 while (!coins.empty()) {
211 CMutableTransaction tx{};
213 auto num_inputs{fuzzed_data_provider.ConsumeIntegralInRange<int>(1, coins.size())};
215 while (num_inputs-- > 0) {
216 const auto& [coin_amt, coin_outpoint]{*coins.begin()};
218 tx.
vin.emplace_back(coin_outpoint);
219 coins.erase(coins.begin());
224 const auto out_value{
ConsumeMoney(fuzzed_data_provider, in)};
227 tx.
vout.emplace_back(out_value,
wallet.GetScriptPubKey(fuzzed_data_provider));
231 tx.
vout.emplace_back(in,
wallet.GetScriptPubKey(fuzzed_data_provider));
235 a.FundTx(fuzzed_data_provider, tx);
236 b.FundTx(fuzzed_data_provider, tx);
239 const uint256& hash = block.GetHash();
241 info.prev_hash = &block.hashPrevBlock;
242 info.height = chain.
size();
247 info.chain_time_max = std::numeric_limits<unsigned int>::max();
252 for (
const auto& tx : block.vtx) {
254 for (
const auto&
out : tx->
vout) {
255 coins_new.emplace(
out.nValue,
COutPoint{tx->GetHash(), i++});
258 chain.emplace_back(coins_new,
CBlock{});
261 if (chain.size() <= 1)
return;
262 auto& [coins, block]{chain.back()};
263 if (block.vtx.empty())
return;
265 const uint256& hash = block.GetHash();
267 info.prev_hash = &block.hashPrevBlock;
268 info.height = chain.
size() - 1;
270 a.wallet->blockDisconnected(info);
271 b.wallet->blockDisconnected(info);
274 auto& [coins, first_block]{chain.front()};
275 if (!first_block.vtx.empty()) {
279 assert(total_amount == bal_a + bal_b);
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
static constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
int64_t CAmount
Amount in satoshis (Can be negative)
#define Assert(val)
Identity function.
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
An outpoint - a combination of a transaction hash and an index n into its vout.
Serialized script, used inside transaction inputs and outputs.
The basic transaction that is broadcasted on the network and contained in blocks.
An output of a transaction.
T ConsumeIntegralInRange(T min, T max)
T PickValueInArray(const T(&array)[size])
static constexpr unsigned int size()
static transaction_identifier FromUint256(const uint256 &id)
static UniValue Parse(std::string_view raw)
Parse string to UniValue or throw runtime_error if string contains invalid JSON.
#define LIMITED_WHILE(condition, limit)
Can be used to limit a theoretically unbounded loop.
Balance GetBalance(const CWallet &wallet, const int min_depth, bool avoid_reuse)
CreatedTransactionResult FundTransaction(CWallet &wallet, const CMutableTransaction &tx, const std::vector< CRecipient > &recipients, const UniValue &options, CCoinControl &coinControl, bool override_min_fee)
CFeeRate GetMinimumFeeRate(const CWallet &wallet, const CCoinControl &coin_control, FeeCalculation *feeCalc)
Estimate the minimum fee rate considering user set parameters and the required fee.
FUZZ_TARGET(coin_grinder)
std::unique_ptr< WalletDatabase > CreateMockableWalletDatabase(MockableData records)
@ WALLET_FLAG_DESCRIPTORS
Indicate that this wallet supports DescriptorScriptPubKeyMan.
std::shared_ptr< CWallet > wallet
static constexpr auto OUTPUT_TYPES
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop)
Compute the virtual transaction size (weight reinterpreted as bytes).
static CTransactionRef MakeTransactionRef(Tx &&txIn)
A mutable version of CTransaction.
std::vector< CTxOut > vout
std::map< CKeyID, CKey > keys
Testing setup that configures a complete environment.
Block data sent with blockConnected, blockDisconnected notifications.
std::unique_ptr< interfaces::Chain > chain
CAmount m_mine_trusted
Trusted, at depth=GetBalance.min_depth or more.
CAmount ConsumeMoney(FuzzedDataProvider &fuzzed_data_provider, const std::optional< CAmount > &max) noexcept
size_t CallOneOf(FuzzedDataProvider &fuzzed_data_provider, Callables... callables)