Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251r = UniValue{EncodeBase32(fuzzed_data_provider.ConsumeRandomLengthString(max_string_length))};252},253[&] {254// base58 argument255r = UniValue{EncodeBase58(MakeUCharSpan(fuzzed_data_provider.ConsumeRandomLengthString(max_base58_bytes_length)))};256},257[&] {258// base58 argument with checksum259r = UniValue{EncodeBase58Check(MakeUCharSpan(fuzzed_data_provider.ConsumeRandomLengthString(max_base58_bytes_length)))};260},261[&] {262// hex encoded block263std::optional<CBlock> opt_block = ConsumeDeserializable<CBlock>(fuzzed_data_provider, TX_WITH_WITNESS);264if (!opt_block) {265good_data = false;266return;267}268DataStream data_stream{};269data_stream << TX_WITH_WITNESS(*opt_block);270r = UniValue{HexStr(data_stream)};271},272[&] {273// hex encoded block header274std::optional<CBlockHeader> opt_block_header = ConsumeDeserializable<CBlockHeader>(fuzzed_data_provider);275if (!opt_block_header) {276good_data = false;277return;278}279DataStream data_stream{};280data_stream << *opt_block_header;281r = UniValue{HexStr(data_stream)};282},283[&] {284// hex encoded tx285std::optional<CMutableTransaction> opt_tx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);286if (!opt_tx) {287good_data = false;288return;289}290DataStream data_stream;291auto allow_witness = (fuzzed_data_provider.ConsumeBool() ? TX_WITH_WITNESS : TX_NO_WITNESS);292data_stream << allow_witness(*opt_tx);293r = UniValue{HexStr(data_stream)};294},295[&] {296// base64 encoded psbt297std::optional<PartiallySignedTransaction> opt_psbt = ConsumeDeserializableConstructor<PartiallySignedTransaction>(fuzzed_data_provider);298if (!opt_psbt) {299good_data = false;300return;301}302DataStream data_stream{};303data_stream << *opt_psbt;304r = UniValue{EncodeBase64(data_stream)};305},306[&] {307// base58 encoded key308CKey key = ConsumePrivateKey(fuzzed_data_provider);309if (!key.IsValid()) {310good_data = false;311return;312}313r = UniValue{EncodeSecret(key)};314},315[&] {316// hex encoded pubkey317CKey key = ConsumePrivateKey(fuzzed_data_provider);318if (!key.IsValid()) {319good_data = false;320return;321}322r = UniValue{HexStr(key.GetPubKey())};323});324return r;325}327constexpr int MAX_RPC_ARGUMENT_NESTING{9};329// NOLINTBEGIN(misc-no-recursion)330UniValue ConsumeRPCArgument(FuzzedDataProvider& fuzzed_data_provider, bool& good_data, int nesting_depth)331{332if (nesting_depth == 0) {333return ConsumeBasicRPCArgument(fuzzed_data_provider, good_data);334}335UniValue argument{};336std::vector<std::function<void()>> mks{337[&] { argument = ConsumeBasicRPCArgument(fuzzed_data_provider, good_data); },338[&] {339argument = UniValue(UniValue::VARR);340LIMITED_WHILE (good_data && fuzzed_data_provider.ConsumeBool(), 100) {341argument.push_back(ConsumeRPCArgument(fuzzed_data_provider, good_data, nesting_depth - 1));342}343},344[&] {345argument = UniValue(UniValue::VOBJ);346LIMITED_WHILE (good_data && fuzzed_data_provider.ConsumeBool(), 100) {347argument.pushKV(fuzzed_data_provider.ConsumeRandomLengthString(128),348ConsumeRPCArgument(fuzzed_data_provider, good_data, nesting_depth - 1));349}350},351};352PickValue(fuzzed_data_provider, mks)();353return argument;354}355// NOLINTEND(misc-no-recursion)357RPCFuzzTestingSetup* InitializeRPCFuzzTestingSetup()358{359static const auto setup = MakeNoLogFileContext<RPCFuzzTestingSetup>();360SetRPCWarmupFinished();361return setup.get();362}363}; // namespace365void initialize_rpc()366{367rpc_testing_setup = InitializeRPCFuzzTestingSetup();368const std::vector<std::string> supported_rpc_commands = rpc_testing_setup->GetRPCCommands();369for (const std::string& rpc_command : supported_rpc_commands) {370const bool safe_for_fuzzing = std::find(RPC_COMMANDS_SAFE_FOR_FUZZING.begin(), RPC_COMMANDS_SAFE_FOR_FUZZING.end(), rpc_command) != RPC_COMMANDS_SAFE_FOR_FUZZING.end();371const bool not_safe_for_fuzzing = std::find(RPC_COMMANDS_NOT_SAFE_FOR_FUZZING.begin(), RPC_COMMANDS_NOT_SAFE_FOR_FUZZING.end(), rpc_command) != RPC_COMMANDS_NOT_SAFE_FOR_FUZZING.end();372if (!(safe_for_fuzzing || not_safe_for_fuzzing)) {373std::cerr << "Error: RPC command \"" << rpc_command << "\" not found in RPC_COMMANDS_SAFE_FOR_FUZZING or RPC_COMMANDS_NOT_SAFE_FOR_FUZZING. Please update " << __FILE__ << ".\n";374std::terminate();375}376if (safe_for_fuzzing && not_safe_for_fuzzing) {377std::cerr << "Error: RPC command \"" << rpc_command << "\" found in *both* RPC_COMMANDS_SAFE_FOR_FUZZING and RPC_COMMANDS_NOT_SAFE_FOR_FUZZING. Please update " << __FILE__ << ".\n";378std::terminate();379}380}381const char* limit_to_rpc_command_env = std::getenv("LIMIT_TO_RPC_COMMAND");382if (limit_to_rpc_command_env != nullptr) {383g_limit_to_rpc_command = std::string{limit_to_rpc_command_env};384}385}387FUZZ_TARGET(rpc, .init = initialize_rpc)388{389SeedRandomStateForTest(SeedRand::ZEROS);390FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};391bool good_data{true};392FakeNodeClock clock{ConsumeTime(fuzzed_data_provider)};393const std::string rpc_command = fuzzed_data_provider.ConsumeRandomLengthString(64);394if (!g_limit_to_rpc_command.empty() && rpc_command != g_limit_to_rpc_command) {395return;396}397const bool safe_for_fuzzing = std::find(RPC_COMMANDS_SAFE_FOR_FUZZING.begin(), RPC_COMMANDS_SAFE_FOR_FUZZING.end(), rpc_command) != RPC_COMMANDS_SAFE_FOR_FUZZING.end();398if (!safe_for_fuzzing) {399return;400}401UniValue arguments(UniValue::VARR);402LIMITED_WHILE (good_data && fuzzed_data_provider.ConsumeBool(), 100) {403arguments.push_back(ConsumeRPCArgument(fuzzed_data_provider, good_data, MAX_RPC_ARGUMENT_NESTING));404}405try {406std::optional<test_only_CheckFailuresAreExceptionsNotAborts> maybe_mock{};407if (rpc_command == "echo") {408// Avoid aborting fuzzing for this specific test-only RPC with an409// intentional trigger_internal_bug410maybe_mock.emplace();411}412rpc_testing_setup->CallRPC(rpc_command, std::move(arguments));413} catch (const UniValue& json_rpc_error) {414const std::string error_msg{json_rpc_error.find_value("message").get_str()};415if (error_msg.starts_with("Internal bug detected")) {416// Only allow the intentional internal bug417assert(error_msg.find("trigger_internal_bug") != std::string::npos);418}419}420}
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.