Branch data Line data Source code
# 1 : : // Copyright (c) 2012-2020 The Bitcoin Core developers
# 2 : : // Distributed under the MIT software license, see the accompanying
# 3 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
# 4 : : #include <addrman.h>
# 5 : : #include <i2p.h>
# 6 : : #include <test/data/asmap.raw.h>
# 7 : : #include <test/util/setup_common.h>
# 8 : : #include <util/asmap.h>
# 9 : : #include <util/string.h>
# 10 : : #include <hash.h>
# 11 : : #include <netbase.h>
# 12 : : #include <random.h>
# 13 : :
# 14 : : #include <boost/test/unit_test.hpp>
# 15 : :
# 16 : : #include <optional>
# 17 : : #include <string>
# 18 : :
# 19 : : class CAddrManTest : public CAddrMan
# 20 : : {
# 21 : : private:
# 22 : : bool deterministic;
# 23 : : public:
# 24 : : explicit CAddrManTest(bool makeDeterministic = true,
# 25 : : std::vector<bool> asmap = std::vector<bool>())
# 26 : 42 : {
# 27 [ + - ]: 42 : if (makeDeterministic) {
# 28 : : // Set addrman addr placement to be deterministic.
# 29 : 42 : MakeDeterministic();
# 30 : 42 : }
# 31 : 42 : deterministic = makeDeterministic;
# 32 : 42 : m_asmap = asmap;
# 33 : 42 : }
# 34 : :
# 35 : : //! Ensure that bucket placement is always the same for testing purposes.
# 36 : : void MakeDeterministic()
# 37 : 42 : {
# 38 : 42 : nKey.SetNull();
# 39 : 42 : insecure_rand = FastRandomContext(true);
# 40 : 42 : }
# 41 : :
# 42 : : CAddrInfo* Find(const CNetAddr& addr, int* pnId = nullptr)
# 43 : 10 : {
# 44 : 10 : LOCK(cs);
# 45 : 10 : return CAddrMan::Find(addr, pnId);
# 46 : 10 : }
# 47 : :
# 48 : : CAddrInfo* Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId = nullptr)
# 49 : 4 : {
# 50 : 4 : LOCK(cs);
# 51 : 4 : return CAddrMan::Create(addr, addrSource, pnId);
# 52 : 4 : }
# 53 : :
# 54 : : void Delete(int nId)
# 55 : 2 : {
# 56 : 2 : LOCK(cs);
# 57 : 2 : CAddrMan::Delete(nId);
# 58 : 2 : }
# 59 : :
# 60 : : // Used to test deserialization
# 61 : : std::pair<int, int> GetBucketAndEntry(const CAddress& addr)
# 62 : 16 : {
# 63 : 16 : LOCK(cs);
# 64 : 16 : int nId = mapAddr[addr];
# 65 [ + - ]: 6512 : for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; ++bucket) {
# 66 [ + + ]: 422846 : for (int entry = 0; entry < ADDRMAN_BUCKET_SIZE; ++entry) {
# 67 [ + + ]: 416350 : if (nId == vvNew[bucket][entry]) {
# 68 : 16 : return std::pair<int, int>(bucket, entry);
# 69 : 16 : }
# 70 : 416350 : }
# 71 : 6512 : }
# 72 : 16 : return std::pair<int, int>(-1, -1);
# 73 : 16 : }
# 74 : :
# 75 : : // Simulates connection failure so that we can test eviction of offline nodes
# 76 : : void SimConnFail(const CService& addr)
# 77 : 2 : {
# 78 : 2 : LOCK(cs);
# 79 : 2 : int64_t nLastSuccess = 1;
# 80 : 2 : Good_(addr, true, nLastSuccess); // Set last good connection in the deep past.
# 81 : :
# 82 : 2 : bool count_failure = false;
# 83 : 2 : int64_t nLastTry = GetAdjustedTime()-61;
# 84 : 2 : Attempt(addr, count_failure, nLastTry);
# 85 : 2 : }
# 86 : :
# 87 : : void Clear()
# 88 : 10 : {
# 89 : 10 : CAddrMan::Clear();
# 90 [ + - ]: 10 : if (deterministic) {
# 91 : 10 : nKey.SetNull();
# 92 : 10 : insecure_rand = FastRandomContext(true);
# 93 : 10 : }
# 94 : 10 : }
# 95 : :
# 96 : : };
# 97 : :
# 98 : : static CNetAddr ResolveIP(const std::string& ip)
# 99 : 12800 : {
# 100 : 12800 : CNetAddr addr;
# 101 : 12800 : BOOST_CHECK_MESSAGE(LookupHost(ip, addr, false), strprintf("failed to resolve: %s", ip));
# 102 : 12800 : return addr;
# 103 : 12800 : }
# 104 : :
# 105 : : static CService ResolveService(const std::string& ip, uint16_t port = 0)
# 106 : 13268 : {
# 107 : 13268 : CService serv;
# 108 : 13268 : BOOST_CHECK_MESSAGE(Lookup(ip, serv, port, false), strprintf("failed to resolve: %s:%i", ip, port));
# 109 : 13268 : return serv;
# 110 : 13268 : }
# 111 : :
# 112 : :
# 113 : 6 : static std::vector<bool> FromBytes(const unsigned char* source, int vector_size) {
# 114 : 6 : std::vector<bool> result(vector_size);
# 115 [ + + ]: 360 : for (int byte_i = 0; byte_i < vector_size / 8; ++byte_i) {
# 116 : 354 : unsigned char cur_byte = source[byte_i];
# 117 [ + + ]: 3186 : for (int bit_i = 0; bit_i < 8; ++bit_i) {
# 118 : 2832 : result[byte_i * 8 + bit_i] = (cur_byte >> bit_i) & 1;
# 119 : 2832 : }
# 120 : 354 : }
# 121 : 6 : return result;
# 122 : 6 : }
# 123 : :
# 124 : :
# 125 : : BOOST_FIXTURE_TEST_SUITE(addrman_tests, BasicTestingSetup)
# 126 : :
# 127 : : BOOST_AUTO_TEST_CASE(addrman_simple)
# 128 : 2 : {
# 129 : 2 : CAddrManTest addrman;
# 130 : :
# 131 : 2 : CNetAddr source = ResolveIP("252.2.2.2");
# 132 : :
# 133 : : // Test: Does Addrman respond correctly when empty.
# 134 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 0U);
# 135 : 2 : CAddrInfo addr_null = addrman.Select();
# 136 : 2 : BOOST_CHECK_EQUAL(addr_null.ToString(), "[::]:0");
# 137 : :
# 138 : : // Test: Does Addrman::Add work as expected.
# 139 : 2 : CService addr1 = ResolveService("250.1.1.1", 8333);
# 140 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr1, NODE_NONE), source));
# 141 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 1U);
# 142 : 2 : CAddrInfo addr_ret1 = addrman.Select();
# 143 : 2 : BOOST_CHECK_EQUAL(addr_ret1.ToString(), "250.1.1.1:8333");
# 144 : :
# 145 : : // Test: Does IP address deduplication work correctly.
# 146 : : // Expected dup IP should not be added.
# 147 : 2 : CService addr1_dup = ResolveService("250.1.1.1", 8333);
# 148 : 2 : BOOST_CHECK(!addrman.Add(CAddress(addr1_dup, NODE_NONE), source));
# 149 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 1U);
# 150 : :
# 151 : :
# 152 : : // Test: New table has one addr and we add a diff addr we should
# 153 : : // have at least one addr.
# 154 : : // Note that addrman's size cannot be tested reliably after insertion, as
# 155 : : // hash collisions may occur. But we can always be sure of at least one
# 156 : : // success.
# 157 : :
# 158 : 2 : CService addr2 = ResolveService("250.1.1.2", 8333);
# 159 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr2, NODE_NONE), source));
# 160 : 2 : BOOST_CHECK(addrman.size() >= 1);
# 161 : :
# 162 : : // Test: AddrMan::Clear() should empty the new table.
# 163 : 2 : addrman.Clear();
# 164 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 0U);
# 165 : 2 : CAddrInfo addr_null2 = addrman.Select();
# 166 : 2 : BOOST_CHECK_EQUAL(addr_null2.ToString(), "[::]:0");
# 167 : :
# 168 : : // Test: AddrMan::Add multiple addresses works as expected
# 169 : 2 : std::vector<CAddress> vAddr;
# 170 : 2 : vAddr.push_back(CAddress(ResolveService("250.1.1.3", 8333), NODE_NONE));
# 171 : 2 : vAddr.push_back(CAddress(ResolveService("250.1.1.4", 8333), NODE_NONE));
# 172 : 2 : BOOST_CHECK(addrman.Add(vAddr, source));
# 173 : 2 : BOOST_CHECK(addrman.size() >= 1);
# 174 : 2 : }
# 175 : :
# 176 : : BOOST_AUTO_TEST_CASE(addrman_ports)
# 177 : 2 : {
# 178 : 2 : CAddrManTest addrman;
# 179 : :
# 180 : 2 : CNetAddr source = ResolveIP("252.2.2.2");
# 181 : :
# 182 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 0U);
# 183 : :
# 184 : : // Test 7; Addr with same IP but diff port does not replace existing addr.
# 185 : 2 : CService addr1 = ResolveService("250.1.1.1", 8333);
# 186 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr1, NODE_NONE), source));
# 187 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 1U);
# 188 : :
# 189 : 2 : CService addr1_port = ResolveService("250.1.1.1", 8334);
# 190 : 2 : BOOST_CHECK(!addrman.Add(CAddress(addr1_port, NODE_NONE), source));
# 191 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 1U);
# 192 : 2 : CAddrInfo addr_ret2 = addrman.Select();
# 193 : 2 : BOOST_CHECK_EQUAL(addr_ret2.ToString(), "250.1.1.1:8333");
# 194 : :
# 195 : : // Test: Add same IP but diff port to tried table, it doesn't get added.
# 196 : : // Perhaps this is not ideal behavior but it is the current behavior.
# 197 : 2 : addrman.Good(CAddress(addr1_port, NODE_NONE));
# 198 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 1U);
# 199 : 2 : bool newOnly = true;
# 200 : 2 : CAddrInfo addr_ret3 = addrman.Select(newOnly);
# 201 : 2 : BOOST_CHECK_EQUAL(addr_ret3.ToString(), "250.1.1.1:8333");
# 202 : 2 : }
# 203 : :
# 204 : :
# 205 : : BOOST_AUTO_TEST_CASE(addrman_select)
# 206 : 2 : {
# 207 : 2 : CAddrManTest addrman;
# 208 : :
# 209 : 2 : CNetAddr source = ResolveIP("252.2.2.2");
# 210 : :
# 211 : : // Test: Select from new with 1 addr in new.
# 212 : 2 : CService addr1 = ResolveService("250.1.1.1", 8333);
# 213 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr1, NODE_NONE), source));
# 214 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 1U);
# 215 : :
# 216 : 2 : bool newOnly = true;
# 217 : 2 : CAddrInfo addr_ret1 = addrman.Select(newOnly);
# 218 : 2 : BOOST_CHECK_EQUAL(addr_ret1.ToString(), "250.1.1.1:8333");
# 219 : :
# 220 : : // Test: move addr to tried, select from new expected nothing returned.
# 221 : 2 : addrman.Good(CAddress(addr1, NODE_NONE));
# 222 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 1U);
# 223 : 2 : CAddrInfo addr_ret2 = addrman.Select(newOnly);
# 224 : 2 : BOOST_CHECK_EQUAL(addr_ret2.ToString(), "[::]:0");
# 225 : :
# 226 : 2 : CAddrInfo addr_ret3 = addrman.Select();
# 227 : 2 : BOOST_CHECK_EQUAL(addr_ret3.ToString(), "250.1.1.1:8333");
# 228 : :
# 229 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 1U);
# 230 : :
# 231 : :
# 232 : : // Add three addresses to new table.
# 233 : 2 : CService addr2 = ResolveService("250.3.1.1", 8333);
# 234 : 2 : CService addr3 = ResolveService("250.3.2.2", 9999);
# 235 : 2 : CService addr4 = ResolveService("250.3.3.3", 9999);
# 236 : :
# 237 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr2, NODE_NONE), ResolveService("250.3.1.1", 8333)));
# 238 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr3, NODE_NONE), ResolveService("250.3.1.1", 8333)));
# 239 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr4, NODE_NONE), ResolveService("250.4.1.1", 8333)));
# 240 : :
# 241 : : // Add three addresses to tried table.
# 242 : 2 : CService addr5 = ResolveService("250.4.4.4", 8333);
# 243 : 2 : CService addr6 = ResolveService("250.4.5.5", 7777);
# 244 : 2 : CService addr7 = ResolveService("250.4.6.6", 8333);
# 245 : :
# 246 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr5, NODE_NONE), ResolveService("250.3.1.1", 8333)));
# 247 : 2 : addrman.Good(CAddress(addr5, NODE_NONE));
# 248 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr6, NODE_NONE), ResolveService("250.3.1.1", 8333)));
# 249 : 2 : addrman.Good(CAddress(addr6, NODE_NONE));
# 250 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr7, NODE_NONE), ResolveService("250.1.1.3", 8333)));
# 251 : 2 : addrman.Good(CAddress(addr7, NODE_NONE));
# 252 : :
# 253 : : // Test: 6 addrs + 1 addr from last test = 7.
# 254 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 7U);
# 255 : :
# 256 : : // Test: Select pulls from new and tried regardless of port number.
# 257 : 2 : std::set<uint16_t> ports;
# 258 [ + + ]: 42 : for (int i = 0; i < 20; ++i) {
# 259 : 40 : ports.insert(addrman.Select().GetPort());
# 260 : 40 : }
# 261 : 2 : BOOST_CHECK_EQUAL(ports.size(), 3U);
# 262 : 2 : }
# 263 : :
# 264 : : BOOST_AUTO_TEST_CASE(addrman_new_collisions)
# 265 : 2 : {
# 266 : 2 : CAddrManTest addrman;
# 267 : :
# 268 : 2 : CNetAddr source = ResolveIP("252.2.2.2");
# 269 : :
# 270 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 0U);
# 271 : :
# 272 [ + + ]: 36 : for (unsigned int i = 1; i < 18; i++) {
# 273 : 34 : CService addr = ResolveService("250.1.1." + ToString(i));
# 274 : 34 : BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source));
# 275 : :
# 276 : : //Test: No collision in new table yet.
# 277 : 34 : BOOST_CHECK_EQUAL(addrman.size(), i);
# 278 : 34 : }
# 279 : :
# 280 : : //Test: new table collision!
# 281 : 2 : CService addr1 = ResolveService("250.1.1.18");
# 282 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr1, NODE_NONE), source));
# 283 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 17U);
# 284 : :
# 285 : 2 : CService addr2 = ResolveService("250.1.1.19");
# 286 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr2, NODE_NONE), source));
# 287 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 18U);
# 288 : 2 : }
# 289 : :
# 290 : : BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
# 291 : 2 : {
# 292 : 2 : CAddrManTest addrman;
# 293 : :
# 294 : 2 : CNetAddr source = ResolveIP("252.2.2.2");
# 295 : :
# 296 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 0U);
# 297 : :
# 298 [ + + ]: 160 : for (unsigned int i = 1; i < 80; i++) {
# 299 : 158 : CService addr = ResolveService("250.1.1." + ToString(i));
# 300 : 158 : BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source));
# 301 : 158 : addrman.Good(CAddress(addr, NODE_NONE));
# 302 : :
# 303 : : //Test: No collision in tried table yet.
# 304 : 158 : BOOST_CHECK_EQUAL(addrman.size(), i);
# 305 : 158 : }
# 306 : :
# 307 : : //Test: tried table collision!
# 308 : 2 : CService addr1 = ResolveService("250.1.1.80");
# 309 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr1, NODE_NONE), source));
# 310 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 79U);
# 311 : :
# 312 : 2 : CService addr2 = ResolveService("250.1.1.81");
# 313 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr2, NODE_NONE), source));
# 314 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 80U);
# 315 : 2 : }
# 316 : :
# 317 : : BOOST_AUTO_TEST_CASE(addrman_find)
# 318 : 2 : {
# 319 : 2 : CAddrManTest addrman;
# 320 : :
# 321 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 0U);
# 322 : :
# 323 : 2 : CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
# 324 : 2 : CAddress addr2 = CAddress(ResolveService("250.1.2.1", 9999), NODE_NONE);
# 325 : 2 : CAddress addr3 = CAddress(ResolveService("251.255.2.1", 8333), NODE_NONE);
# 326 : :
# 327 : 2 : CNetAddr source1 = ResolveIP("250.1.2.1");
# 328 : 2 : CNetAddr source2 = ResolveIP("250.1.2.2");
# 329 : :
# 330 : 2 : BOOST_CHECK(addrman.Add(addr1, source1));
# 331 : 2 : BOOST_CHECK(!addrman.Add(addr2, source2));
# 332 : 2 : BOOST_CHECK(addrman.Add(addr3, source1));
# 333 : :
# 334 : : // Test: ensure Find returns an IP matching what we searched on.
# 335 : 2 : CAddrInfo* info1 = addrman.Find(addr1);
# 336 : 2 : BOOST_REQUIRE(info1);
# 337 : 2 : BOOST_CHECK_EQUAL(info1->ToString(), "250.1.2.1:8333");
# 338 : :
# 339 : : // Test 18; Find does not discriminate by port number.
# 340 : 2 : CAddrInfo* info2 = addrman.Find(addr2);
# 341 : 2 : BOOST_REQUIRE(info2);
# 342 : 2 : BOOST_CHECK_EQUAL(info2->ToString(), info1->ToString());
# 343 : :
# 344 : : // Test: Find returns another IP matching what we searched on.
# 345 : 2 : CAddrInfo* info3 = addrman.Find(addr3);
# 346 : 2 : BOOST_REQUIRE(info3);
# 347 : 2 : BOOST_CHECK_EQUAL(info3->ToString(), "251.255.2.1:8333");
# 348 : 2 : }
# 349 : :
# 350 : : BOOST_AUTO_TEST_CASE(addrman_create)
# 351 : 2 : {
# 352 : 2 : CAddrManTest addrman;
# 353 : :
# 354 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 0U);
# 355 : :
# 356 : 2 : CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
# 357 : 2 : CNetAddr source1 = ResolveIP("250.1.2.1");
# 358 : :
# 359 : 2 : int nId;
# 360 : 2 : CAddrInfo* pinfo = addrman.Create(addr1, source1, &nId);
# 361 : :
# 362 : : // Test: The result should be the same as the input addr.
# 363 : 2 : BOOST_CHECK_EQUAL(pinfo->ToString(), "250.1.2.1:8333");
# 364 : :
# 365 : 2 : CAddrInfo* info2 = addrman.Find(addr1);
# 366 : 2 : BOOST_CHECK_EQUAL(info2->ToString(), "250.1.2.1:8333");
# 367 : 2 : }
# 368 : :
# 369 : :
# 370 : : BOOST_AUTO_TEST_CASE(addrman_delete)
# 371 : 2 : {
# 372 : 2 : CAddrManTest addrman;
# 373 : :
# 374 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 0U);
# 375 : :
# 376 : 2 : CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
# 377 : 2 : CNetAddr source1 = ResolveIP("250.1.2.1");
# 378 : :
# 379 : 2 : int nId;
# 380 : 2 : addrman.Create(addr1, source1, &nId);
# 381 : :
# 382 : : // Test: Delete should actually delete the addr.
# 383 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 1U);
# 384 : 2 : addrman.Delete(nId);
# 385 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 0U);
# 386 : 2 : CAddrInfo* info2 = addrman.Find(addr1);
# 387 : 2 : BOOST_CHECK(info2 == nullptr);
# 388 : 2 : }
# 389 : :
# 390 : : BOOST_AUTO_TEST_CASE(addrman_getaddr)
# 391 : 2 : {
# 392 : 2 : CAddrManTest addrman;
# 393 : :
# 394 : : // Test: Sanity check, GetAddr should never return anything if addrman
# 395 : : // is empty.
# 396 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 0U);
# 397 : 2 : std::vector<CAddress> vAddr1 = addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0, /* network */ std::nullopt);
# 398 : 2 : BOOST_CHECK_EQUAL(vAddr1.size(), 0U);
# 399 : :
# 400 : 2 : CAddress addr1 = CAddress(ResolveService("250.250.2.1", 8333), NODE_NONE);
# 401 : 2 : addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false
# 402 : 2 : CAddress addr2 = CAddress(ResolveService("250.251.2.2", 9999), NODE_NONE);
# 403 : 2 : addr2.nTime = GetAdjustedTime();
# 404 : 2 : CAddress addr3 = CAddress(ResolveService("251.252.2.3", 8333), NODE_NONE);
# 405 : 2 : addr3.nTime = GetAdjustedTime();
# 406 : 2 : CAddress addr4 = CAddress(ResolveService("252.253.3.4", 8333), NODE_NONE);
# 407 : 2 : addr4.nTime = GetAdjustedTime();
# 408 : 2 : CAddress addr5 = CAddress(ResolveService("252.254.4.5", 8333), NODE_NONE);
# 409 : 2 : addr5.nTime = GetAdjustedTime();
# 410 : 2 : CNetAddr source1 = ResolveIP("250.1.2.1");
# 411 : 2 : CNetAddr source2 = ResolveIP("250.2.3.3");
# 412 : :
# 413 : : // Test: Ensure GetAddr works with new addresses.
# 414 : 2 : BOOST_CHECK(addrman.Add(addr1, source1));
# 415 : 2 : BOOST_CHECK(addrman.Add(addr2, source2));
# 416 : 2 : BOOST_CHECK(addrman.Add(addr3, source1));
# 417 : 2 : BOOST_CHECK(addrman.Add(addr4, source2));
# 418 : 2 : BOOST_CHECK(addrman.Add(addr5, source1));
# 419 : :
# 420 : 2 : BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0, /* network */ std::nullopt).size(), 5U);
# 421 : : // Net processing asks for 23% of addresses. 23% of 5 is 1 rounded down.
# 422 : 2 : BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt).size(), 1U);
# 423 : :
# 424 : : // Test: Ensure GetAddr works with new and tried addresses.
# 425 : 2 : addrman.Good(CAddress(addr1, NODE_NONE));
# 426 : 2 : addrman.Good(CAddress(addr2, NODE_NONE));
# 427 : 2 : BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0, /* network */ std::nullopt).size(), 5U);
# 428 : 2 : BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt).size(), 1U);
# 429 : :
# 430 : : // Test: Ensure GetAddr still returns 23% when addrman has many addrs.
# 431 [ + + ]: 4096 : for (unsigned int i = 1; i < (8 * 256); i++) {
# 432 : 4094 : int octet1 = i % 256;
# 433 : 4094 : int octet2 = i >> 8 % 256;
# 434 : 4094 : std::string strAddr = ToString(octet1) + "." + ToString(octet2) + ".1.23";
# 435 : 4094 : CAddress addr = CAddress(ResolveService(strAddr), NODE_NONE);
# 436 : :
# 437 : : // Ensure that for all addrs in addrman, isTerrible == false.
# 438 : 4094 : addr.nTime = GetAdjustedTime();
# 439 : 4094 : addrman.Add(addr, ResolveIP(strAddr));
# 440 [ + + ]: 4094 : if (i % 8 == 0)
# 441 : 510 : addrman.Good(addr);
# 442 : 4094 : }
# 443 : 2 : std::vector<CAddress> vAddr = addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt);
# 444 : :
# 445 : 2 : size_t percent23 = (addrman.size() * 23) / 100;
# 446 : 2 : BOOST_CHECK_EQUAL(vAddr.size(), percent23);
# 447 : 2 : BOOST_CHECK_EQUAL(vAddr.size(), 461U);
# 448 : : // (Addrman.size() < number of addresses added) due to address collisions.
# 449 : 2 : BOOST_CHECK_EQUAL(addrman.size(), 2006U);
# 450 : 2 : }
# 451 : :
# 452 : :
# 453 : : BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket_legacy)
# 454 : 2 : {
# 455 : 2 : CAddrManTest addrman;
# 456 : :
# 457 : 2 : CAddress addr1 = CAddress(ResolveService("250.1.1.1", 8333), NODE_NONE);
# 458 : 2 : CAddress addr2 = CAddress(ResolveService("250.1.1.1", 9999), NODE_NONE);
# 459 : :
# 460 : 2 : CNetAddr source1 = ResolveIP("250.1.1.1");
# 461 : :
# 462 : :
# 463 : 2 : CAddrInfo info1 = CAddrInfo(addr1, source1);
# 464 : :
# 465 : 2 : uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash();
# 466 : 2 : uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash();
# 467 : :
# 468 : 2 : std::vector<bool> asmap; // use /16
# 469 : :
# 470 : 2 : BOOST_CHECK_EQUAL(info1.GetTriedBucket(nKey1, asmap), 40);
# 471 : :
# 472 : : // Test: Make sure key actually randomizes bucket placement. A fail on
# 473 : : // this test could be a security issue.
# 474 : 2 : BOOST_CHECK(info1.GetTriedBucket(nKey1, asmap) != info1.GetTriedBucket(nKey2, asmap));
# 475 : :
# 476 : : // Test: Two addresses with same IP but different ports can map to
# 477 : : // different buckets because they have different keys.
# 478 : 2 : CAddrInfo info2 = CAddrInfo(addr2, source1);
# 479 : :
# 480 : 2 : BOOST_CHECK(info1.GetKey() != info2.GetKey());
# 481 : 2 : BOOST_CHECK(info1.GetTriedBucket(nKey1, asmap) != info2.GetTriedBucket(nKey1, asmap));
# 482 : :
# 483 : 2 : std::set<int> buckets;
# 484 [ + + ]: 512 : for (int i = 0; i < 255; i++) {
# 485 : 510 : CAddrInfo infoi = CAddrInfo(
# 486 : 510 : CAddress(ResolveService("250.1.1." + ToString(i)), NODE_NONE),
# 487 : 510 : ResolveIP("250.1.1." + ToString(i)));
# 488 : 510 : int bucket = infoi.GetTriedBucket(nKey1, asmap);
# 489 : 510 : buckets.insert(bucket);
# 490 : 510 : }
# 491 : : // Test: IP addresses in the same /16 prefix should
# 492 : : // never get more than 8 buckets with legacy grouping
# 493 : 2 : BOOST_CHECK_EQUAL(buckets.size(), 8U);
# 494 : :
# 495 : 2 : buckets.clear();
# 496 [ + + ]: 512 : for (int j = 0; j < 255; j++) {
# 497 : 510 : CAddrInfo infoj = CAddrInfo(
# 498 : 510 : CAddress(ResolveService("250." + ToString(j) + ".1.1"), NODE_NONE),
# 499 : 510 : ResolveIP("250." + ToString(j) + ".1.1"));
# 500 : 510 : int bucket = infoj.GetTriedBucket(nKey1, asmap);
# 501 : 510 : buckets.insert(bucket);
# 502 : 510 : }
# 503 : : // Test: IP addresses in the different /16 prefix should map to more than
# 504 : : // 8 buckets with legacy grouping
# 505 : 2 : BOOST_CHECK_EQUAL(buckets.size(), 160U);
# 506 : 2 : }
# 507 : :
# 508 : : BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket_legacy)
# 509 : 2 : {
# 510 : 2 : CAddrManTest addrman;
# 511 : :
# 512 : 2 : CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
# 513 : 2 : CAddress addr2 = CAddress(ResolveService("250.1.2.1", 9999), NODE_NONE);
# 514 : :
# 515 : 2 : CNetAddr source1 = ResolveIP("250.1.2.1");
# 516 : :
# 517 : 2 : CAddrInfo info1 = CAddrInfo(addr1, source1);
# 518 : :
# 519 : 2 : uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash();
# 520 : 2 : uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash();
# 521 : :
# 522 : 2 : std::vector<bool> asmap; // use /16
# 523 : :
# 524 : : // Test: Make sure the buckets are what we expect
# 525 : 2 : BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, asmap), 786);
# 526 : 2 : BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, source1, asmap), 786);
# 527 : :
# 528 : : // Test: Make sure key actually randomizes bucket placement. A fail on
# 529 : : // this test could be a security issue.
# 530 : 2 : BOOST_CHECK(info1.GetNewBucket(nKey1, asmap) != info1.GetNewBucket(nKey2, asmap));
# 531 : :
# 532 : : // Test: Ports should not affect bucket placement in the addr
# 533 : 2 : CAddrInfo info2 = CAddrInfo(addr2, source1);
# 534 : 2 : BOOST_CHECK(info1.GetKey() != info2.GetKey());
# 535 : 2 : BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, asmap), info2.GetNewBucket(nKey1, asmap));
# 536 : :
# 537 : 2 : std::set<int> buckets;
# 538 [ + + ]: 512 : for (int i = 0; i < 255; i++) {
# 539 : 510 : CAddrInfo infoi = CAddrInfo(
# 540 : 510 : CAddress(ResolveService("250.1.1." + ToString(i)), NODE_NONE),
# 541 : 510 : ResolveIP("250.1.1." + ToString(i)));
# 542 : 510 : int bucket = infoi.GetNewBucket(nKey1, asmap);
# 543 : 510 : buckets.insert(bucket);
# 544 : 510 : }
# 545 : : // Test: IP addresses in the same group (\16 prefix for IPv4) should
# 546 : : // always map to the same bucket.
# 547 : 2 : BOOST_CHECK_EQUAL(buckets.size(), 1U);
# 548 : :
# 549 : 2 : buckets.clear();
# 550 [ + + ]: 2042 : for (int j = 0; j < 4 * 255; j++) {
# 551 : 2040 : CAddrInfo infoj = CAddrInfo(CAddress(
# 552 : 2040 : ResolveService(
# 553 : 2040 : ToString(250 + (j / 255)) + "." + ToString(j % 256) + ".1.1"), NODE_NONE),
# 554 : 2040 : ResolveIP("251.4.1.1"));
# 555 : 2040 : int bucket = infoj.GetNewBucket(nKey1, asmap);
# 556 : 2040 : buckets.insert(bucket);
# 557 : 2040 : }
# 558 : : // Test: IP addresses in the same source groups should map to NO MORE
# 559 : : // than 64 buckets.
# 560 : 2 : BOOST_CHECK(buckets.size() <= 64);
# 561 : :
# 562 : 2 : buckets.clear();
# 563 [ + + ]: 512 : for (int p = 0; p < 255; p++) {
# 564 : 510 : CAddrInfo infoj = CAddrInfo(
# 565 : 510 : CAddress(ResolveService("250.1.1.1"), NODE_NONE),
# 566 : 510 : ResolveIP("250." + ToString(p) + ".1.1"));
# 567 : 510 : int bucket = infoj.GetNewBucket(nKey1, asmap);
# 568 : 510 : buckets.insert(bucket);
# 569 : 510 : }
# 570 : : // Test: IP addresses in the different source groups should map to MORE
# 571 : : // than 64 buckets.
# 572 : 2 : BOOST_CHECK(buckets.size() > 64);
# 573 : 2 : }
# 574 : :
# 575 : : // The following three test cases use asmap.raw
# 576 : : // We use an artificial minimal mock mapping
# 577 : : // 250.0.0.0/8 AS1000
# 578 : : // 101.1.0.0/16 AS1
# 579 : : // 101.2.0.0/16 AS2
# 580 : : // 101.3.0.0/16 AS3
# 581 : : // 101.4.0.0/16 AS4
# 582 : : // 101.5.0.0/16 AS5
# 583 : : // 101.6.0.0/16 AS6
# 584 : : // 101.7.0.0/16 AS7
# 585 : : // 101.8.0.0/16 AS8
# 586 : : BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
# 587 : 2 : {
# 588 : 2 : CAddrManTest addrman;
# 589 : :
# 590 : 2 : CAddress addr1 = CAddress(ResolveService("250.1.1.1", 8333), NODE_NONE);
# 591 : 2 : CAddress addr2 = CAddress(ResolveService("250.1.1.1", 9999), NODE_NONE);
# 592 : :
# 593 : 2 : CNetAddr source1 = ResolveIP("250.1.1.1");
# 594 : :
# 595 : :
# 596 : 2 : CAddrInfo info1 = CAddrInfo(addr1, source1);
# 597 : :
# 598 : 2 : uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash();
# 599 : 2 : uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash();
# 600 : :
# 601 : 2 : std::vector<bool> asmap = FromBytes(asmap_raw, sizeof(asmap_raw) * 8);
# 602 : :
# 603 : 2 : BOOST_CHECK_EQUAL(info1.GetTriedBucket(nKey1, asmap), 236);
# 604 : :
# 605 : : // Test: Make sure key actually randomizes bucket placement. A fail on
# 606 : : // this test could be a security issue.
# 607 : 2 : BOOST_CHECK(info1.GetTriedBucket(nKey1, asmap) != info1.GetTriedBucket(nKey2, asmap));
# 608 : :
# 609 : : // Test: Two addresses with same IP but different ports can map to
# 610 : : // different buckets because they have different keys.
# 611 : 2 : CAddrInfo info2 = CAddrInfo(addr2, source1);
# 612 : :
# 613 : 2 : BOOST_CHECK(info1.GetKey() != info2.GetKey());
# 614 : 2 : BOOST_CHECK(info1.GetTriedBucket(nKey1, asmap) != info2.GetTriedBucket(nKey1, asmap));
# 615 : :
# 616 : 2 : std::set<int> buckets;
# 617 [ + + ]: 512 : for (int j = 0; j < 255; j++) {
# 618 : 510 : CAddrInfo infoj = CAddrInfo(
# 619 : 510 : CAddress(ResolveService("101." + ToString(j) + ".1.1"), NODE_NONE),
# 620 : 510 : ResolveIP("101." + ToString(j) + ".1.1"));
# 621 : 510 : int bucket = infoj.GetTriedBucket(nKey1, asmap);
# 622 : 510 : buckets.insert(bucket);
# 623 : 510 : }
# 624 : : // Test: IP addresses in the different /16 prefix MAY map to more than
# 625 : : // 8 buckets.
# 626 : 2 : BOOST_CHECK(buckets.size() > 8);
# 627 : :
# 628 : 2 : buckets.clear();
# 629 [ + + ]: 512 : for (int j = 0; j < 255; j++) {
# 630 : 510 : CAddrInfo infoj = CAddrInfo(
# 631 : 510 : CAddress(ResolveService("250." + ToString(j) + ".1.1"), NODE_NONE),
# 632 : 510 : ResolveIP("250." + ToString(j) + ".1.1"));
# 633 : 510 : int bucket = infoj.GetTriedBucket(nKey1, asmap);
# 634 : 510 : buckets.insert(bucket);
# 635 : 510 : }
# 636 : : // Test: IP addresses in the different /16 prefix MAY NOT map to more than
# 637 : : // 8 buckets.
# 638 : 2 : BOOST_CHECK(buckets.size() == 8);
# 639 : 2 : }
# 640 : :
# 641 : : BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
# 642 : 2 : {
# 643 : 2 : CAddrManTest addrman;
# 644 : :
# 645 : 2 : CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
# 646 : 2 : CAddress addr2 = CAddress(ResolveService("250.1.2.1", 9999), NODE_NONE);
# 647 : :
# 648 : 2 : CNetAddr source1 = ResolveIP("250.1.2.1");
# 649 : :
# 650 : 2 : CAddrInfo info1 = CAddrInfo(addr1, source1);
# 651 : :
# 652 : 2 : uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash();
# 653 : 2 : uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash();
# 654 : :
# 655 : 2 : std::vector<bool> asmap = FromBytes(asmap_raw, sizeof(asmap_raw) * 8);
# 656 : :
# 657 : : // Test: Make sure the buckets are what we expect
# 658 : 2 : BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, asmap), 795);
# 659 : 2 : BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, source1, asmap), 795);
# 660 : :
# 661 : : // Test: Make sure key actually randomizes bucket placement. A fail on
# 662 : : // this test could be a security issue.
# 663 : 2 : BOOST_CHECK(info1.GetNewBucket(nKey1, asmap) != info1.GetNewBucket(nKey2, asmap));
# 664 : :
# 665 : : // Test: Ports should not affect bucket placement in the addr
# 666 : 2 : CAddrInfo info2 = CAddrInfo(addr2, source1);
# 667 : 2 : BOOST_CHECK(info1.GetKey() != info2.GetKey());
# 668 : 2 : BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, asmap), info2.GetNewBucket(nKey1, asmap));
# 669 : :
# 670 : 2 : std::set<int> buckets;
# 671 [ + + ]: 512 : for (int i = 0; i < 255; i++) {
# 672 : 510 : CAddrInfo infoi = CAddrInfo(
# 673 : 510 : CAddress(ResolveService("250.1.1." + ToString(i)), NODE_NONE),
# 674 : 510 : ResolveIP("250.1.1." + ToString(i)));
# 675 : 510 : int bucket = infoi.GetNewBucket(nKey1, asmap);
# 676 : 510 : buckets.insert(bucket);
# 677 : 510 : }
# 678 : : // Test: IP addresses in the same /16 prefix
# 679 : : // usually map to the same bucket.
# 680 : 2 : BOOST_CHECK_EQUAL(buckets.size(), 1U);
# 681 : :
# 682 : 2 : buckets.clear();
# 683 [ + + ]: 2042 : for (int j = 0; j < 4 * 255; j++) {
# 684 : 2040 : CAddrInfo infoj = CAddrInfo(CAddress(
# 685 : 2040 : ResolveService(
# 686 : 2040 : ToString(250 + (j / 255)) + "." + ToString(j % 256) + ".1.1"), NODE_NONE),
# 687 : 2040 : ResolveIP("251.4.1.1"));
# 688 : 2040 : int bucket = infoj.GetNewBucket(nKey1, asmap);
# 689 : 2040 : buckets.insert(bucket);
# 690 : 2040 : }
# 691 : : // Test: IP addresses in the same source /16 prefix should not map to more
# 692 : : // than 64 buckets.
# 693 : 2 : BOOST_CHECK(buckets.size() <= 64);
# 694 : :
# 695 : 2 : buckets.clear();
# 696 [ + + ]: 512 : for (int p = 0; p < 255; p++) {
# 697 : 510 : CAddrInfo infoj = CAddrInfo(
# 698 : 510 : CAddress(ResolveService("250.1.1.1"), NODE_NONE),
# 699 : 510 : ResolveIP("101." + ToString(p) + ".1.1"));
# 700 : 510 : int bucket = infoj.GetNewBucket(nKey1, asmap);
# 701 : 510 : buckets.insert(bucket);
# 702 : 510 : }
# 703 : : // Test: IP addresses in the different source /16 prefixes usually map to MORE
# 704 : : // than 1 bucket.
# 705 : 2 : BOOST_CHECK(buckets.size() > 1);
# 706 : :
# 707 : 2 : buckets.clear();
# 708 [ + + ]: 512 : for (int p = 0; p < 255; p++) {
# 709 : 510 : CAddrInfo infoj = CAddrInfo(
# 710 : 510 : CAddress(ResolveService("250.1.1.1"), NODE_NONE),
# 711 : 510 : ResolveIP("250." + ToString(p) + ".1.1"));
# 712 : 510 : int bucket = infoj.GetNewBucket(nKey1, asmap);
# 713 : 510 : buckets.insert(bucket);
# 714 : 510 : }
# 715 : : // Test: IP addresses in the different source /16 prefixes sometimes map to NO MORE
# 716 : : // than 1 bucket.
# 717 : 2 : BOOST_CHECK(buckets.size() == 1);
# 718 : :
# 719 : 2 : }
# 720 : :
# 721 : : BOOST_AUTO_TEST_CASE(addrman_serialization)
# 722 : 2 : {
# 723 : 2 : std::vector<bool> asmap1 = FromBytes(asmap_raw, sizeof(asmap_raw) * 8);
# 724 : :
# 725 : 2 : CAddrManTest addrman_asmap1(true, asmap1);
# 726 : 2 : CAddrManTest addrman_asmap1_dup(true, asmap1);
# 727 : 2 : CAddrManTest addrman_noasmap;
# 728 : 2 : CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
# 729 : :
# 730 : 2 : CAddress addr = CAddress(ResolveService("250.1.1.1"), NODE_NONE);
# 731 : 2 : CNetAddr default_source;
# 732 : :
# 733 : :
# 734 : 2 : addrman_asmap1.Add(addr, default_source);
# 735 : :
# 736 : 2 : stream << addrman_asmap1;
# 737 : : // serizalizing/deserializing addrman with the same asmap
# 738 : 2 : stream >> addrman_asmap1_dup;
# 739 : :
# 740 : 2 : std::pair<int, int> bucketAndEntry_asmap1 = addrman_asmap1.GetBucketAndEntry(addr);
# 741 : 2 : std::pair<int, int> bucketAndEntry_asmap1_dup = addrman_asmap1_dup.GetBucketAndEntry(addr);
# 742 : 2 : BOOST_CHECK(bucketAndEntry_asmap1.second != -1);
# 743 : 2 : BOOST_CHECK(bucketAndEntry_asmap1_dup.second != -1);
# 744 : :
# 745 : 2 : BOOST_CHECK(bucketAndEntry_asmap1.first == bucketAndEntry_asmap1_dup.first);
# 746 : 2 : BOOST_CHECK(bucketAndEntry_asmap1.second == bucketAndEntry_asmap1_dup.second);
# 747 : :
# 748 : : // deserializing asmaped peers.dat to non-asmaped addrman
# 749 : 2 : stream << addrman_asmap1;
# 750 : 2 : stream >> addrman_noasmap;
# 751 : 2 : std::pair<int, int> bucketAndEntry_noasmap = addrman_noasmap.GetBucketAndEntry(addr);
# 752 : 2 : BOOST_CHECK(bucketAndEntry_noasmap.second != -1);
# 753 : 2 : BOOST_CHECK(bucketAndEntry_asmap1.first != bucketAndEntry_noasmap.first);
# 754 : 2 : BOOST_CHECK(bucketAndEntry_asmap1.second != bucketAndEntry_noasmap.second);
# 755 : :
# 756 : : // deserializing non-asmaped peers.dat to asmaped addrman
# 757 : 2 : addrman_asmap1.Clear();
# 758 : 2 : addrman_noasmap.Clear();
# 759 : 2 : addrman_noasmap.Add(addr, default_source);
# 760 : 2 : stream << addrman_noasmap;
# 761 : 2 : stream >> addrman_asmap1;
# 762 : 2 : std::pair<int, int> bucketAndEntry_asmap1_deser = addrman_asmap1.GetBucketAndEntry(addr);
# 763 : 2 : BOOST_CHECK(bucketAndEntry_asmap1_deser.second != -1);
# 764 : 2 : BOOST_CHECK(bucketAndEntry_asmap1_deser.first != bucketAndEntry_noasmap.first);
# 765 : 2 : BOOST_CHECK(bucketAndEntry_asmap1_deser.first == bucketAndEntry_asmap1_dup.first);
# 766 : 2 : BOOST_CHECK(bucketAndEntry_asmap1_deser.second == bucketAndEntry_asmap1_dup.second);
# 767 : :
# 768 : : // used to map to different buckets, now maps to the same bucket.
# 769 : 2 : addrman_asmap1.Clear();
# 770 : 2 : addrman_noasmap.Clear();
# 771 : 2 : CAddress addr1 = CAddress(ResolveService("250.1.1.1"), NODE_NONE);
# 772 : 2 : CAddress addr2 = CAddress(ResolveService("250.2.1.1"), NODE_NONE);
# 773 : 2 : addrman_noasmap.Add(addr, default_source);
# 774 : 2 : addrman_noasmap.Add(addr2, default_source);
# 775 : 2 : std::pair<int, int> bucketAndEntry_noasmap_addr1 = addrman_noasmap.GetBucketAndEntry(addr1);
# 776 : 2 : std::pair<int, int> bucketAndEntry_noasmap_addr2 = addrman_noasmap.GetBucketAndEntry(addr2);
# 777 : 2 : BOOST_CHECK(bucketAndEntry_noasmap_addr1.first != bucketAndEntry_noasmap_addr2.first);
# 778 : 2 : BOOST_CHECK(bucketAndEntry_noasmap_addr1.second != bucketAndEntry_noasmap_addr2.second);
# 779 : 2 : stream << addrman_noasmap;
# 780 : 2 : stream >> addrman_asmap1;
# 781 : 2 : std::pair<int, int> bucketAndEntry_asmap1_deser_addr1 = addrman_asmap1.GetBucketAndEntry(addr1);
# 782 : 2 : std::pair<int, int> bucketAndEntry_asmap1_deser_addr2 = addrman_asmap1.GetBucketAndEntry(addr2);
# 783 : 2 : BOOST_CHECK(bucketAndEntry_asmap1_deser_addr1.first == bucketAndEntry_asmap1_deser_addr2.first);
# 784 : 2 : BOOST_CHECK(bucketAndEntry_asmap1_deser_addr1.second != bucketAndEntry_asmap1_deser_addr2.second);
# 785 : 2 : }
# 786 : :
# 787 : :
# 788 : : BOOST_AUTO_TEST_CASE(addrman_selecttriedcollision)
# 789 : 2 : {
# 790 : 2 : CAddrManTest addrman;
# 791 : :
# 792 : 2 : BOOST_CHECK(addrman.size() == 0);
# 793 : :
# 794 : : // Empty addrman should return blank addrman info.
# 795 : 2 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
# 796 : :
# 797 : : // Add twenty two addresses.
# 798 : 2 : CNetAddr source = ResolveIP("252.2.2.2");
# 799 [ + + ]: 46 : for (unsigned int i = 1; i < 23; i++) {
# 800 : 44 : CService addr = ResolveService("250.1.1."+ToString(i));
# 801 : 44 : BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source));
# 802 : 44 : addrman.Good(addr);
# 803 : :
# 804 : : // No collisions yet.
# 805 : 44 : BOOST_CHECK(addrman.size() == i);
# 806 : 44 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
# 807 : 44 : }
# 808 : :
# 809 : : // Ensure Good handles duplicates well.
# 810 [ + + ]: 46 : for (unsigned int i = 1; i < 23; i++) {
# 811 : 44 : CService addr = ResolveService("250.1.1."+ToString(i));
# 812 : 44 : addrman.Good(addr);
# 813 : :
# 814 : 44 : BOOST_CHECK(addrman.size() == 22);
# 815 : 44 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
# 816 : 44 : }
# 817 : :
# 818 : 2 : }
# 819 : :
# 820 : : BOOST_AUTO_TEST_CASE(addrman_noevict)
# 821 : 2 : {
# 822 : 2 : CAddrManTest addrman;
# 823 : :
# 824 : : // Add twenty two addresses.
# 825 : 2 : CNetAddr source = ResolveIP("252.2.2.2");
# 826 [ + + ]: 46 : for (unsigned int i = 1; i < 23; i++) {
# 827 : 44 : CService addr = ResolveService("250.1.1."+ToString(i));
# 828 : 44 : BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source));
# 829 : 44 : addrman.Good(addr);
# 830 : :
# 831 : : // No collision yet.
# 832 : 44 : BOOST_CHECK(addrman.size() == i);
# 833 : 44 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
# 834 : 44 : }
# 835 : :
# 836 : : // Collision between 23 and 19.
# 837 : 2 : CService addr23 = ResolveService("250.1.1.23");
# 838 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr23, NODE_NONE), source));
# 839 : 2 : addrman.Good(addr23);
# 840 : :
# 841 : 2 : BOOST_CHECK(addrman.size() == 23);
# 842 : 2 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "250.1.1.19:0");
# 843 : :
# 844 : : // 23 should be discarded and 19 not evicted.
# 845 : 2 : addrman.ResolveCollisions();
# 846 : 2 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
# 847 : :
# 848 : : // Lets create two collisions.
# 849 [ + + ]: 20 : for (unsigned int i = 24; i < 33; i++) {
# 850 : 18 : CService addr = ResolveService("250.1.1."+ToString(i));
# 851 : 18 : BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source));
# 852 : 18 : addrman.Good(addr);
# 853 : :
# 854 : 18 : BOOST_CHECK(addrman.size() == i);
# 855 : 18 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
# 856 : 18 : }
# 857 : :
# 858 : : // Cause a collision.
# 859 : 2 : CService addr33 = ResolveService("250.1.1.33");
# 860 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr33, NODE_NONE), source));
# 861 : 2 : addrman.Good(addr33);
# 862 : 2 : BOOST_CHECK(addrman.size() == 33);
# 863 : :
# 864 : 2 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "250.1.1.27:0");
# 865 : :
# 866 : : // Cause a second collision.
# 867 : 2 : BOOST_CHECK(!addrman.Add(CAddress(addr23, NODE_NONE), source));
# 868 : 2 : addrman.Good(addr23);
# 869 : 2 : BOOST_CHECK(addrman.size() == 33);
# 870 : :
# 871 : 2 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() != "[::]:0");
# 872 : 2 : addrman.ResolveCollisions();
# 873 : 2 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
# 874 : 2 : }
# 875 : :
# 876 : : BOOST_AUTO_TEST_CASE(addrman_evictionworks)
# 877 : 2 : {
# 878 : 2 : CAddrManTest addrman;
# 879 : :
# 880 : 2 : BOOST_CHECK(addrman.size() == 0);
# 881 : :
# 882 : : // Empty addrman should return blank addrman info.
# 883 : 2 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
# 884 : :
# 885 : : // Add twenty two addresses.
# 886 : 2 : CNetAddr source = ResolveIP("252.2.2.2");
# 887 [ + + ]: 46 : for (unsigned int i = 1; i < 23; i++) {
# 888 : 44 : CService addr = ResolveService("250.1.1."+ToString(i));
# 889 : 44 : BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source));
# 890 : 44 : addrman.Good(addr);
# 891 : :
# 892 : : // No collision yet.
# 893 : 44 : BOOST_CHECK(addrman.size() == i);
# 894 : 44 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
# 895 : 44 : }
# 896 : :
# 897 : : // Collision between 23 and 19.
# 898 : 2 : CService addr = ResolveService("250.1.1.23");
# 899 : 2 : BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source));
# 900 : 2 : addrman.Good(addr);
# 901 : :
# 902 : 2 : BOOST_CHECK(addrman.size() == 23);
# 903 : 2 : CAddrInfo info = addrman.SelectTriedCollision();
# 904 : 2 : BOOST_CHECK(info.ToString() == "250.1.1.19:0");
# 905 : :
# 906 : : // Ensure test of address fails, so that it is evicted.
# 907 : 2 : addrman.SimConnFail(info);
# 908 : :
# 909 : : // Should swap 23 for 19.
# 910 : 2 : addrman.ResolveCollisions();
# 911 : 2 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
# 912 : :
# 913 : : // If 23 was swapped for 19, then this should cause no collisions.
# 914 : 2 : BOOST_CHECK(!addrman.Add(CAddress(addr, NODE_NONE), source));
# 915 : 2 : addrman.Good(addr);
# 916 : :
# 917 : 2 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
# 918 : :
# 919 : : // If we insert 19 is should collide with 23.
# 920 : 2 : CService addr19 = ResolveService("250.1.1.19");
# 921 : 2 : BOOST_CHECK(!addrman.Add(CAddress(addr19, NODE_NONE), source));
# 922 : 2 : addrman.Good(addr19);
# 923 : :
# 924 : 2 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "250.1.1.23:0");
# 925 : :
# 926 : 2 : addrman.ResolveCollisions();
# 927 : 2 : BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
# 928 : 2 : }
# 929 : :
# 930 : : BOOST_AUTO_TEST_CASE(reset_i2p_ports)
# 931 : 2 : {
# 932 : 2 : CAddrManTest addrman1;
# 933 : 2 : CAddrManTest addrman2;
# 934 : 2 : const uint32_t good_time{static_cast<uint32_t>(GetAdjustedTime())};
# 935 : 2 : constexpr uint16_t port = 8333;
# 936 : :
# 937 : : // Gets port changed, will be re-positioned within the same bucket in vvNew.
# 938 : 2 : const CAddress i2p_new1{
# 939 : 2 : ResolveService("72l3ucjkuscrbiiepoehuwqgknyzgo7zuix5ty4puwrkyhtmnsga.b32.i2p", port),
# 940 : 2 : NODE_NONE,
# 941 : 2 : good_time};
# 942 : :
# 943 : : // Gets port changed, will not be re-positioned in vvNew because ports 0 and 10075 result in
# 944 : : // the same bucket position.
# 945 : 2 : const CAddress i2p_new2{
# 946 : 2 : ResolveService("gehtac45oaghz54ypyopim64mql7oad2bqclla74l6tfeolzmodq.b32.i2p", 10075),
# 947 : 2 : NODE_NONE,
# 948 : 2 : good_time};
# 949 : :
# 950 : : // Remains unchanged, port is already as it should be.
# 951 : 2 : const CAddress i2p_new3{
# 952 : 2 : ResolveService("c4gfnttsuwqomiygupdqqqyy5y5emnk5c73hrfvatri67prd7vyq.b32.i2p",
# 953 : 2 : i2p::sam::PORT_SAM31),
# 954 : 2 : NODE_NONE,
# 955 : 2 : good_time};
# 956 : :
# 957 : : // Gets removed because after changing the port it will collide with i2p_new3.
# 958 : 2 : const CAddress i2p_new4{
# 959 : 2 : ResolveService("c4cbbkn46qxftwja53pxiykntegfyfjqtnzbm6iv6r5mungmqgmq.b32.i2p", port),
# 960 : 2 : NODE_NONE,
# 961 : 2 : good_time};
# 962 : :
# 963 : : // Remains unchanged.
# 964 : 2 : const CAddress ipv4_new{ResolveService("1.2.3.4", port), NODE_NONE, good_time};
# 965 : :
# 966 : : // Gets port changed, will be re-positioned in vvTried.
# 967 : 2 : const CAddress i2p_tried1{
# 968 : 2 : ResolveService("h3r6bkn46qxftwja53pxiykntegfyfjqtnzbm6iv6r5mungmqgmq.b32.i2p", port),
# 969 : 2 : NODE_NONE,
# 970 : 2 : good_time};
# 971 : :
# 972 : : // Gets port changed, will not be re-positioned in vvTried because ports 0 and 10537 result in
# 973 : : // the same position (bucket, i).
# 974 : 2 : const CAddress i2p_tried2{
# 975 : 2 : ResolveService("pjs7or2ctvteeo5tu4bwyrtydeuhqhvdprtujn4daxr75jpebjxa.b32.i2p", 10537),
# 976 : 2 : NODE_NONE,
# 977 : 2 : good_time};
# 978 : :
# 979 : : // Remains unchanged, port is already as it should be.
# 980 : 2 : const CAddress i2p_tried3{
# 981 : 2 : ResolveService("hnbbyjpxx54623l555sta7pocy3se4sdgmuebi5k6reesz5rjp6q.b32.i2p",
# 982 : 2 : i2p::sam::PORT_SAM31),
# 983 : 2 : NODE_NONE,
# 984 : 2 : good_time};
# 985 : :
# 986 : : // Gets removed because after changing the port it will collide with i2p_tried3.
# 987 : 2 : const CAddress i2p_tried4{
# 988 : 2 : ResolveService("hna37nqr3ahkqv62cuqfwgtneekvvpnuc4i4f6yo7tpoqjswvcwa.b32.i2p", port),
# 989 : 2 : NODE_NONE,
# 990 : 2 : good_time};
# 991 : :
# 992 : : // Remains unchanged.
# 993 : 2 : const CAddress ipv4_tried{ResolveService("2.3.4.5", port), NODE_NONE, good_time};
# 994 : :
# 995 : 2 : const CNetAddr source;
# 996 : :
# 997 : 2 : CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
# 998 : :
# 999 : 2 : addrman1.Add(i2p_new1, source);
# 1000 : 2 : addrman1.Add(i2p_new2, source);
# 1001 : 2 : addrman1.Add(i2p_new3, source);
# 1002 : 2 : addrman1.Add(i2p_new4, source);
# 1003 : 2 : addrman1.Add(ipv4_new, source);
# 1004 : :
# 1005 : 2 : addrman1.Add(i2p_tried1, source);
# 1006 : 2 : addrman1.Good(i2p_tried1);
# 1007 : 2 : addrman1.Add(i2p_tried2, source);
# 1008 : 2 : addrman1.Good(i2p_tried2);
# 1009 : 2 : addrman1.Add(i2p_tried3, source);
# 1010 : 2 : addrman1.Good(i2p_tried3);
# 1011 : 2 : addrman1.Add(i2p_tried4, source);
# 1012 : 2 : addrman1.Good(i2p_tried4);
# 1013 : 2 : addrman1.Add(ipv4_tried, source);
# 1014 : 2 : addrman1.Good(ipv4_tried);
# 1015 : :
# 1016 : 2 : stream << addrman1;
# 1017 : 2 : stream >> addrman2;
# 1018 : :
# 1019 : 2 : auto addresses = addrman2.GetAddr(0, 0, NET_I2P);
# 1020 : 2 : BOOST_REQUIRE_EQUAL(addresses.size(), 6UL);
# 1021 : 2 : std::sort(addresses.begin(), addresses.end()); // Just some deterministic order.
# 1022 : 2 : BOOST_CHECK_EQUAL(addresses[0].ToStringIP(), i2p_new3.ToStringIP());
# 1023 : 2 : BOOST_CHECK_EQUAL(addresses[0].GetPort(), i2p::sam::PORT_SAM31);
# 1024 : 2 : BOOST_CHECK_EQUAL(addresses[1].ToStringIP(), i2p_new2.ToStringIP());
# 1025 : 2 : BOOST_CHECK_EQUAL(addresses[1].GetPort(), i2p::sam::PORT_SAM31);
# 1026 : 2 : BOOST_CHECK_EQUAL(addresses[2].ToStringIP(), i2p_tried3.ToStringIP());
# 1027 : 2 : BOOST_CHECK_EQUAL(addresses[2].GetPort(), i2p::sam::PORT_SAM31);
# 1028 : 2 : BOOST_CHECK_EQUAL(addresses[3].ToStringIP(), i2p_tried1.ToStringIP());
# 1029 : 2 : BOOST_CHECK_EQUAL(addresses[3].GetPort(), i2p::sam::PORT_SAM31);
# 1030 : 2 : BOOST_CHECK_EQUAL(addresses[4].ToStringIP(), i2p_tried2.ToStringIP());
# 1031 : 2 : BOOST_CHECK_EQUAL(addresses[4].GetPort(), i2p::sam::PORT_SAM31);
# 1032 : 2 : BOOST_CHECK_EQUAL(addresses[5].ToStringIP(), i2p_new1.ToStringIP());
# 1033 : 2 : BOOST_CHECK_EQUAL(addresses[5].GetPort(), i2p::sam::PORT_SAM31);
# 1034 : :
# 1035 : 2 : addresses = addrman2.GetAddr(0, 0, NET_IPV4);
# 1036 : 2 : BOOST_REQUIRE_EQUAL(addresses.size(), 2UL);
# 1037 : 2 : std::sort(addresses.begin(), addresses.end()); // Just some deterministic order.
# 1038 : 2 : BOOST_CHECK_EQUAL(addresses[0].ToStringIPPort(), ipv4_new.ToStringIPPort());
# 1039 : 2 : BOOST_CHECK_EQUAL(addresses[1].ToStringIPPort(), ipv4_tried.ToStringIPPort());
# 1040 : 2 : }
# 1041 : :
# 1042 : : BOOST_AUTO_TEST_SUITE_END()
|