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.
1// Copyright (c) 2020-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <banman.h>6#include <common/args.h>7#include <netaddress.h>8#include <test/fuzz/FuzzedDataProvider.h>9#include <test/fuzz/fuzz.h>10#include <test/fuzz/util.h>11#include <test/fuzz/util/net.h>12#include <test/util/setup_common.h>13#include <test/util/time.h>14#include <util/fs.h>15#include <util/readwritefile.h>17#include <cassert>18#include <cstdint>19#include <limits>20#include <string>21#include <vector>23namespace {24int64_t ConsumeBanTimeOffset(FuzzedDataProvider& fuzzed_data_provider) noexcept25{26// Avoid signed integer overflow by capping to int32_t max:27// banman.cpp:137:73: runtime error: signed integer overflow: 1591700817 + 9223372036854775807 cannot be represented in type 'long'28return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(std::numeric_limits<int64_t>::min(), std::numeric_limits<int32_t>::max());29}30} // namespace32void initialize_banman()33{34static const auto testing_setup = MakeNoLogFileContext<>();35}37static bool operator==(const CBanEntry& lhs, const CBanEntry& rhs)38{39return lhs.nVersion == rhs.nVersion &&40lhs.nCreateTime == rhs.nCreateTime &&41lhs.nBanUntil == rhs.nBanUntil;42}44FUZZ_TARGET(banman, .init = initialize_banman)45{46SeedRandomStateForTest(SeedRand::ZEROS);47FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};48FakeNodeClock clock{ConsumeTime(fuzzed_data_provider)};49fs::path banlist_file = gArgs.GetDataDirNet() / "fuzzed_banlist";51const bool start_with_corrupted_banlist{fuzzed_data_provider.ConsumeBool()};52bool force_read_and_write_to_err{false};53if (start_with_corrupted_banlist) {54assert(WriteBinaryFile(banlist_file + ".json",55fuzzed_data_provider.ConsumeRandomLengthString()));56} else {57force_read_and_write_to_err = fuzzed_data_provider.ConsumeBool();58if (force_read_and_write_to_err) {59banlist_file = fs::path{"path"} / "to" / "inaccessible" / "fuzzed_banlist";60}61}63{64BanMan ban_man{banlist_file, /*client_interface=*/nullptr, /*default_ban_time=*/ConsumeBanTimeOffset(fuzzed_data_provider)};65// The complexity is O(N^2), where N is the input size, because each call66// might call DumpBanlist (or other methods that are at least linear67// complexity of the input size).68bool contains_invalid{false};69LIMITED_WHILE (fuzzed_data_provider.ConsumeBool(), 300) {70CallOneOf(71fuzzed_data_provider,72[&] {73CNetAddr net_addr{ConsumeNetAddr(fuzzed_data_provider)};74if (!net_addr.IsCJDNS() || !net_addr.IsValid()) {75const std::optional<CNetAddr>& addr{LookupHost(net_addr.ToStringAddr(), /*fAllowLookup=*/false)};76if (addr.has_value() && addr->IsValid()) {77net_addr = *addr;78} else {79contains_invalid = true;80}81}82auto ban_time_offset = ConsumeBanTimeOffset(fuzzed_data_provider);83auto since_unix_epoch = fuzzed_data_provider.ConsumeBool();84ban_man.Ban(net_addr, ban_time_offset, since_unix_epoch);85},86[&] {87CSubNet subnet{ConsumeSubNet(fuzzed_data_provider)};88subnet = LookupSubNet(subnet.ToString());89if (!subnet.IsValid()) {90contains_invalid = true;91}92auto ban_time_offset = ConsumeBanTimeOffset(fuzzed_data_provider);93auto since_unix_epoch = fuzzed_data_provider.ConsumeBool();94ban_man.Ban(subnet, ban_time_offset, since_unix_epoch);95},96[&] {97ban_man.ClearBanned();98},99[&] {100ban_man.IsBanned(ConsumeNetAddr(fuzzed_data_provider));101},102[&] {103ban_man.IsBanned(ConsumeSubNet(fuzzed_data_provider));104},105[&] {106ban_man.Unban(ConsumeNetAddr(fuzzed_data_provider));107},108[&] {109ban_man.Unban(ConsumeSubNet(fuzzed_data_provider));110},111[&] {112banmap_t banmap;113ban_man.GetBanned(banmap);114},115[&] {116ban_man.DumpBanlist();117},118[&] {119ban_man.Discourage(ConsumeNetAddr(fuzzed_data_provider));120},121[&] {122ban_man.IsDiscouraged(ConsumeNetAddr(fuzzed_data_provider));123});124}125if (!force_read_and_write_to_err) {126ban_man.DumpBanlist();127clock.set(ConsumeTime(fuzzed_data_provider));128banmap_t banmap;129ban_man.GetBanned(banmap);130BanMan ban_man_read{banlist_file, /*client_interface=*/nullptr, /*default_ban_time=*/0};131banmap_t banmap_read;132ban_man_read.GetBanned(banmap_read);133if (!contains_invalid) {134assert(banmap == banmap_read);135}136}137}138fs::remove(fs::PathToString(banlist_file + ".json"));139}
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.