Repository: bitcoin/bitcoin
File: src/wallet/test/fuzz/notifications.cpp (C++)

Code before:
#include <wallet/test/util.h>
#include <wallet/wallet.h>
#include <wallet/walletutil.h>

#include <cstddef>
#include <cstdint>
#include <limits>
#include <numeric>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

namespace wallet {
namespace {
const TestingSetup* g_setup;

void initialize_setup()
{
    static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
    g_setup = testing_setup.get();
}

void ImportDescriptors(CWallet& wallet, const std::string& seed_insecure)
{
    const std::vector<std::string> DESCS{
        "pkh(%s/%s/*)",
        "sh(wpkh(%s/%s/*))",
        "tr(%s/%s/*)",
        "wpkh(%s/%s/*)",
    };

    for (const std::string& desc_fmt : DESCS) {
        for (bool internal : {true, false}) {
            const auto descriptor{(strprintf)(desc_fmt, "[5aa9973a/66h/4h/2h]" + seed_insecure, int{internal})};

            FlatSigningProvider keys;
            std::string error;
            auto parsed_desc = std::move(Parse(descriptor, keys, error, /*require_checksum=*/false).at(0));
            assert(parsed_desc);
            assert(error.empty());
            assert(parsed_desc->IsRange());
            assert(parsed_desc->IsSingleType());
            assert(!keys.keys.empty());
            WalletDescriptor w_desc{std::move(parsed_desc), /*creation_time=*/0, /*range_start=*/0, /*range_end=*/1, /*next_index=*/0};
            assert(!wallet.GetDescriptorScriptPubKeyMan(w_desc));
            LOCK(wallet.cs_wallet);
            auto spk_manager{wallet.AddWalletDescriptor(w_desc, keys, /*label=*/"", internal)};
            assert(spk_manager);
            wallet.AddActiveScriptPubKeyMan(spk_manager->GetID(), *Assert(w_desc.descriptor->GetOutputType()), internal);

Review comment (bug):
Maybe move this to util.cpp as well? In theory it is the wrong place, because it depends on `FuzzedDataProvider`, but I think this isn't too important in tests.

Code after:
#include <wallet/spend.h>
#include <wallet/test/util.h>
#include <wallet/wallet.h>
#include <wallet/walletutil.h>

#include <cstddef>
#include <cstdint>
#include <limits>
#include <numeric>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

namespace wallet {
namespace {
const TestingSetup* g_setup;

void initialize_setup()
{
    static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
    g_setup = testing_setup.get();
}

FUZZ_TARGET(wallet_notifications, .init = initialize_setup)
{
    FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
    // The total amount, to be distributed to the wallets a and b in txs
    // without fee. Thus, the balance of the wallets should always equal the
    // total amount.
    const auto total_amount{ConsumeMoney(fuzzed_data_provider, /*max=*/MAX_MONEY / 100000)};
    FuzzedWallet a{
        *g_setup->m_node.chain,
        "fuzzed_wallet_a",
        "tprv8ZgxMBicQKsPd1QwsGgzfu2pcPYbBosZhJknqreRHgsWx32nNEhMjGQX2cgFL8n6wz9xdDYwLcs78N4nsCo32cxEX8RBtwGsEGgybLiQJfk",
    };
    FuzzedWallet b{
        *g_setup->m_node.chain,
        "fuzzed_wallet_b",
        "tprv8ZgxMBicQKsPfCunYTF18sEmEyjz8TfhGnZ3BoVAhkqLv7PLkQgmoG2Ecsp4JuqciWnkopuEwShit7st743fdmB9cMD4tznUkcs33vK51K9",
    };

    // Keep track of all coins in this test.
    // Each tuple in the chain represents the coins and the block created with
    // those coins. Once the block is mined, the next tuple will have an empty
    // block and the freshly mined coins.
    using Coins = std::set<std::tuple<CAmount, COutPoint>>;
    std::vector<std::tuple<Coins, CBlock>> chain;
    {
        // Add the initial entry