LCOV - code coverage report
Current view: top level - src/test - addrman_tests.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 563 564 99.8 %
Date: 2020-09-26 01:30:44 Functions: 135 135 100.0 %

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

Generated by: LCOV version 1.15