LCOV - code coverage report
Current view: top level - src/test - addrman_tests.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 541 543 99.6 %
Date: 2025-04-02 01:23:23 Functions: 45 45 100.0 %

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

Generated by: LCOV version 1.14