From f611d3bdaf035280f44d5183a8322c0a0c6e3d27 Mon Sep 17 00:00:00 2001 From: brunoerg Date: Mon, 16 Feb 2026 16:05:23 -0300 Subject: [PATCH 1/2] refactor: addrman: move consts to .h --- src/addrman.cpp | 20 -------------------- src/addrman.h | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 2e5149093c4..e3981e6a404 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -24,26 +24,6 @@ #include #include -/** Over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread */ -static constexpr uint32_t ADDRMAN_TRIED_BUCKETS_PER_GROUP{8}; -/** Over how many buckets entries with new addresses originating from a single group are spread */ -static constexpr uint32_t ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP{64}; -/** Maximum number of times an address can occur in the new table */ -static constexpr int32_t ADDRMAN_NEW_BUCKETS_PER_ADDRESS{8}; -/** How old addresses can maximally be */ -static constexpr auto ADDRMAN_HORIZON{30 * 24h}; -/** After how many failed attempts we give up on a new node */ -static constexpr int32_t ADDRMAN_RETRIES{3}; -/** How many successive failures are allowed ... */ -static constexpr int32_t ADDRMAN_MAX_FAILURES{10}; -/** ... in at least this duration */ -static constexpr auto ADDRMAN_MIN_FAIL{7 * 24h}; -/** How recent a successful connection should be before we allow an address to be evicted from tried */ -static constexpr auto ADDRMAN_REPLACEMENT{4h}; -/** The maximum number of tried addr collisions to store */ -static constexpr size_t ADDRMAN_SET_TRIED_COLLISION_SIZE{10}; -/** The maximum time we'll spend trying to resolve a tried table collision */ -static constexpr auto ADDRMAN_TEST_WINDOW{40min}; int AddrInfo::GetTriedBucket(const uint256& nKey, const NetGroupManager& netgroupman) const { diff --git a/src/addrman.h b/src/addrman.h index 8368e30b7b7..94e7d3e6537 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -19,6 +19,27 @@ #include #include +/** Over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread */ +static constexpr uint32_t ADDRMAN_TRIED_BUCKETS_PER_GROUP{8}; +/** Over how many buckets entries with new addresses originating from a single group are spread */ +static constexpr uint32_t ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP{64}; +/** Maximum number of times an address can occur in the new table */ +static constexpr int32_t ADDRMAN_NEW_BUCKETS_PER_ADDRESS{8}; +/** How old addresses can maximally be */ +static constexpr auto ADDRMAN_HORIZON{30 * 24h}; +/** After how many failed attempts we give up on a new node */ +static constexpr int32_t ADDRMAN_RETRIES{3}; +/** How many successive failures are allowed ... */ +static constexpr int32_t ADDRMAN_MAX_FAILURES{10}; +/** ... in at least this duration */ +static constexpr auto ADDRMAN_MIN_FAIL{7 * 24h}; +/** How recent a successful connection should be before we allow an address to be evicted from tried */ +static constexpr auto ADDRMAN_REPLACEMENT{4h}; +/** The maximum number of tried addr collisions to store */ +static constexpr size_t ADDRMAN_SET_TRIED_COLLISION_SIZE{10}; +/** The maximum time we'll spend trying to resolve a tried table collision */ +static constexpr auto ADDRMAN_TEST_WINDOW{40min}; + class InvalidAddrManVersionError : public std::ios_base::failure { public: From 6202acd284bc0284fc9b144fdc39774f112fcdf2 Mon Sep 17 00:00:00 2001 From: brunoerg Date: Mon, 16 Feb 2026 15:56:35 -0300 Subject: [PATCH 2/2] test: addrman: successive failures in the last week for IsTerrible --- src/test/addrman_tests.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index a085c1f5a98..e9069079f1f 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -93,6 +93,42 @@ BOOST_AUTO_TEST_CASE(addrman_simple) BOOST_CHECK(addrman->Size() >= 1); } + +BOOST_AUTO_TEST_CASE(addrman_terrible_many_failures) +{ + auto now = Now(); + SetMockTime(now - (ADDRMAN_MIN_FAIL + 24h)); + + auto addrman{std::make_unique(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node))}; + + CNetAddr source{ResolveIP("250.1.2.1")}; + CAddress addr{CAddress(ResolveService("250.250.2.1", 8333), NODE_NONE)}; + addr.nTime = Now(); + + BOOST_CHECK(addrman->Add({addr}, source)); + BOOST_CHECK(addrman->Good(addr)); + + SetMockTime(now); + + CAddress addr_helper{CAddress(ResolveService("251.252.2.3", 8333), NODE_NONE)}; + addr_helper.nTime = Now(); + BOOST_CHECK(addrman->Add({addr_helper}, source)); + BOOST_CHECK(addrman->Good(addr_helper)); + + for (int i = 0; i < ADDRMAN_MAX_FAILURES; ++i) { + // Use a time > 60s ago so IsTerrible doesn't bail out at the "tried in the last minute" check + addrman->Attempt(addr, /*fCountFailure=*/true, Now() - 61s); + } + + std::vector filtered{addrman->GetAddr(/*max_addresses=*/0, /*max_pct=*/0, /*network=*/std::nullopt)}; + BOOST_CHECK_EQUAL(filtered.size(), 1U); + BOOST_CHECK_EQUAL(filtered[0].ToStringAddrPort(), "251.252.2.3:8333"); + + std::vector unfiltered{addrman->GetAddr(/*max_addresses=*/0, /*max_pct=*/0, /*network=*/std::nullopt, /*filtered=*/false)}; + BOOST_CHECK_EQUAL(unfiltered.size(), 2U); +} + + BOOST_AUTO_TEST_CASE(addrman_penalty_self_announcement) { SetMockTime(Now());