From 0c23c01a6c8de26e2c17447b7d59a63261c4e51f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 26 Mar 2016 10:58:00 -0700 Subject: [PATCH 1/6] Keep addrman's nService bits consistent with outbound observations --- src/addrman.cpp | 18 ++++++++++++++++++ src/addrman.h | 13 ++++++++++++- src/main.cpp | 3 +++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 2a3ce3f6fcbe0..053225430d73f 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -503,6 +503,24 @@ void CAddrMan::Connected_(const CService& addr, int64_t nTime) info.nTime = nTime; } +void CAddrMan::SetServices_(const CService& addr, uint64_t nServices) +{ + CAddrInfo* pinfo = Find(addr); + + // if not found, bail out + if (!pinfo) + return; + + CAddrInfo& info = *pinfo; + + // check whether we are talking about the exact same CService (including same port) + if (info != addr) + return; + + // update info + info.nServices = nServices; +} + int CAddrMan::RandomInt(int nMax){ return GetRandInt(nMax); } diff --git a/src/addrman.h b/src/addrman.h index cfc1b947d8013..394b9532d5c55 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -1,5 +1,5 @@ // Copyright (c) 2012 Pieter Wuille -// Copyright (c) 2012-2014 The Bitcoin developers +// Copyright (c) 2012-2015 The Bitcoin developers // Copyright (c) 2017-2020 The PIVX developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -264,6 +264,9 @@ class CAddrMan //! Mark an entry as currently-connected-to. void Connected_(const CService& addr, int64_t nTime); + //! Update an entry's service bits. + void SetServices_(const CService& addr, uint64_t nServices); + public: /** * serialized format: @@ -589,6 +592,14 @@ class CAddrMan Check(); } } + + void SetServices(const CService& addr, uint64_t nServices) + { + LOCK(cs); + Check(); + SetServices_(addr, nServices); + Check(); + } }; #endif // BITCOIN_ADDRMAN_H diff --git a/src/main.cpp b/src/main.cpp index d8e7a2e02dc2f..f6a74baf11767 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5234,6 +5234,9 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR CAddress addrFrom; uint64_t nNonce = 1; vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; + if (!pfrom->fInbound) { + addrman.SetServices(pfrom->addr, pfrom->nServices); + } if (pfrom->DisconnectOldProtocol(ActiveProtocol(), strCommand)) return false; From 1905a6a0941e432c7533e3f9d3ecc58763a88f0c Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 26 Mar 2016 11:09:22 -0700 Subject: [PATCH 2/6] Verify that outbound connections have expected services --- src/main.cpp | 8 ++++++++ src/net.cpp | 5 +++++ src/net.h | 1 + 3 files changed, 14 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index f6a74baf11767..f462b6c4eb5ca 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5237,6 +5237,14 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR if (!pfrom->fInbound) { addrman.SetServices(pfrom->addr, pfrom->nServices); } + if (pfrom->nServicesExpected & ~pfrom->nServices) { + LogPrint(BCLog::NET, "peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n", pfrom->id, pfrom->nServices, pfrom->nServicesExpected); + pfrom->PushMessage(NetMsgType::REJECT, strCommand, REJECT_NONSTANDARD, + strprintf("Expected to offer services %08x", pfrom->nServicesExpected)); + pfrom->fDisconnect = true; + return false; + } + if (pfrom->DisconnectOldProtocol(ActiveProtocol(), strCommand)) return false; diff --git a/src/net.cpp b/src/net.cpp index ea8e4dd7cae3d..4169d76eb9eda 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -67,6 +67,9 @@ struct ListenSocket { }; } +/** Services this node implementation cares about */ +static const uint64_t nRelevantServices = NODE_NETWORK; + // // Global state variables // @@ -446,6 +449,7 @@ CNode* ConnectNode(CAddress addrConnect, const char* pszDest, bool fCountFailure vNodes.push_back(pnode); } + pnode->nServicesExpected = addrConnect.nServices & nRelevantServices; pnode->nTimeConnected = GetTime(); return pnode; @@ -2108,6 +2112,7 @@ unsigned int SendBufferSize() { return 1000 * GetArg("-maxsendbuffer", 1 * 1000) CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), setAddrKnown(5000) { nServices = 0; + nServicesExpected = 0; hSocket = hSocketIn; nRecvVersion = INIT_PROTO_VERSION; nLastSend = 0; diff --git a/src/net.h b/src/net.h index 11df74dfe3bea..5bd49661285cf 100644 --- a/src/net.h +++ b/src/net.h @@ -296,6 +296,7 @@ class CNode public: // socket uint64_t nServices; + uint64_t nServicesExpected; SOCKET hSocket; CDataStream ssSend; size_t nSendSize; // total size of all vSendMsg entries From 6dba254a01fbe1a8f8f4a7188813b6cb8a9cc55a Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 26 Mar 2016 13:31:25 +0100 Subject: [PATCH 3/6] Only store and connect to NODE_NETWORK nodes --- src/main.cpp | 3 +++ src/net.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index f462b6c4eb5ca..ada4dabcae9d9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5394,6 +5394,9 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR for (CAddress& addr : vAddr) { boost::this_thread::interruption_point(); + if (!(addr.nServices & NODE_NETWORK)) + continue; + if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) addr.nTime = nNow - 5 * 24 * 60 * 60; pfrom->AddAddressKnown(addr); diff --git a/src/net.cpp b/src/net.cpp index 4169d76eb9eda..5a16e410c02fa 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1439,6 +1439,10 @@ void ThreadOpenConnections() if (IsLimited(addr)) continue; + // only connect to full nodes + if (!(addr.nServices & NODE_NETWORK)) + continue; + // only consider very recently tried nodes after 30 failed attempts if (nANow - addr.nLastTry < 600 && nTries < 30) continue; From b6a0455b376282f3af8176d17548eac6d9126003 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 25 May 2016 08:18:37 -0700 Subject: [PATCH 4/6] Don't require services in -addnode --- src/activemasternode.cpp | 4 +- src/masternodeman.cpp | 2 +- src/net.cpp | 17 +++---- src/protocol.cpp | 2 +- src/protocol.h | 2 +- src/rpc/masternode.cpp | 2 +- src/test/DoS_tests.cpp | 8 ++-- src/test/addrman_tests.cpp | 94 +++++++++++++++++++------------------- src/test/net_tests.cpp | 8 ++-- 9 files changed, 70 insertions(+), 69 deletions(-) diff --git a/src/activemasternode.cpp b/src/activemasternode.cpp index 972fd505ff37c..8271eea2a8581 100644 --- a/src/activemasternode.cpp +++ b/src/activemasternode.cpp @@ -76,7 +76,7 @@ void CActiveMasternode::ManageStatus() LogPrintf("CActiveMasternode::ManageStatus() - Checking inbound connection to '%s'\n", service.ToString()); - CNode* pnode = ConnectNode((CAddress)service, NULL, true); + CNode* pnode = ConnectNode(CAddress(service, NODE_NETWORK), NULL, true); if (!pnode) { notCapableReason = "Could not connect to " + service.ToString(); LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason); @@ -244,7 +244,7 @@ bool CActiveMasternode::CreateBroadcast(std::string strService, std::string strK if(!CMasternodeBroadcast::CheckDefaultPort(strService, errorMessage, "CActiveMasternode::CreateBroadcast()")) return false; - addrman.Add(CAddress(service), CNetAddr("127.0.0.1"), 2 * 60 * 60); + addrman.Add(CAddress(service, NODE_NETWORK), CNetAddr("127.0.0.1"), 2 * 60 * 60); return CreateBroadcast(vin, CService(strService), keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage, mnb); } diff --git a/src/masternodeman.cpp b/src/masternodeman.cpp index ab1e43ebc78f3..7fb92d98ae815 100644 --- a/src/masternodeman.cpp +++ b/src/masternodeman.cpp @@ -749,7 +749,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData // - this is checked later by .check() in many places and by ThreadCheckObfuScationPool() if (mnb.CheckInputsAndAdd(nDoS)) { // use this as a peer - addrman.Add(CAddress(mnb.addr), pfrom->addr, 2 * 60 * 60); + addrman.Add(CAddress(mnb.addr, NODE_NETWORK), pfrom->addr, 2 * 60 * 60); masternodeSync.AddedMasternodeList(mnb.GetHash()); } else { LogPrint(BCLog::MASTERNODE,"mnb - Rejected Masternode entry %s\n", mnb.vin.prevout.hash.ToString()); diff --git a/src/net.cpp b/src/net.cpp index 5a16e410c02fa..7bf052c87bd9d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2015 The Bitcoin developers // Copyright (c) 2014-2015 The Dash developers // Copyright (c) 2015-2020 The PIVX developers // Distributed under the MIT/X11 software license, see the accompanying @@ -160,7 +160,7 @@ static std::vector convertSeed6(const std::vector& vSeedsIn for (std::vector::const_iterator i(vSeedsIn.begin()); i != vSeedsIn.end(); ++i) { struct in6_addr ip; memcpy(&ip, i->addr, sizeof(ip)); - CAddress addr(CService(ip, i->port)); + CAddress addr(CService(ip, i->port), NODE_NETWORK); addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek; vSeedsOut.push_back(addr); } @@ -176,9 +176,8 @@ CAddress GetLocalAddress(const CNetAddr* paddrPeer) CAddress ret(CService("0.0.0.0", GetListenPort()), 0); CService addr; if (GetLocal(addr, paddrPeer)) { - ret = CAddress(addr); + ret = CAddress(addr, nLocalServices); } - ret.nServices = nLocalServices; ret.nTime = GetAdjustedTime(); return ret; } @@ -494,7 +493,7 @@ void CNode::PushVersion() /// when NTP implemented, change to just nTime = GetAdjustedTime() int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime()); - CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0", 0))); + CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0", 0), addr.nServices)); CAddress addrMe = GetLocalAddress(&addr); GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); if (fLogIPs) @@ -1302,7 +1301,7 @@ void ThreadDNSAddressSeed() } else { std::vector vIPs; std::vector vAdd; - uint64_t requiredServiceBits = NODE_NETWORK; + uint64_t requiredServiceBits = nRelevantServices; if (LookupHost(seed.getHost(requiredServiceBits).c_str(), vIPs, 0, true)) { for (CNetAddr& ip : vIPs) { int nOneDay = 24 * 3600; @@ -1370,7 +1369,7 @@ void ThreadOpenConnections() for (int64_t nLoop = 0;; nLoop++) { ProcessOneShot(); for (std::string strAddr : mapMultiArgs["-connect"]) { - CAddress addr; + CAddress addr(CService(), 0); OpenNetworkConnection(addr, false, NULL, strAddr.c_str()); for (int i = 0; i < 10 && i < nLoop; i++) { MilliSleep(500); @@ -1520,7 +1519,9 @@ void ThreadOpenAddedConnections() } for (std::vector& vserv : lservAddressesToAdd) { CSemaphoreGrant grant(*semOutbound); - OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), false, &grant); + /* We want -addnode to work even for nodes that don't provide all + * wanted services, so pass in nServices=0 to CAddress. */ + OpenNetworkConnection(CAddress(vserv[i % vserv.size()], 0), false, &grant); MilliSleep(500); } MilliSleep(120000); // Retry every 2 minutes diff --git a/src/protocol.cpp b/src/protocol.cpp index 728ac0fb922ba..b93ac78937aa8 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -179,7 +179,7 @@ CAddress::CAddress(CService ipIn, uint64_t nServicesIn) : CService(ipIn) void CAddress::Init() { - nServices = NODE_NETWORK; + nServices = 0; nTime = 100000000; } diff --git a/src/protocol.h b/src/protocol.h index 4ede64630bc6c..fb99e2017c52b 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -310,7 +310,7 @@ class CAddress : public CService { public: CAddress(); - explicit CAddress(CService ipIn, uint64_t nServicesIn = NODE_NETWORK); + explicit CAddress(CService ipIn, uint64_t nServicesIn); void Init(); diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index e5ac7cef0e335..dd37d84d0f4c7 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -119,7 +119,7 @@ UniValue masternodeconnect(const UniValue& params, bool fHelp) CService addr = CService(strAddress); - CNode* pnode = ConnectNode((CAddress)addr, NULL, true); + CNode* pnode = ConnectNode(CAddress(addr, NODE_NETWORK), NULL, true); if (pnode) { pnode->Release(); return NullUniValue; diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index a0a628f63d060..e45dd03389ba8 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -48,7 +48,7 @@ BOOST_FIXTURE_TEST_SUITE(DoS_tests, TestingSetup) BOOST_AUTO_TEST_CASE(DoS_banning) { CNode::ClearBanned(); - CAddress addr1(ip(0xa0b0c001)); + CAddress addr1(ip(0xa0b0c001), 0); CNode dummyNode1(INVALID_SOCKET, addr1, "", true); dummyNode1.nVersion = 1; Misbehaving(dummyNode1.GetId(), 100); // Should get banned @@ -56,7 +56,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning) BOOST_CHECK(CNode::IsBanned(addr1)); BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned - CAddress addr2(ip(0xa0b0c002)); + CAddress addr2(ip(0xa0b0c002), 0); CNode dummyNode2(INVALID_SOCKET, addr2, "", true); dummyNode2.nVersion = 1; Misbehaving(dummyNode2.GetId(), 50); @@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore) { CNode::ClearBanned(); mapArgs["-banscore"] = "111"; // because 11 is my favorite number - CAddress addr1(ip(0xa0b0c001)); + CAddress addr1(ip(0xa0b0c001), 0); CNode dummyNode1(INVALID_SOCKET, addr1, "", true); dummyNode1.nVersion = 1; Misbehaving(dummyNode1.GetId(), 100); @@ -93,7 +93,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) int64_t nStartTime = GetTime(); SetMockTime(nStartTime); // Overrides future calls to GetTime() - CAddress addr(ip(0xa0b0c001)); + CAddress addr(ip(0xa0b0c001), 0); CNode dummyNode(INVALID_SOCKET, addr, "", true); dummyNode.nVersion = 1; diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index d2b5e170b674f..98933b2f250d2 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Copyright (c) 2019 The PIVX developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -68,7 +68,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple) // Test 2: Does Addrman::Add work as expected. CService addr1 = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1), source); + addrman.Add(CAddress(addr1, 0), source); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret1 = addrman.Select(); BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); @@ -76,14 +76,14 @@ BOOST_AUTO_TEST_CASE(addrman_simple) // Test 3: Does IP address deduplication work correctly. // Expected dup IP should not be added. CService addr1_dup = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1_dup), source); + addrman.Add(CAddress(addr1_dup, 0), source); BOOST_CHECK(addrman.size() == 1); // Test 5: New table has one addr and we add a diff addr we should // have two addrs. CService addr2 = CService("250.1.1.2", 8333); - addrman.Add(CAddress(addr2), source); + addrman.Add(CAddress(addr2, 0), source); BOOST_CHECK(addrman.size() == 2); // Test 6: AddrMan::Clear() should empty the new table. @@ -106,18 +106,18 @@ BOOST_AUTO_TEST_CASE(addrman_ports) // Test 7; Addr with same IP but diff port does not replace existing addr. CService addr1 = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1), source); + addrman.Add(CAddress(addr1, 0), source); BOOST_CHECK(addrman.size() == 1); CService addr1_port = CService("250.1.1.1", 8334); - addrman.Add(CAddress(addr1_port), source); + addrman.Add(CAddress(addr1_port, 0), source); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret2 = addrman.Select(); BOOST_CHECK(addr_ret2.ToString() == "250.1.1.1:8333"); // Test 8: Add same IP but diff port to tried table, it doesn't get added. // Perhaps this is not ideal behavior but it is the current behavior. - addrman.Good(CAddress(addr1_port)); + addrman.Good(CAddress(addr1_port, 0)); BOOST_CHECK(addrman.size() == 1); bool newOnly = true; CAddrInfo addr_ret3 = addrman.Select(newOnly); @@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(addrman_select) // Test 9: Select from new with 1 addr in new. CService addr1 = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1), source); + addrman.Add(CAddress(addr1, 0), source); BOOST_CHECK(addrman.size() == 1); bool newOnly = true; @@ -144,7 +144,7 @@ BOOST_AUTO_TEST_CASE(addrman_select) BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); // Test 10: move addr to tried, select from new expected nothing returned. - addrman.Good(CAddress(addr1)); + addrman.Good(CAddress(addr1, 0)); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret2 = addrman.Select(newOnly); BOOST_CHECK(addr_ret2.ToString() == "[::]:0"); @@ -160,21 +160,21 @@ BOOST_AUTO_TEST_CASE(addrman_select) CService addr3 = CService("250.3.2.2", 9999); CService addr4 = CService("250.3.3.3", 9999); - addrman.Add(CAddress(addr2), CService("250.3.1.1", 8333)); - addrman.Add(CAddress(addr3), CService("250.3.1.1", 8333)); - addrman.Add(CAddress(addr4), CService("250.4.1.1", 8333)); + addrman.Add(CAddress(addr2, 0), CService("250.3.1.1", 8333)); + addrman.Add(CAddress(addr3, 0), CService("250.3.1.1", 8333)); + addrman.Add(CAddress(addr4, 0), CService("250.4.1.1", 8333)); // Add three addresses to tried table. CService addr5 = CService("250.4.4.4", 8333); CService addr6 = CService("250.4.5.5", 7777); CService addr7 = CService("250.4.6.6", 8333); - addrman.Add(CAddress(addr5), CService("250.3.1.1", 8333)); - addrman.Good(CAddress(addr5)); - addrman.Add(CAddress(addr6), CService("250.3.1.1", 8333)); - addrman.Good(CAddress(addr6)); - addrman.Add(CAddress(addr7), CService("250.1.1.3", 8333)); - addrman.Good(CAddress(addr7)); + addrman.Add(CAddress(addr5, 0), CService("250.3.1.1", 8333)); + addrman.Good(CAddress(addr5, 0)); + addrman.Add(CAddress(addr6, 0), CService("250.3.1.1", 8333)); + addrman.Good(CAddress(addr6, 0)); + addrman.Add(CAddress(addr7, 0), CService("250.1.1.3", 8333)); + addrman.Good(CAddress(addr7, 0)); // Test 11: 6 addrs + 1 addr from last test = 7. BOOST_CHECK(addrman.size() == 7); @@ -200,7 +200,7 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) for (int i = 1; i < 18; i++) { CService addr = CService("250.1.1." + boost::to_string(i)); - addrman.Add(CAddress(addr), source); + addrman.Add(CAddress(addr, 0), source); //Test 13: No collision in new table yet. BOOST_CHECK(addrman.size() == i); @@ -208,11 +208,11 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) //Test 14: new table collision! CService addr1 = CService("250.1.1.18"); - addrman.Add(CAddress(addr1), source); + addrman.Add(CAddress(addr1, 0), source); BOOST_CHECK(addrman.size() == 17); CService addr2 = CService("250.1.1.19"); - addrman.Add(CAddress(addr2), source); + addrman.Add(CAddress(addr2, 0), source); BOOST_CHECK(addrman.size() == 18); } @@ -229,8 +229,8 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) for (int i = 1; i < 80; i++) { CService addr = CService("250.1.1." + boost::to_string(i)); - addrman.Add(CAddress(addr), source); - addrman.Good(CAddress(addr)); + addrman.Add(CAddress(addr, 0), source); + addrman.Good(CAddress(addr, 0)); //Test 15: No collision in tried table yet. BOOST_TEST_MESSAGE(addrman.size()); @@ -239,11 +239,11 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) //Test 16: tried table collision! CService addr1 = CService("250.1.1.80"); - addrman.Add(CAddress(addr1), source); + addrman.Add(CAddress(addr1, 0), source); BOOST_CHECK(addrman.size() == 79); CService addr2 = CService("250.1.1.81"); - addrman.Add(CAddress(addr2), source); + addrman.Add(CAddress(addr2, 0), source); BOOST_CHECK(addrman.size() == 80); } @@ -256,9 +256,9 @@ BOOST_AUTO_TEST_CASE(addrman_find) BOOST_CHECK(addrman.size() == 0); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); - CAddress addr2 = CAddress(CService("250.1.2.1", 9999)); - CAddress addr3 = CAddress(CService("251.255.2.1", 8333)); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); + CAddress addr2 = CAddress(CService("250.1.2.1", 9999), 0); + CAddress addr3 = CAddress(CService("251.255.2.1", 8333), 0); CNetAddr source1 = CNetAddr("250.1.2.1"); CNetAddr source2 = CNetAddr("250.1.2.2"); @@ -295,7 +295,7 @@ BOOST_AUTO_TEST_CASE(addrman_create) BOOST_CHECK(addrman.size() == 0); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); CNetAddr source1 = CNetAddr("250.1.2.1"); int nId; @@ -318,7 +318,7 @@ BOOST_AUTO_TEST_CASE(addrman_delete) BOOST_CHECK(addrman.size() == 0); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); CNetAddr source1 = CNetAddr("250.1.2.1"); int nId; @@ -345,15 +345,15 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) std::vector vAddr1 = addrman.GetAddr(); BOOST_CHECK(vAddr1.size() == 0); - CAddress addr1 = CAddress(CService("250.250.2.1", 8333)); + CAddress addr1 = CAddress(CService("250.250.2.1", 8333), 0); addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false - CAddress addr2 = CAddress(CService("250.251.2.2", 9999)); + CAddress addr2 = CAddress(CService("250.251.2.2", 9999), 0); addr2.nTime = GetAdjustedTime(); - CAddress addr3 = CAddress(CService("251.252.2.3", 8333)); + CAddress addr3 = CAddress(CService("251.252.2.3", 8333), 0); addr3.nTime = GetAdjustedTime(); - CAddress addr4 = CAddress(CService("252.253.3.4", 8333)); + CAddress addr4 = CAddress(CService("252.253.3.4", 8333), 0); addr4.nTime = GetAdjustedTime(); - CAddress addr5 = CAddress(CService("252.254.4.5", 8333)); + CAddress addr5 = CAddress(CService("252.254.4.5", 8333), 0); addr5.nTime = GetAdjustedTime(); CNetAddr source1 = CNetAddr("250.1.2.1"); CNetAddr source2 = CNetAddr("250.2.3.3"); @@ -369,8 +369,8 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) BOOST_CHECK(addrman.GetAddr().size() == 1); // Test 24: Ensure GetAddr works with new and tried addresses. - addrman.Good(CAddress(addr1)); - addrman.Good(CAddress(addr2)); + addrman.Good(CAddress(addr1, 0)); + addrman.Good(CAddress(addr2, 0)); BOOST_CHECK(addrman.GetAddr().size() == 1); // Test 25: Ensure GetAddr still returns 23% when addrman has many addrs. @@ -379,7 +379,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) int octet2 = (i / 256) % 256; int octet3 = (i / (256 * 2)) % 256; std::string strAddr = boost::to_string(octet1) + "." + boost::to_string(octet2) + "." + boost::to_string(octet3) + ".23"; - CAddress addr = CAddress(CService(strAddr)); + CAddress addr = CAddress(CService(strAddr), 0); // Ensure that for all addrs in addrman, isTerrible == false. addr.nTime = GetAdjustedTime(); @@ -404,8 +404,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CAddress addr1 = CAddress(CService("250.1.1.1", 8333)); - CAddress addr2 = CAddress(CService("250.1.1.1", 9999)); + CAddress addr1 = CAddress(CService("250.1.1.1", 8333), 0); + CAddress addr2 = CAddress(CService("250.1.1.1", 9999), 0); CNetAddr source1 = CNetAddr("250.1.1.1"); @@ -432,7 +432,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) std::set buckets; for (int i = 0; i < 255; i++) { CAddrInfo infoi = CAddrInfo( - CAddress(CService("250.1.1." + boost::to_string(i))), + CAddress(CService("250.1.1." + boost::to_string(i)), 0), CNetAddr("250.1.1." + boost::to_string(i))); int bucket = infoi.GetTriedBucket(nKey1); buckets.insert(bucket); @@ -444,7 +444,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) buckets.clear(); for (int j = 0; j < 255; j++) { CAddrInfo infoj = CAddrInfo( - CAddress(CService("250." + boost::to_string(j) + ".1.1")), + CAddress(CService("250." + boost::to_string(j) + ".1.1"), 0), CNetAddr("250." + boost::to_string(j) + ".1.1")); int bucket = infoj.GetTriedBucket(nKey1); buckets.insert(bucket); @@ -461,8 +461,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); - CAddress addr2 = CAddress(CService("250.1.2.1", 9999)); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); + CAddress addr2 = CAddress(CService("250.1.2.1", 9999), 0); CNetAddr source1 = CNetAddr("250.1.2.1"); @@ -485,7 +485,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) std::set buckets; for (int i = 0; i < 255; i++) { CAddrInfo infoi = CAddrInfo( - CAddress(CService("250.1.1." + boost::to_string(i))), + CAddress(CService("250.1.1." + boost::to_string(i)), 0), CNetAddr("250.1.1." + boost::to_string(i))); int bucket = infoi.GetNewBucket(nKey1); buckets.insert(bucket); @@ -498,7 +498,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) for (int j = 0; j < 4 * 255; j++) { CAddrInfo infoj = CAddrInfo(CAddress( CService( - boost::to_string(250 + (j / 255)) + "." + boost::to_string(j % 256) + ".1.1")), + boost::to_string(250 + (j / 255)) + "." + boost::to_string(j % 256) + ".1.1"), 0), CNetAddr("251.4.1.1")); int bucket = infoj.GetNewBucket(nKey1); buckets.insert(bucket); @@ -510,7 +510,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) buckets.clear(); for (int p = 0; p < 255; p++) { CAddrInfo infoj = CAddrInfo( - CAddress(CService("250.1.1.1")), + CAddress(CService("250.1.1.1"), 0), CNetAddr("250." + boost::to_string(p) + ".1.1")); int bucket = infoj.GetNewBucket(nKey1); buckets.insert(bucket); diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 78ac0ded21f02..6670efa1fd457 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -53,7 +53,7 @@ class CAddrManCorrupted : public CAddrManSerializationMock int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30); s << nUBuckets; - CAddress addr = CAddress(CService("252.1.1.1", 7777)); + CAddress addr = CAddress(CService("252.1.1.1", 7777), 0); CAddrInfo info = CAddrInfo(addr, CNetAddr("252.2.2.2")); s << info; } @@ -81,9 +81,9 @@ BOOST_AUTO_TEST_CASE(caddrdb_read) CService addr3 = CService("250.7.3.3", 9999); // Add three addresses to new table. - addrmanUncorrupted.Add(CAddress(addr1), CService("252.5.1.1", 8333)); - addrmanUncorrupted.Add(CAddress(addr2), CService("252.5.1.1", 8333)); - addrmanUncorrupted.Add(CAddress(addr3), CService("252.5.1.1", 8333)); + addrmanUncorrupted.Add(CAddress(addr1, 0), CService("252.5.1.1", 8333)); + addrmanUncorrupted.Add(CAddress(addr2, 0), CService("252.5.1.1", 8333)); + addrmanUncorrupted.Add(CAddress(addr3, 0), CService("252.5.1.1", 8333)); // Test that the de-serialization does not throw an exception. CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted); From d1391e37b925afd73d9d5d219a600a581aa2bc43 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 8 Jun 2016 10:12:22 -0700 Subject: [PATCH 5/6] Introduce enum ServiceFlags for service flags --- src/addrman.cpp | 4 +- src/addrman.h | 4 +- src/init.cpp | 4 +- src/main.cpp | 6 ++- src/net.cpp | 22 ++++----- src/net.h | 10 ++--- src/protocol.cpp | 4 +- src/protocol.h | 22 +++++---- src/test/DoS_tests.cpp | 8 ++-- src/test/addrman_tests.cpp | 92 +++++++++++++++++++------------------- src/test/net_tests.cpp | 8 ++-- 11 files changed, 96 insertions(+), 88 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 053225430d73f..0b38f9f5cce82 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -265,7 +265,7 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP pinfo->nTime = std::max((int64_t)0, addr.nTime - nTimePenalty); // add services - pinfo->nServices |= addr.nServices; + pinfo->nServices = ServiceFlags(pinfo->nServices | addr.nServices); // do not update if no new information is present if (!addr.nTime || (pinfo->nTime && addr.nTime <= pinfo->nTime)) @@ -503,7 +503,7 @@ void CAddrMan::Connected_(const CService& addr, int64_t nTime) info.nTime = nTime; } -void CAddrMan::SetServices_(const CService& addr, uint64_t nServices) +void CAddrMan::SetServices_(const CService& addr, ServiceFlags nServices) { CAddrInfo* pinfo = Find(addr); diff --git a/src/addrman.h b/src/addrman.h index 394b9532d5c55..b8e4badad4010 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -265,7 +265,7 @@ class CAddrMan void Connected_(const CService& addr, int64_t nTime); //! Update an entry's service bits. - void SetServices_(const CService& addr, uint64_t nServices); + void SetServices_(const CService& addr, ServiceFlags nServices); public: /** @@ -593,7 +593,7 @@ class CAddrMan } } - void SetServices(const CService& addr, uint64_t nServices) + void SetServices(const CService& addr, ServiceFlags nServices) { LOCK(cs); Check(); diff --git a/src/init.cpp b/src/init.cpp index 39ad0a19b1446..38fd6489c5878 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2015 The Bitcoin developers // Copyright (c) 2014-2015 The Dash developers // Copyright (c) 2011-2013 The PPCoin developers // Copyright (c) 2013-2014 The NovaCoin Developers @@ -1043,7 +1043,7 @@ bool AppInit2() nMaxDatacarrierBytes = GetArg("-datacarriersize", nMaxDatacarrierBytes); if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) - nLocalServices |= NODE_BLOOM; + nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM); nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); diff --git a/src/main.cpp b/src/main.cpp index ada4dabcae9d9..79083c2b738d1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2015 The Bitcoin developers // Copyright (c) 2014-2015 The Dash developers // Copyright (c) 2011-2013 The PPCoin developers // Copyright (c) 2013-2014 The NovaCoin Developers @@ -5233,7 +5233,9 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR CAddress addrMe; CAddress addrFrom; uint64_t nNonce = 1; - vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; + uint64_t nServiceInt; + vRecv >> pfrom->nVersion >> nServiceInt >> nTime >> addrMe; + pfrom->nServices = ServiceFlags(nServiceInt); if (!pfrom->fInbound) { addrman.SetServices(pfrom->addr, pfrom->nServices); } diff --git a/src/net.cpp b/src/net.cpp index 7bf052c87bd9d..d76ff7df7c024 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -68,14 +68,14 @@ struct ListenSocket { } /** Services this node implementation cares about */ -static const uint64_t nRelevantServices = NODE_NETWORK; +static const ServiceFlags nRelevantServices = NODE_NETWORK; // // Global state variables // bool fDiscover = true; bool fListen = true; -uint64_t nLocalServices = NODE_NETWORK; +ServiceFlags nLocalServices = NODE_NETWORK; RecursiveMutex cs_mapLocalHost; std::map mapLocalHost; static bool vfLimited[NET_MAX] = {}; @@ -173,7 +173,7 @@ static std::vector convertSeed6(const std::vector& vSeedsIn // one by discovery. CAddress GetLocalAddress(const CNetAddr* paddrPeer) { - CAddress ret(CService("0.0.0.0", GetListenPort()), 0); + CAddress ret(CService("0.0.0.0", GetListenPort()), NODE_NONE); CService addr; if (GetLocal(addr, paddrPeer)) { ret = CAddress(addr, nLocalServices); @@ -448,7 +448,7 @@ CNode* ConnectNode(CAddress addrConnect, const char* pszDest, bool fCountFailure vNodes.push_back(pnode); } - pnode->nServicesExpected = addrConnect.nServices & nRelevantServices; + pnode->nServicesExpected = ServiceFlags(addrConnect.nServices & nRelevantServices); pnode->nTimeConnected = GetTime(); return pnode; @@ -500,7 +500,7 @@ void CNode::PushVersion() LogPrint(BCLog::NET, "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id); else LogPrint(BCLog::NET, "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id); - PushMessage(NetMsgType::VERSION, PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, + PushMessage(NetMsgType::VERSION, PROTOCOL_VERSION, (uint64_t)nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, strSubVersion, nBestHeight, true); } @@ -1301,7 +1301,7 @@ void ThreadDNSAddressSeed() } else { std::vector vIPs; std::vector vAdd; - uint64_t requiredServiceBits = nRelevantServices; + ServiceFlags requiredServiceBits = nRelevantServices; if (LookupHost(seed.getHost(requiredServiceBits).c_str(), vIPs, 0, true)) { for (CNetAddr& ip : vIPs) { int nOneDay = 24 * 3600; @@ -1369,7 +1369,7 @@ void ThreadOpenConnections() for (int64_t nLoop = 0;; nLoop++) { ProcessOneShot(); for (std::string strAddr : mapMultiArgs["-connect"]) { - CAddress addr(CService(), 0); + CAddress addr(CService(), NODE_NONE); OpenNetworkConnection(addr, false, NULL, strAddr.c_str()); for (int i = 0; i < 10 && i < nLoop; i++) { MilliSleep(500); @@ -1520,8 +1520,8 @@ void ThreadOpenAddedConnections() for (std::vector& vserv : lservAddressesToAdd) { CSemaphoreGrant grant(*semOutbound); /* We want -addnode to work even for nodes that don't provide all - * wanted services, so pass in nServices=0 to CAddress. */ - OpenNetworkConnection(CAddress(vserv[i % vserv.size()], 0), false, &grant); + * wanted services, so pass in nServices=NODE_NONE to CAddress. */ + OpenNetworkConnection(CAddress(vserv[i % vserv.size()], NODE_NONE), false, &grant); MilliSleep(500); } MilliSleep(120000); // Retry every 2 minutes @@ -2116,8 +2116,8 @@ unsigned int SendBufferSize() { return 1000 * GetArg("-maxsendbuffer", 1 * 1000) CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), setAddrKnown(5000) { - nServices = 0; - nServicesExpected = 0; + nServices = NODE_NONE; + nServicesExpected = NODE_NONE; hSocket = hSocketIn; nRecvVersion = INIT_PROTO_VERSION; nLastSend = 0; diff --git a/src/net.h b/src/net.h index 5bd49661285cf..31b2d4c79a85e 100644 --- a/src/net.h +++ b/src/net.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2015 The Bitcoin developers // Copyright (c) 2015-2020 The PIVX developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -135,7 +135,7 @@ bool validateMasternodeIP(const std::string& addrStr); // valid, reacha extern bool fDiscover; extern bool fListen; -extern uint64_t nLocalServices; +extern ServiceFlags nLocalServices; extern uint64_t nLocalHostNonce; extern CAddrMan addrman; extern int nMaxConnections; @@ -168,7 +168,7 @@ class CNodeStats { public: NodeId nodeid; - uint64_t nServices; + ServiceFlags nServices; int64_t nLastSend; int64_t nLastRecv; int64_t nTimeConnected; @@ -295,8 +295,8 @@ class CNode { public: // socket - uint64_t nServices; - uint64_t nServicesExpected; + ServiceFlags nServices; + ServiceFlags nServicesExpected; SOCKET hSocket; CDataStream ssSend; size_t nSendSize; // total size of all vSendMsg entries diff --git a/src/protocol.cpp b/src/protocol.cpp index b93ac78937aa8..f182cc4da44dc 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -171,7 +171,7 @@ CAddress::CAddress() : CService() Init(); } -CAddress::CAddress(CService ipIn, uint64_t nServicesIn) : CService(ipIn) +CAddress::CAddress(CService ipIn, ServiceFlags nServicesIn) : CService(ipIn) { Init(); nServices = nServicesIn; @@ -179,7 +179,7 @@ CAddress::CAddress(CService ipIn, uint64_t nServicesIn) : CService(ipIn) void CAddress::Init() { - nServices = 0; + nServices = NODE_NONE; nTime = 100000000; } diff --git a/src/protocol.h b/src/protocol.h index fb99e2017c52b..d53444511ad2b 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2015 The Bitcoin developers // Copyright (c) 2014-2015 The Dash developers // Copyright (c) 2016-2020 The PIVX developers // Distributed under the MIT/X11 software license, see the accompanying @@ -283,7 +283,12 @@ extern const char* SYNCSTATUSCOUNT; const std::vector& getAllNetMessageTypes(); /** nServices flags */ -enum { +enum ServiceFlags : uint64_t { + // Nothing + NODE_NONE = 0, + // NODE_NETWORK means that the node is capable of serving the block chain. It is currently + // set by all Bitcoin Core nodes, and is unset by SPV clients or other peers that just want + // network services but don't provide them. NODE_NETWORK = (1 << 0), // NODE_BLOOM means the node is capable and willing to handle bloom-filtered connections. @@ -291,9 +296,8 @@ enum { // but no longer do as of protocol version 70011 (= NO_BLOOM_VERSION) NODE_BLOOM = (1 << 2), - // NODE_BLOOM_WITHOUT_MN means the node has the same features as NODE_BLOOM with the only difference - // that the node doens't want to receive master nodes messages. (the 1<<3 was not picked as constant because on bitcoin 0.14 is witness and we want that update here ) - + // NODE_BLOOM_WITHOUT_MN means the node has the same features as NODE_BLOOM with the only difference + // that the node doesn't want to receive master nodes messages. (the 1<<3 was not picked as constant because on bitcoin 0.14 is witness and we want that update here ) NODE_BLOOM_WITHOUT_MN = (1 << 4), // Bits 24-31 are reserved for temporary experiments. Just pick a bit that @@ -310,7 +314,7 @@ class CAddress : public CService { public: CAddress(); - explicit CAddress(CService ipIn, uint64_t nServicesIn); + explicit CAddress(CService ipIn, ServiceFlags nServicesIn); void Init(); @@ -326,13 +330,15 @@ class CAddress : public CService if ((nType & SER_DISK) || (nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH))) READWRITE(nTime); - READWRITE(nServices); + uint64_t nServicesInt = nServices; + READWRITE(nServicesInt); + nServices = (ServiceFlags)nServicesInt; READWRITE(*(CService*)this); } // TODO: make private (improves encapsulation) public: - uint64_t nServices; + ServiceFlags nServices; // disk and network only unsigned int nTime; diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index e45dd03389ba8..85e1c5258a83d 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -48,7 +48,7 @@ BOOST_FIXTURE_TEST_SUITE(DoS_tests, TestingSetup) BOOST_AUTO_TEST_CASE(DoS_banning) { CNode::ClearBanned(); - CAddress addr1(ip(0xa0b0c001), 0); + CAddress addr1(ip(0xa0b0c001), NODE_NONE); CNode dummyNode1(INVALID_SOCKET, addr1, "", true); dummyNode1.nVersion = 1; Misbehaving(dummyNode1.GetId(), 100); // Should get banned @@ -56,7 +56,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning) BOOST_CHECK(CNode::IsBanned(addr1)); BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned - CAddress addr2(ip(0xa0b0c002), 0); + CAddress addr2(ip(0xa0b0c002), NODE_NONE); CNode dummyNode2(INVALID_SOCKET, addr2, "", true); dummyNode2.nVersion = 1; Misbehaving(dummyNode2.GetId(), 50); @@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore) { CNode::ClearBanned(); mapArgs["-banscore"] = "111"; // because 11 is my favorite number - CAddress addr1(ip(0xa0b0c001), 0); + CAddress addr1(ip(0xa0b0c001), NODE_NONE); CNode dummyNode1(INVALID_SOCKET, addr1, "", true); dummyNode1.nVersion = 1; Misbehaving(dummyNode1.GetId(), 100); @@ -93,7 +93,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) int64_t nStartTime = GetTime(); SetMockTime(nStartTime); // Overrides future calls to GetTime() - CAddress addr(ip(0xa0b0c001), 0); + CAddress addr(ip(0xa0b0c001), NODE_NONE); CNode dummyNode(INVALID_SOCKET, addr, "", true); dummyNode.nVersion = 1; diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index 98933b2f250d2..2f8454a18fd22 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -68,7 +68,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple) // Test 2: Does Addrman::Add work as expected. CService addr1 = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1, 0), source); + addrman.Add(CAddress(addr1, NODE_NONE), source); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret1 = addrman.Select(); BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); @@ -76,14 +76,14 @@ BOOST_AUTO_TEST_CASE(addrman_simple) // Test 3: Does IP address deduplication work correctly. // Expected dup IP should not be added. CService addr1_dup = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1_dup, 0), source); + addrman.Add(CAddress(addr1_dup, NODE_NONE), source); BOOST_CHECK(addrman.size() == 1); // Test 5: New table has one addr and we add a diff addr we should // have two addrs. CService addr2 = CService("250.1.1.2", 8333); - addrman.Add(CAddress(addr2, 0), source); + addrman.Add(CAddress(addr2, NODE_NONE), source); BOOST_CHECK(addrman.size() == 2); // Test 6: AddrMan::Clear() should empty the new table. @@ -106,18 +106,18 @@ BOOST_AUTO_TEST_CASE(addrman_ports) // Test 7; Addr with same IP but diff port does not replace existing addr. CService addr1 = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1, 0), source); + addrman.Add(CAddress(addr1, NODE_NONE), source); BOOST_CHECK(addrman.size() == 1); CService addr1_port = CService("250.1.1.1", 8334); - addrman.Add(CAddress(addr1_port, 0), source); + addrman.Add(CAddress(addr1_port, NODE_NONE), source); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret2 = addrman.Select(); BOOST_CHECK(addr_ret2.ToString() == "250.1.1.1:8333"); // Test 8: Add same IP but diff port to tried table, it doesn't get added. // Perhaps this is not ideal behavior but it is the current behavior. - addrman.Good(CAddress(addr1_port, 0)); + addrman.Good(CAddress(addr1_port, NODE_NONE)); BOOST_CHECK(addrman.size() == 1); bool newOnly = true; CAddrInfo addr_ret3 = addrman.Select(newOnly); @@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(addrman_select) // Test 9: Select from new with 1 addr in new. CService addr1 = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1, 0), source); + addrman.Add(CAddress(addr1, NODE_NONE), source); BOOST_CHECK(addrman.size() == 1); bool newOnly = true; @@ -144,7 +144,7 @@ BOOST_AUTO_TEST_CASE(addrman_select) BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); // Test 10: move addr to tried, select from new expected nothing returned. - addrman.Good(CAddress(addr1, 0)); + addrman.Good(CAddress(addr1, NODE_NONE)); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret2 = addrman.Select(newOnly); BOOST_CHECK(addr_ret2.ToString() == "[::]:0"); @@ -160,21 +160,21 @@ BOOST_AUTO_TEST_CASE(addrman_select) CService addr3 = CService("250.3.2.2", 9999); CService addr4 = CService("250.3.3.3", 9999); - addrman.Add(CAddress(addr2, 0), CService("250.3.1.1", 8333)); - addrman.Add(CAddress(addr3, 0), CService("250.3.1.1", 8333)); - addrman.Add(CAddress(addr4, 0), CService("250.4.1.1", 8333)); + addrman.Add(CAddress(addr2, NODE_NONE), CService("250.3.1.1", 8333)); + addrman.Add(CAddress(addr3, NODE_NONE), CService("250.3.1.1", 8333)); + addrman.Add(CAddress(addr4, NODE_NONE), CService("250.4.1.1", 8333)); // Add three addresses to tried table. CService addr5 = CService("250.4.4.4", 8333); CService addr6 = CService("250.4.5.5", 7777); CService addr7 = CService("250.4.6.6", 8333); - addrman.Add(CAddress(addr5, 0), CService("250.3.1.1", 8333)); - addrman.Good(CAddress(addr5, 0)); - addrman.Add(CAddress(addr6, 0), CService("250.3.1.1", 8333)); - addrman.Good(CAddress(addr6, 0)); - addrman.Add(CAddress(addr7, 0), CService("250.1.1.3", 8333)); - addrman.Good(CAddress(addr7, 0)); + addrman.Add(CAddress(addr5, NODE_NONE), CService("250.3.1.1", 8333)); + addrman.Good(CAddress(addr5, NODE_NONE)); + addrman.Add(CAddress(addr6, NODE_NONE), CService("250.3.1.1", 8333)); + addrman.Good(CAddress(addr6, NODE_NONE)); + addrman.Add(CAddress(addr7, NODE_NONE), CService("250.1.1.3", 8333)); + addrman.Good(CAddress(addr7, NODE_NONE)); // Test 11: 6 addrs + 1 addr from last test = 7. BOOST_CHECK(addrman.size() == 7); @@ -200,7 +200,7 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) for (int i = 1; i < 18; i++) { CService addr = CService("250.1.1." + boost::to_string(i)); - addrman.Add(CAddress(addr, 0), source); + addrman.Add(CAddress(addr, NODE_NONE), source); //Test 13: No collision in new table yet. BOOST_CHECK(addrman.size() == i); @@ -208,11 +208,11 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) //Test 14: new table collision! CService addr1 = CService("250.1.1.18"); - addrman.Add(CAddress(addr1, 0), source); + addrman.Add(CAddress(addr1, NODE_NONE), source); BOOST_CHECK(addrman.size() == 17); CService addr2 = CService("250.1.1.19"); - addrman.Add(CAddress(addr2, 0), source); + addrman.Add(CAddress(addr2, NODE_NONE), source); BOOST_CHECK(addrman.size() == 18); } @@ -229,8 +229,8 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) for (int i = 1; i < 80; i++) { CService addr = CService("250.1.1." + boost::to_string(i)); - addrman.Add(CAddress(addr, 0), source); - addrman.Good(CAddress(addr, 0)); + addrman.Add(CAddress(addr, NODE_NONE), source); + addrman.Good(CAddress(addr, NODE_NONE)); //Test 15: No collision in tried table yet. BOOST_TEST_MESSAGE(addrman.size()); @@ -239,11 +239,11 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) //Test 16: tried table collision! CService addr1 = CService("250.1.1.80"); - addrman.Add(CAddress(addr1, 0), source); + addrman.Add(CAddress(addr1, NODE_NONE), source); BOOST_CHECK(addrman.size() == 79); CService addr2 = CService("250.1.1.81"); - addrman.Add(CAddress(addr2, 0), source); + addrman.Add(CAddress(addr2, NODE_NONE), source); BOOST_CHECK(addrman.size() == 80); } @@ -256,9 +256,9 @@ BOOST_AUTO_TEST_CASE(addrman_find) BOOST_CHECK(addrman.size() == 0); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); - CAddress addr2 = CAddress(CService("250.1.2.1", 9999), 0); - CAddress addr3 = CAddress(CService("251.255.2.1", 8333), 0); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE); + CAddress addr2 = CAddress(CService("250.1.2.1", 9999), NODE_NONE); + CAddress addr3 = CAddress(CService("251.255.2.1", 8333), NODE_NONE); CNetAddr source1 = CNetAddr("250.1.2.1"); CNetAddr source2 = CNetAddr("250.1.2.2"); @@ -295,7 +295,7 @@ BOOST_AUTO_TEST_CASE(addrman_create) BOOST_CHECK(addrman.size() == 0); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE); CNetAddr source1 = CNetAddr("250.1.2.1"); int nId; @@ -318,7 +318,7 @@ BOOST_AUTO_TEST_CASE(addrman_delete) BOOST_CHECK(addrman.size() == 0); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE); CNetAddr source1 = CNetAddr("250.1.2.1"); int nId; @@ -345,15 +345,15 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) std::vector vAddr1 = addrman.GetAddr(); BOOST_CHECK(vAddr1.size() == 0); - CAddress addr1 = CAddress(CService("250.250.2.1", 8333), 0); + CAddress addr1 = CAddress(CService("250.250.2.1", 8333), NODE_NONE); addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false - CAddress addr2 = CAddress(CService("250.251.2.2", 9999), 0); + CAddress addr2 = CAddress(CService("250.251.2.2", 9999), NODE_NONE); addr2.nTime = GetAdjustedTime(); - CAddress addr3 = CAddress(CService("251.252.2.3", 8333), 0); + CAddress addr3 = CAddress(CService("251.252.2.3", 8333), NODE_NONE); addr3.nTime = GetAdjustedTime(); - CAddress addr4 = CAddress(CService("252.253.3.4", 8333), 0); + CAddress addr4 = CAddress(CService("252.253.3.4", 8333), NODE_NONE); addr4.nTime = GetAdjustedTime(); - CAddress addr5 = CAddress(CService("252.254.4.5", 8333), 0); + CAddress addr5 = CAddress(CService("252.254.4.5", 8333), NODE_NONE); addr5.nTime = GetAdjustedTime(); CNetAddr source1 = CNetAddr("250.1.2.1"); CNetAddr source2 = CNetAddr("250.2.3.3"); @@ -369,8 +369,8 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) BOOST_CHECK(addrman.GetAddr().size() == 1); // Test 24: Ensure GetAddr works with new and tried addresses. - addrman.Good(CAddress(addr1, 0)); - addrman.Good(CAddress(addr2, 0)); + addrman.Good(CAddress(addr1, NODE_NONE)); + addrman.Good(CAddress(addr2, NODE_NONE)); BOOST_CHECK(addrman.GetAddr().size() == 1); // Test 25: Ensure GetAddr still returns 23% when addrman has many addrs. @@ -379,7 +379,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) int octet2 = (i / 256) % 256; int octet3 = (i / (256 * 2)) % 256; std::string strAddr = boost::to_string(octet1) + "." + boost::to_string(octet2) + "." + boost::to_string(octet3) + ".23"; - CAddress addr = CAddress(CService(strAddr), 0); + CAddress addr = CAddress(CService(strAddr), NODE_NONE); // Ensure that for all addrs in addrman, isTerrible == false. addr.nTime = GetAdjustedTime(); @@ -404,8 +404,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CAddress addr1 = CAddress(CService("250.1.1.1", 8333), 0); - CAddress addr2 = CAddress(CService("250.1.1.1", 9999), 0); + CAddress addr1 = CAddress(CService("250.1.1.1", 8333), NODE_NONE); + CAddress addr2 = CAddress(CService("250.1.1.1", 9999), NODE_NONE); CNetAddr source1 = CNetAddr("250.1.1.1"); @@ -432,7 +432,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) std::set buckets; for (int i = 0; i < 255; i++) { CAddrInfo infoi = CAddrInfo( - CAddress(CService("250.1.1." + boost::to_string(i)), 0), + CAddress(CService("250.1.1." + boost::to_string(i)), NODE_NONE), CNetAddr("250.1.1." + boost::to_string(i))); int bucket = infoi.GetTriedBucket(nKey1); buckets.insert(bucket); @@ -444,7 +444,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) buckets.clear(); for (int j = 0; j < 255; j++) { CAddrInfo infoj = CAddrInfo( - CAddress(CService("250." + boost::to_string(j) + ".1.1"), 0), + CAddress(CService("250." + boost::to_string(j) + ".1.1"), NODE_NONE), CNetAddr("250." + boost::to_string(j) + ".1.1")); int bucket = infoj.GetTriedBucket(nKey1); buckets.insert(bucket); @@ -461,8 +461,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); - CAddress addr2 = CAddress(CService("250.1.2.1", 9999), 0); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE); + CAddress addr2 = CAddress(CService("250.1.2.1", 9999), NODE_NONE); CNetAddr source1 = CNetAddr("250.1.2.1"); @@ -485,7 +485,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) std::set buckets; for (int i = 0; i < 255; i++) { CAddrInfo infoi = CAddrInfo( - CAddress(CService("250.1.1." + boost::to_string(i)), 0), + CAddress(CService("250.1.1." + boost::to_string(i)), NODE_NONE), CNetAddr("250.1.1." + boost::to_string(i))); int bucket = infoi.GetNewBucket(nKey1); buckets.insert(bucket); @@ -498,7 +498,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) for (int j = 0; j < 4 * 255; j++) { CAddrInfo infoj = CAddrInfo(CAddress( CService( - boost::to_string(250 + (j / 255)) + "." + boost::to_string(j % 256) + ".1.1"), 0), + boost::to_string(250 + (j / 255)) + "." + boost::to_string(j % 256) + ".1.1"), NODE_NONE), CNetAddr("251.4.1.1")); int bucket = infoj.GetNewBucket(nKey1); buckets.insert(bucket); @@ -510,7 +510,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) buckets.clear(); for (int p = 0; p < 255; p++) { CAddrInfo infoj = CAddrInfo( - CAddress(CService("250.1.1.1"), 0), + CAddress(CService("250.1.1.1"), NODE_NONE), CNetAddr("250." + boost::to_string(p) + ".1.1")); int bucket = infoj.GetNewBucket(nKey1); buckets.insert(bucket); diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 6670efa1fd457..0de0c64f5e0ec 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -53,7 +53,7 @@ class CAddrManCorrupted : public CAddrManSerializationMock int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30); s << nUBuckets; - CAddress addr = CAddress(CService("252.1.1.1", 7777), 0); + CAddress addr = CAddress(CService("252.1.1.1", 7777), NODE_NONE); CAddrInfo info = CAddrInfo(addr, CNetAddr("252.2.2.2")); s << info; } @@ -81,9 +81,9 @@ BOOST_AUTO_TEST_CASE(caddrdb_read) CService addr3 = CService("250.7.3.3", 9999); // Add three addresses to new table. - addrmanUncorrupted.Add(CAddress(addr1, 0), CService("252.5.1.1", 8333)); - addrmanUncorrupted.Add(CAddress(addr2, 0), CService("252.5.1.1", 8333)); - addrmanUncorrupted.Add(CAddress(addr3, 0), CService("252.5.1.1", 8333)); + addrmanUncorrupted.Add(CAddress(addr1, NODE_NONE), CService("252.5.1.1", 8333)); + addrmanUncorrupted.Add(CAddress(addr2, NODE_NONE), CService("252.5.1.1", 8333)); + addrmanUncorrupted.Add(CAddress(addr3, NODE_NONE), CService("252.5.1.1", 8333)); // Test that the de-serialization does not throw an exception. CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted); From a48639fcb78c34bd2b4dde7ac5f8c4abd9acf162 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 13 Jun 2016 07:01:21 -0700 Subject: [PATCH 6/6] Introduce REQUIRED_SERVICES constant --- src/main.cpp | 2 +- src/net.cpp | 2 +- src/net.h | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 79083c2b738d1..0e0746ec8f6d5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5396,7 +5396,7 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR for (CAddress& addr : vAddr) { boost::this_thread::interruption_point(); - if (!(addr.nServices & NODE_NETWORK)) + if ((addr.nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES) continue; if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) diff --git a/src/net.cpp b/src/net.cpp index d76ff7df7c024..ba45b885654f0 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1439,7 +1439,7 @@ void ThreadOpenConnections() continue; // only connect to full nodes - if (!(addr.nServices & NODE_NETWORK)) + if ((addr.nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES) continue; // only consider very recently tried nodes after 30 failed attempts diff --git a/src/net.h b/src/net.h index 31b2d4c79a85e..24b5a5601f3fc 100644 --- a/src/net.h +++ b/src/net.h @@ -71,6 +71,8 @@ static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125; /** Maximum number of peers added to setOffsetDisconnectedPeers before triggering a warning */ #define MAX_TIMEOFFSET_DISCONNECTIONS 16 +static const ServiceFlags REQUIRED_SERVICES = NODE_NETWORK; + unsigned int ReceiveFloodSize(); unsigned int SendBufferSize();