18#include <boost/test/unit_test.hpp> 
   23using namespace std::literals;
 
   31        : 
AddrMan( std::vector<bool>(),  true,  100)
 
   50        unsigned char nVersion = 1;
 
   52        s << ((
unsigned char)32);
 
   74    ssPeersIn << _addrman;
 
   75    std::string str = ssPeersIn.
str();
 
   76    std::vector<unsigned char> vchData(str.begin(), str.end());
 
   86                         std::vector<bool> asmap = std::vector<bool>())
 
   87        : 
AddrMan(asmap, makeDeterministic,  100)
 
   95        return m_impl->Find(addr, pnId);
 
  101        return m_impl->Create(addr, addrSource, pnId);
 
  114        int nId = 
m_impl->mapAddr[addr];
 
  117                if (nId == 
m_impl->vvNew[bucket][entry]) {
 
  118                    return std::pair<int, int>(bucket, entry);
 
  122        return std::pair<int, int>(-1, -1);
 
  128         int64_t nLastSuccess = 1;
 
  130         Good(addr, nLastSuccess);
 
  132         bool count_failure = 
false;
 
  134         Attempt(addr, count_failure, nLastTry);
 
  148    BOOST_CHECK_MESSAGE(
Lookup(
ip, serv, port, 
false), 
strprintf(
"failed to resolve: %s:%i", 
ip, port));
 
  154    std::vector<bool> result(vector_size);
 
  155    for (
int byte_i = 0; byte_i < vector_size / 8; ++byte_i) {
 
  156        unsigned char cur_byte = 
source[byte_i];
 
  157        for (
int bit_i = 0; bit_i < 8; ++bit_i) {
 
  158            result[byte_i * 8 + bit_i] = (cur_byte >> bit_i) & 1;
 
  169    auto addrman = std::make_unique<AddrManTest>();
 
  175    auto addr_null = addrman->Select().first;
 
  182    auto addr_ret1 = addrman->Select().first;
 
  203    addrman = std::make_unique<AddrManTest>();
 
  204    std::vector<CAddress> vAddr;
 
  227    auto addr_ret2 = addrman.
Select().first;
 
  228    BOOST_CHECK(addr_ret2.ToString() == 
"250.1.1.1:8333" || addr_ret2.ToString() == 
"250.1.1.1:8334");
 
  235    auto addr_ret3 = addrman.
Select(newOnly).first;
 
  252    auto addr_ret1 = addrman.
Select(newOnly).first;
 
  258    auto addr_ret2 = addrman.
Select(newOnly).first;
 
  261    auto addr_ret3 = addrman.
Select().first;
 
  292    std::set<uint16_t> ports;
 
  293    for (
int i = 0; i < 20; ++i) {
 
  294        ports.insert(addrman.
Select().first.GetPort());
 
  305    uint32_t num_addrs{0};
 
  309    while (num_addrs < 22) {  
 
  319    uint32_t collisions{1};
 
  334    uint32_t num_addrs{0};
 
  338    while (num_addrs < 64) {  
 
  349    uint32_t collisions{1};
 
  377    BOOST_REQUIRE(info1);
 
  382    BOOST_REQUIRE(info2);
 
  387    BOOST_REQUIRE(info3);
 
  438    std::vector<CAddress> vAddr1 = addrman.
GetAddr( 0,  0,  std::nullopt);
 
  469    for (
unsigned int i = 1; i < (8 * 256); i++) {
 
  470        int octet1 = i % 256;
 
  471        int octet2 = i >> 8 % 256;
 
  481    std::vector<CAddress> vAddr = addrman.
GetAddr( 2500,  23,  std::nullopt);
 
  483    size_t percent23 = (addrman.
size() * 23) / 100;
 
  506    std::vector<bool> asmap; 
 
  521    std::set<int> buckets;
 
  522    for (
int i = 0; i < 255; i++) {
 
  527        buckets.insert(bucket);
 
  534    for (
int j = 0; j < 255; j++) {
 
  539        buckets.insert(bucket);
 
  560    std::vector<bool> asmap; 
 
  575    std::set<int> buckets;
 
  576    for (
int i = 0; i < 255; i++) {
 
  581        buckets.insert(bucket);
 
  588    for (
int j = 0; j < 4 * 255; j++) {
 
  594        buckets.insert(bucket);
 
  601    for (
int p = 0; p < 255; p++) {
 
  606        buckets.insert(bucket);
 
  654    std::set<int> buckets;
 
  655    for (
int j = 0; j < 255; j++) {
 
  660        buckets.insert(bucket);
 
  667    for (
int j = 0; j < 255; j++) {
 
  672        buckets.insert(bucket);
 
  708    std::set<int> buckets;
 
  709    for (
int i = 0; i < 255; i++) {
 
  714        buckets.insert(bucket);
 
  721    for (
int j = 0; j < 4 * 255; j++) {
 
  727        buckets.insert(bucket);
 
  734    for (
int p = 0; p < 255; p++) {
 
  739        buckets.insert(bucket);
 
  746    for (
int p = 0; p < 255; p++) {
 
  751        buckets.insert(bucket);
 
  763    auto addrman_asmap1 = std::make_unique<AddrManTest>(
true, asmap1);
 
  764    auto addrman_asmap1_dup = std::make_unique<AddrManTest>(
true, asmap1);
 
  765    auto addrman_noasmap = std::make_unique<AddrManTest>();
 
  772    addrman_asmap1->Add({addr}, default_source);
 
  774    stream << *addrman_asmap1;
 
  776    stream >> *addrman_asmap1_dup;
 
  778    std::pair<int, int> bucketAndEntry_asmap1 = addrman_asmap1->GetBucketAndEntry(addr);
 
  779    std::pair<int, int> bucketAndEntry_asmap1_dup = addrman_asmap1_dup->GetBucketAndEntry(addr);
 
  781    BOOST_CHECK(bucketAndEntry_asmap1_dup.second != -1);
 
  783    BOOST_CHECK(bucketAndEntry_asmap1.first == bucketAndEntry_asmap1_dup.first);
 
  784    BOOST_CHECK(bucketAndEntry_asmap1.second == bucketAndEntry_asmap1_dup.second);
 
  787    stream << *addrman_asmap1;
 
  788    stream >> *addrman_noasmap;
 
  789    std::pair<int, int> bucketAndEntry_noasmap = addrman_noasmap->GetBucketAndEntry(addr);
 
  791    BOOST_CHECK(bucketAndEntry_asmap1.first != bucketAndEntry_noasmap.first);
 
  792    BOOST_CHECK(bucketAndEntry_asmap1.second != bucketAndEntry_noasmap.second);
 
  795    addrman_asmap1 = std::make_unique<AddrManTest>(
true, asmap1);
 
  796    addrman_noasmap = std::make_unique<AddrManTest>();
 
  797    addrman_noasmap->Add({addr}, default_source);
 
  798    stream << *addrman_noasmap;
 
  799    stream >> *addrman_asmap1;
 
  800    std::pair<int, int> bucketAndEntry_asmap1_deser = addrman_asmap1->GetBucketAndEntry(addr);
 
  801    BOOST_CHECK(bucketAndEntry_asmap1_deser.second != -1);
 
  802    BOOST_CHECK(bucketAndEntry_asmap1_deser.first != bucketAndEntry_noasmap.first);
 
  803    BOOST_CHECK(bucketAndEntry_asmap1_deser.first == bucketAndEntry_asmap1_dup.first);
 
  804    BOOST_CHECK(bucketAndEntry_asmap1_deser.second == bucketAndEntry_asmap1_dup.second);
 
  807    addrman_asmap1 = std::make_unique<AddrManTest>(
true, asmap1);
 
  808    addrman_noasmap = std::make_unique<AddrManTest>();
 
  811    addrman_noasmap->Add({addr, 
addr2}, default_source);
 
  812    std::pair<int, int> bucketAndEntry_noasmap_addr1 = addrman_noasmap->GetBucketAndEntry(
addr1);
 
  813    std::pair<int, int> bucketAndEntry_noasmap_addr2 = addrman_noasmap->GetBucketAndEntry(
addr2);
 
  814    BOOST_CHECK(bucketAndEntry_noasmap_addr1.first != bucketAndEntry_noasmap_addr2.first);
 
  815    BOOST_CHECK(bucketAndEntry_noasmap_addr1.second != bucketAndEntry_noasmap_addr2.second);
 
  816    stream << *addrman_noasmap;
 
  817    stream >> *addrman_asmap1;
 
  818    std::pair<int, int> bucketAndEntry_asmap1_deser_addr1 = addrman_asmap1->GetBucketAndEntry(
addr1);
 
  819    std::pair<int, int> bucketAndEntry_asmap1_deser_addr2 = addrman_asmap1->GetBucketAndEntry(
addr2);
 
  820    BOOST_CHECK(bucketAndEntry_asmap1_deser_addr1.first == bucketAndEntry_asmap1_deser_addr2.first);
 
  821    BOOST_CHECK(bucketAndEntry_asmap1_deser_addr1.second != bucketAndEntry_asmap1_deser_addr2.second);
 
  828    auto addrman = std::make_unique<AddrManTest>();
 
  836    addrman->Add({new1, tried1, new2, tried2}, 
CNetAddr{});
 
  837    addrman->Good(tried1);
 
  838    addrman->Good(tried2);
 
  839    BOOST_REQUIRE_EQUAL(addrman->size(), 4);
 
  843    const std::string str{stream.
str()};
 
  846    const char new2_raw[]{6, 6, 6, 6};
 
  847    const uint8_t new2_raw_replacement[]{0, 0, 0, 0}; 
 
  848    pos = str.find(new2_raw, 0, 
sizeof(new2_raw));
 
  849    BOOST_REQUIRE(pos != std::string::npos);
 
  850    BOOST_REQUIRE(pos + 
sizeof(new2_raw_replacement) <= stream.
size());
 
  851    memcpy(stream.
data() + pos, new2_raw_replacement, 
sizeof(new2_raw_replacement));
 
  853    const char tried2_raw[]{8, 8, 8, 8};
 
  854    const uint8_t tried2_raw_replacement[]{255, 255, 255, 255}; 
 
  855    pos = str.find(tried2_raw, 0, 
sizeof(tried2_raw));
 
  856    BOOST_REQUIRE(pos != std::string::npos);
 
  857    BOOST_REQUIRE(pos + 
sizeof(tried2_raw_replacement) <= stream.
size());
 
  858    memcpy(stream.
data() + pos, tried2_raw_replacement, 
sizeof(tried2_raw_replacement));
 
  860    addrman = std::make_unique<AddrManTest>();
 
  876    for (
unsigned int i = 1; i < 23; i++) {
 
  887    for (
unsigned int i = 1; i < 23; i++) {
 
  903    for (
unsigned int i = 1; i < 36; i++) {
 
  916    addrman.
Good(addr36);
 
  926    for (
unsigned int i = 37; i < 59; i++) {
 
  938    addrman.
Good(addr59);
 
  945    addrman.
Good(addr36);
 
  964    for (
unsigned int i = 1; i < 36; i++) {
 
  999    addrman.
Good(addr19);
 
 1027    bool exceptionThrown = 
false;
 
 1028    AddrMan addrman1( std::vector<bool>(),  
false,  100);
 
 1032        unsigned char pchMsgTmp[4];
 
 1033        ssPeers1 >> pchMsgTmp;
 
 1034        ssPeers1 >> addrman1;
 
 1035    } 
catch (
const std::exception&) {
 
 1036        exceptionThrown = 
true;
 
 1045    AddrMan addrman2( std::vector<bool>(),  
false,  100);
 
 1058    bool exceptionThrown = 
false;
 
 1059    AddrMan addrman1( std::vector<bool>(),  
false,  100);
 
 1062        unsigned char pchMsgTmp[4];
 
 1063        ssPeers1 >> pchMsgTmp;
 
 1064        ssPeers1 >> addrman1;
 
 1065    } 
catch (
const std::exception&) {
 
 1066        exceptionThrown = 
true;
 
 1075    AddrMan addrman2( std::vector<bool>(),  
false,  100);
 
void ReadFromStream(AddrMan &addr, CDataStream &ssPeers)
Only used by tests.
static constexpr int ADDRMAN_BUCKET_SIZE
static constexpr int ADDRMAN_NEW_BUCKET_COUNT
static std::vector< bool > FromBytes(const unsigned char *source, int vector_size)
static CService ResolveService(const std::string &ip, uint16_t port=0)
static CDataStream AddrmanToStream(const AddrManSerializationMock &_addrman)
BOOST_AUTO_TEST_CASE(addrman_simple)
static CNetAddr ResolveIP(const std::string &ip)
static unsigned const char asmap_raw[]
const CChainParams & Params()
Return the currently selected parameters.
Extended statistics about a CAddress.
int GetTriedBucket(const uint256 &nKey, const std::vector< bool > &asmap) const
Calculate in which "tried" bucket this entry belongs.
int GetNewBucket(const uint256 &nKey, const CNetAddr &src, const std::vector< bool > &asmap) const
Calculate in which "new" bucket this entry belongs, given a certain source.
void Serialize(CDataStream &s) const override
Stochastic address manager.
std::pair< CAddress, int64_t > SelectTriedCollision()
Randomly select an address in the tried table that another address is attempting to evict.
const std::unique_ptr< AddrManImpl > m_impl
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct, std::optional< Network > network) const
Return all or many randomly selected addresses, optionally by network.
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, int64_t nTimePenalty=0)
Attempt to add one or more addresses to addrman's new table.
void Good(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible, possibly moving it from "new" to "tried".
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
void Serialize(Stream &s_) const
size_t size() const
Return the number of (unique) addresses in all tables.
std::pair< CAddress, int64_t > Select(bool newOnly=false) const
Choose an address to connect to.
virtual void Serialize(CDataStream &s) const =0
AddrManSerializationMock()
AddrManTest(bool makeDeterministic=true, std::vector< bool > asmap=std::vector< bool >())
std::pair< int, int > GetBucketAndEntry(const CAddress &addr)
void SimConnFail(const CService &addr)
AddrInfo * Find(const CService &addr, int *pnId=nullptr)
AddrInfo * Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId=nullptr)
void Serialize(CDataStream &s) const override
A CService with information about it as peer.
uint32_t nTime
Always included in serialization.
const CMessageHeader::MessageStartChars & MessageStart() const
Double ended buffer combining vector and stream-like interfaces.
A writer stream (for serialization) that computes a 256-bit hash.
A combination of a network address (CNetAddr) and a (TCP) port.
std::string ToString() const
std::vector< unsigned char > GetKey() const
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
BOOST_AUTO_TEST_SUITE_END()
static CService ip(uint32_t i)
static const std::string addr1
static const std::string addr2
bool Lookup(const std::string &name, std::vector< CService > &vAddr, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function)
Resolve a service string to its corresponding service.
bool LookupHost(const std::string &name, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
Resolve a host string to its corresponding network addresses.
#define BOOST_CHECK_THROW(stmt, excMatch)
#define BOOST_FIXTURE_TEST_SUITE(a, b)
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
int64_t GetAdjustedTime()
static const int PROTOCOL_VERSION
network protocol versioning