8#include <chainparams.h>
14#include <test/data/asmap.raw.h>
21#include <boost/test/unit_test.hpp>
27using namespace std::literals;
36 return std::clamp<int32_t>(node_ctx.
args->
GetIntArg(
"-checkaddrman", 100), 0, 1000000);
41 const std::optional<CNetAddr> addr{
LookupHost(
ip,
false)};
42 BOOST_CHECK_MESSAGE(addr.has_value(),
strprintf(
"failed to resolve: %s",
ip));
48 const std::optional<CService> serv{
Lookup(
ip, port,
false)};
49 BOOST_CHECK_MESSAGE(serv.has_value(),
strprintf(
"failed to resolve: %s:%i",
ip, port));
63 auto addr_null = addrman->Select().first;
70 auto addr_ret1 = addrman->Select().first;
92 std::vector<CAddress> vAddr;
108 addr.
nTime = Now<NodeSeconds>();
116 addr_helper.
nTime = Now<NodeSeconds>();
122 addrman->Attempt(addr,
true, Now<NodeSeconds>() - 61
s);
125 std::vector<CAddress> filtered{addrman->GetAddr(0, 0, std::nullopt)};
129 std::vector<CAddress> unfiltered{addrman->GetAddr(0, 0, std::nullopt,
false)};
139 const auto base_time{Now<NodeSeconds>() - 10000
s};
144 caddr1.
nTime = base_time;
146 const auto time_penalty{3600
s};
148 BOOST_CHECK(addrman->Add({caddr1}, source1, time_penalty));
150 auto addr_pos1{addrman->FindAddressEntry(caddr1)};
151 BOOST_REQUIRE(addr_pos1.has_value());
153 std::vector<CAddress> addresses{addrman->GetAddr(0, 0, std::nullopt)};
154 BOOST_REQUIRE_EQUAL(addresses.size(), 1U);
162 caddr2.
nTime = base_time;
164 BOOST_CHECK(addrman->Add({caddr2}, source2, time_penalty));
166 addresses = addrman->GetAddr(0, 0, std::nullopt);
167 BOOST_REQUIRE_EQUAL(addresses.size(), 2U);
169 CAddress retrieved_addr2{addresses[0]};
170 BOOST_CHECK(retrieved_addr2.nTime == base_time - time_penalty);
189 auto addr_ret2 = addrman->Select().first;
190 BOOST_CHECK(addr_ret2.ToStringAddrPort() ==
"250.1.1.1:8333" || addr_ret2.ToStringAddrPort() ==
"250.1.1.1:8334");
196 bool new_only =
true;
197 auto addr_ret3 = addrman->Select(new_only).first;
204 BOOST_CHECK(!addrman->Select(
false).first.IsValid());
205 BOOST_CHECK(!addrman->Select(
true).first.IsValid());
221 BOOST_CHECK(!addrman->Select(
true).first.IsValid());
242 BOOST_CHECK(addrman->Add({CAddress(addr5, NODE_NONE)}, addr3));
244 BOOST_CHECK(addrman->Add({CAddress(addr6, NODE_NONE)}, addr3));
253 std::set<uint16_t> ports;
254 for (
int i = 0; i < 20; ++i) {
255 ports.insert(addrman->Select().first.GetPort());
263 BOOST_CHECK(!addrman->Select(
true, {NET_IPV4}).first.IsValid());
264 BOOST_CHECK(!addrman->Select(
false, {NET_IPV4}).first.IsValid());
273 BOOST_CHECK(!addrman->Select(
false, {NET_IPV6}).first.IsValid());
274 BOOST_CHECK(!addrman->Select(
false, {NET_ONION}).first.IsValid());
275 BOOST_CHECK(!addrman->Select(
false, {NET_I2P}).first.IsValid());
276 BOOST_CHECK(!addrman->Select(
false, {NET_CJDNS}).first.IsValid());
277 BOOST_CHECK(!addrman->Select(
true, {NET_CJDNS}).first.IsValid());
282 i2p_addr.
SetSpecial(
"udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p");
285 BOOST_CHECK(addrman->Select(
true, {NET_I2P}).first == i2p_addr);
286 BOOST_CHECK(addrman->Select(
false, {NET_I2P}).first == i2p_addr);
289 BOOST_CHECK(addrman->Select(
false, nets_with_entries).first.IsValid());
290 BOOST_CHECK(!addrman->Select(
false, {NET_IPV6}).first.IsValid());
291 BOOST_CHECK(!addrman->Select(
false, {NET_ONION}).first.IsValid());
292 BOOST_CHECK(!addrman->Select(
false, {NET_CJDNS}).first.IsValid());
294 BOOST_CHECK(!addrman->Select(
false, nets_without_entries).first.IsValid());
299 BOOST_CHECK(!addrman->Select(
true, {NET_I2P}).first.IsValid());
300 BOOST_CHECK(addrman->Select(
false, {NET_I2P}).first == i2p_addr);
304 i2p_addr2.
SetSpecial(
"c4gfnttsuwqomiygupdqqqyy5y5emnk5c73hrfvatri67prd7vyq.b32.i2p");
307 BOOST_CHECK(addrman->Select(
true, {NET_I2P}).first == i2p_addr2);
310 bool new_selected{
false};
311 bool tried_selected{
false};
314 while (--counter > 0 && (!new_selected || !tried_selected)) {
316 BOOST_REQUIRE(selected == i2p_addr || selected == i2p_addr2);
317 if (selected == i2p_addr) {
318 tried_selected =
true;
337 i2p_addr.
SetSpecial(
"udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p");
357 uint32_t num_addrs{0};
361 while (num_addrs < 22) {
371 uint32_t collisions{1};
384 const auto start_time{Now<NodeSeconds>()};
385 addr.
nTime = start_time;
388 for (
unsigned int i = 1; i < 20; ++i) {
389 std::string addr_ip{
ToString(i % 256) +
"." +
ToString(i >> 8 % 256) +
".1.1"};
391 addrman->Add({addr},
source);
400 for (
unsigned int i = 1; i < 400; ++i) {
401 std::string addr_ip{
ToString(i % 256) +
"." +
ToString(i >> 8 % 256) +
".1.1"};
403 addr.nTime = start_time + std::chrono::seconds{i};
404 addrman->Add({addr},
source);
406 AddressPosition addr_pos_multi = addrman->FindAddressEntry(addr).value();
418 uint32_t num_addrs{0};
422 while (num_addrs < 35) {
450 std::vector<CAddress> vAddr1 = addrman->GetAddr(0, 0, std::nullopt);
454 addr1.nTime = Now<NodeSeconds>();
456 addr2.nTime = Now<NodeSeconds>();
458 addr3.
nTime = Now<NodeSeconds>();
460 addr4.
nTime = Now<NodeSeconds>();
462 addr5.
nTime = Now<NodeSeconds>();
467 BOOST_CHECK(addrman->Add({addr1, addr3, addr5}, source1));
468 BOOST_CHECK(addrman->Add({addr2, addr4}, source2));
481 for (
unsigned int i = 1; i < (8 * 256); i++) {
482 int octet1 = i % 256;
483 int octet2 = i >> 8 % 256;
488 addr.
nTime = Now<NodeSeconds>();
489 addrman->Add({addr},
ResolveIP(strAddr));
493 std::vector<CAddress> vAddr = addrman->GetAddr(2500, 23, std::nullopt);
495 size_t percent23 = (addrman->Size() * 23) / 100;
508 addr1.nTime = Now<NodeSeconds>();
517 addr3.
nTime = Now<NodeSeconds>();
518 addrman->Good(addr3, Now<NodeSeconds>());
522 for (
size_t i = 0; i < 3; ++i) {
523 addrman->Attempt(addr3,
true, Now<NodeSeconds>() - 61
s);
529 addr4.
nTime = Now<NodeSeconds>() + 11min;
564 std::set<int> buckets;
565 for (
int i = 0; i < 255; i++) {
570 buckets.insert(bucket);
577 for (
int j = 0; j < 255; j++) {
582 buckets.insert(bucket);
614 std::set<int> buckets;
615 for (
int i = 0; i < 255; i++) {
620 buckets.insert(bucket);
627 for (
int j = 0; j < 4 * 255; j++) {
633 buckets.insert(bucket);
640 for (
int p = 0; p < 255; p++) {
645 buckets.insert(bucket);
691 std::set<int> buckets;
692 for (
int j = 0; j < 255; j++) {
697 buckets.insert(bucket);
704 for (
int j = 0; j < 255; j++) {
709 buckets.insert(bucket);
743 std::set<int> buckets;
744 for (
int i = 0; i < 255; i++) {
749 buckets.insert(bucket);
756 for (
int j = 0; j < 4 * 255; j++) {
762 buckets.insert(bucket);
769 for (
int p = 0; p < 255; p++) {
774 buckets.insert(bucket);
781 for (
int p = 0; p < 255; p++) {
786 buckets.insert(bucket);
798 auto addrman_asmap1 = std::make_unique<AddrMan>(netgroupman,
DETERMINISTIC, ratio);
799 auto addrman_asmap1_dup = std::make_unique<AddrMan>(netgroupman,
DETERMINISTIC, ratio);
807 addrman_asmap1->Add({addr}, default_source);
809 stream << *addrman_asmap1;
811 stream >> *addrman_asmap1_dup;
813 AddressPosition addr_pos1 = addrman_asmap1->FindAddressEntry(addr).value();
814 AddressPosition addr_pos2 = addrman_asmap1_dup->FindAddressEntry(addr).value();
821 stream << *addrman_asmap1;
822 stream >> *addrman_noasmap;
823 AddressPosition addr_pos3 = addrman_noasmap->FindAddressEntry(addr).value();
829 addrman_asmap1 = std::make_unique<AddrMan>(netgroupman,
DETERMINISTIC, ratio);
831 addrman_noasmap->Add({addr}, default_source);
832 stream << *addrman_noasmap;
833 stream >> *addrman_asmap1;
835 AddressPosition addr_pos4 = addrman_asmap1->FindAddressEntry(addr).value();
841 addrman_asmap1 = std::make_unique<AddrMan>(netgroupman,
DETERMINISTIC, ratio);
845 addrman_noasmap->Add({addr,
addr2}, default_source);
849 stream << *addrman_noasmap;
850 stream >> *addrman_asmap1;
869 addrman->Add({new1, tried1, new2, tried2},
CNetAddr{});
870 addrman->Good(tried1);
871 addrman->Good(tried2);
872 BOOST_REQUIRE_EQUAL(addrman->Size(), 4);
876 const std::string str{stream.str()};
879 const char new2_raw[]{6, 6, 6, 6};
880 const uint8_t new2_raw_replacement[]{0, 0, 0, 0};
881 pos = str.find(new2_raw, 0,
sizeof(new2_raw));
882 BOOST_REQUIRE(pos != std::string::npos);
883 BOOST_REQUIRE(pos +
sizeof(new2_raw_replacement) <= stream.size());
884 memcpy(stream.data() + pos, new2_raw_replacement,
sizeof(new2_raw_replacement));
886 const char tried2_raw[]{8, 8, 8, 8};
887 const uint8_t tried2_raw_replacement[]{255, 255, 255, 255};
888 pos = str.find(tried2_raw, 0,
sizeof(tried2_raw));
889 BOOST_REQUIRE(pos != std::string::npos);
890 BOOST_REQUIRE(pos +
sizeof(tried2_raw_replacement) <= stream.size());
891 memcpy(stream.data() + pos, tried2_raw_replacement,
sizeof(tried2_raw_replacement));
905 BOOST_CHECK(addrman->SelectTriedCollision().first.ToStringAddrPort() ==
"[::]:0");
909 for (
unsigned int i = 1; i < 23; i++) {
915 BOOST_CHECK(addrman->SelectTriedCollision().first.ToStringAddrPort() ==
"[::]:0");
920 for (
unsigned int i = 1; i < 23; i++) {
927 BOOST_CHECK(addrman->SelectTriedCollision().first.ToStringAddrPort() ==
"[::]:0");
937 for (
unsigned int i = 1; i < 36; i++) {
949 BOOST_CHECK_EQUAL(addrman->SelectTriedCollision().first.ToStringAddrPort(),
"250.1.1.19:0");
954 addrman->ResolveCollisions();
955 BOOST_CHECK(addrman->SelectTriedCollision().first.ToStringAddrPort() ==
"[::]:0");
958 for (
unsigned int i = 37; i < 59; i++) {
969 BOOST_CHECK_EQUAL(addrman->SelectTriedCollision().first.ToStringAddrPort(),
"250.1.1.10:0");
976 BOOST_CHECK(addrman->SelectTriedCollision().first.ToStringAddrPort() !=
"[::]:0");
979 addrman->ResolveCollisions();
980 BOOST_CHECK(addrman->SelectTriedCollision().first.ToStringAddrPort() ==
"[::]:0");
990 BOOST_CHECK(addrman->SelectTriedCollision().first.ToStringAddrPort() ==
"[::]:0");
994 for (
unsigned int i = 1; i < 36; i++) {
1007 auto info = addrman->SelectTriedCollision().first;
1013 addrman->Attempt(info,
false, Now<NodeSeconds>() - 61
s);
1016 addrman->ResolveCollisions();
1017 BOOST_CHECK(addrman->SelectTriedCollision().first.ToStringAddrPort() ==
"[::]:0");
1026 BOOST_CHECK(addrman->SelectTriedCollision().first.ToStringAddrPort() ==
"[::]:0");
1032 BOOST_CHECK_EQUAL(addrman->SelectTriedCollision().first.ToStringAddrPort(),
"250.1.1.36:0");
1037 addrman->ResolveCollisions();
1038 BOOST_CHECK(addrman->SelectTriedCollision().first.ToStringAddrPort() ==
"[::]:0");
1050 ssPeersIn << addrman;
1058 std::optional<CService>
addr1,
addr2, addr3, addr4;
1063 addr3 =
Lookup(
"250.7.3.3", 9999,
false);
1065 addr3 =
Lookup(
"250.7.3.3"s, 9999,
false);
1067 addr4 =
Lookup(
"250.7.3.3\0example.com"s, 9999,
false);
1071 const std::optional<CService>
source{
Lookup(
"252.5.1.1", 8333,
false)};
1083 unsigned char pchMsgTmp[4];
1104 unsigned char nVersion = 1;
1106 s << ((
unsigned char)32);
1114 const std::optional<CService> serv{
Lookup(
"252.1.1.1", 7777,
false)};
1115 BOOST_REQUIRE(serv.has_value());
1117 std::optional<CNetAddr> resolved{
LookupHost(
"252.2.2.2",
false)};
1118 BOOST_REQUIRE(resolved.has_value());
1133 unsigned char pchMsgTmp[4];
1134 ssPeers1 >> pchMsgTmp;
1135 ssPeers1 >> addrman1;
1136 }(), std::ios_base::failure,
HasReason{
"end of data"});
1153 const auto start_time{Now<NodeSeconds>() - 10000
s};
1154 addr.nTime = start_time;
1160 addr_diff_port.
nTime = start_time;
1161 addrman->Connected(addr_diff_port);
1163 std::vector<CAddress> vAddr1{addrman->GetAddr(0, 0, std::nullopt)};
1169 addrman->Connected(addr);
1171 std::vector<CAddress> vAddr2 = addrman->GetAddr(0, 0, std::nullopt);
1173 BOOST_CHECK(vAddr2.at(0).nTime >= start_time + 10000
s);
1178 addr_v2.
nTime = start_time;
1180 std::vector<CAddress> vAddr3{addrman->GetAddr(0, 0, std::nullopt)};
1186 std::vector<CAddress> vAddr4{addrman->GetAddr(0, 0, std::nullopt)};
1192 std::vector<CAddress> vAddr5{addrman->GetAddr(0, 0, std::nullopt)};
1198 std::vector<CAddress> vAddr6{addrman->GetAddr(0, 0, std::nullopt)};
1230 i2p_addr.
SetSpecial(
"UDHDrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.I2P");
void ReadFromStream(AddrMan &addr, DataStream &ssPeers)
Only used by tests.
constexpr int32_t ADDRMAN_MAX_FAILURES
How many successive failures are allowed ...
constexpr auto ADDRMAN_MIN_FAIL
... in at least this duration
constexpr int ADDRMAN_NEW_BUCKET_COUNT
static CService ResolveService(const std::string &ip, uint16_t port=0)
static int32_t GetCheckRatio(const NodeContext &node_ctx)
static auto AddrmanToStream(const AddrMan &addrman)
static const bool DETERMINISTIC
BOOST_AUTO_TEST_CASE(addrman_simple)
static auto MakeCorruptPeersDat()
static auto EMPTY_NETGROUPMAN
static CNetAddr ResolveIP(const std::string &ip)
const CChainParams & Params()
Return the currently selected parameters.
Extended statistics about a CAddress.
int GetNewBucket(const uint256 &nKey, const CNetAddr &src, const NetGroupManager &netgroupman) const
Calculate in which "new" bucket this entry belongs, given a certain source.
int GetTriedBucket(const uint256 &nKey, const NetGroupManager &netgroupman) const
Calculate in which "tried" bucket this entry belongs.
Stochastic address manager.
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
A CService with information about it as peer.
NodeSeconds nTime
Always included in serialization. The behavior is unspecified if the value is not representable as ui...
static constexpr SerParams V1_DISK
const MessageStartChars & MessageStart() const
bool SetSpecial(std::string_view addr)
Parse a Tor or I2P address and set this object to it.
A combination of a network address (CNetAddr) and a (TCP) port.
std::vector< unsigned char > GetKey() const
Double ended buffer combining vector and stream-like interfaces.
Helper to initialize the global NodeClock, let a duration elapse, and reset it after use in a test.
BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
A writer stream (for serialization) that computes a 256-bit hash.
static NetGroupManager NoAsmap()
static NetGroupManager WithEmbeddedAsmap(std::span< const std::byte > asmap)
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
static CService ip(uint32_t i)
BOOST_CHECK_EQUAL(headers.FindFirst("key"), "value")
BOOST_CHECK_EXCEPTION(HTTPHeaders{}.Read(reader), std::runtime_error, HasReason{"Empty HTTP header name"})
static const std::string addr1
static const std::string addr2
std::string ToString(const T &t)
Locale-independent version of std::to_string.
@ NET_ONION
TOR (v2 or v3)
std::vector< CNetAddr > LookupHost(const std::string &name, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
Resolve a host string to its corresponding network addresses.
std::vector< CService > Lookup(const std::string &name, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function)
Resolve a service string to its corresponding service.
#define BOOST_CHECK_THROW(stmt, excMatch)
#define BOOST_CHECK_NO_THROW(stmt)
#define BOOST_CHECK(expr)
Location information for an address in AddrMan.
NodeContext struct containing references to chain state and connection state.
std::chrono::time_point< NodeClock, std::chrono::seconds > NodeSeconds