From a15e906ecc9903f76334e8c8b6d731cf6417ac9f Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Wed, 28 Feb 2018 10:06:16 +0100 Subject: [PATCH 1/5] Remove testnet seeds from devnet --- src/chainparams.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 1060d0d13e55..10313c9e9ee3 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -366,8 +366,6 @@ class CTestNetParams : public CChainParams { // Testnet Dash BIP44 coin type is '1' (All coin's testnet default) nExtCoinType = 1; - vFixedSeeds = std::vector(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test)); - fMiningRequiresPeers = true; fDefaultConsistencyChecks = false; fRequireStandard = false; From 5cfad62ba2015937e82d2641f4d608f3ccbe60ed Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Thu, 24 May 2018 16:00:57 +0200 Subject: [PATCH 2/5] Lift multiple ports restriction on devnet when considering new nodes Allow to connect to multiple nodes behind the same IP --- src/addrman.cpp | 23 +++++++++++++++++++---- src/addrman.h | 10 +++++++--- src/chainparams.cpp | 2 +- src/net.cpp | 21 ++++++++++++++++----- src/test/addrman_tests.cpp | 2 +- src/test/net_tests.cpp | 8 ++++---- 6 files changed, 48 insertions(+), 18 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index e23a33262260..ffc8a6955f3f 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -65,9 +65,14 @@ double CAddrInfo::GetChance(int64_t nNow) const return fChance; } -CAddrInfo* CAddrMan::Find(const CNetAddr& addr, int* pnId) +CAddrInfo* CAddrMan::Find(const CService& addr, int* pnId) { - std::map::iterator it = mapAddr.find(addr); + CService addr2 = addr; + if (!discriminatePorts) { + addr2.SetPort(0); + } + + std::map::iterator it = mapAddr.find(addr2); if (it == mapAddr.end()) return NULL; if (pnId) @@ -80,9 +85,14 @@ CAddrInfo* CAddrMan::Find(const CNetAddr& addr, int* pnId) CAddrInfo* CAddrMan::Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId) { + CService addr2 = addr; + if (!discriminatePorts) { + addr2.SetPort(0); + } + int nId = nIdCount++; mapInfo[nId] = CAddrInfo(addr, addrSource); - mapAddr[addr] = nId; + mapAddr[addr2] = nId; mapInfo[nId].nRandomPos = vRandom.size(); vRandom.push_back(nId); if (pnId) @@ -117,9 +127,14 @@ void CAddrMan::Delete(int nId) assert(!info.fInTried); assert(info.nRefCount == 0); + CService addr = info; + if (!discriminatePorts) { + addr.SetPort(0); + } + SwapRandom(info.nRandomPos, vRandom.size() - 1); vRandom.pop_back(); - mapAddr.erase(info); + mapAddr.erase(addr); mapInfo.erase(nId); nNew--; } diff --git a/src/addrman.h b/src/addrman.h index 76e7b210f7c3..cdb4a65a65ce 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -187,7 +187,7 @@ class CAddrMan std::map mapInfo; //! find an nId based on its network address - std::map mapAddr; + std::map mapAddr; //! randomly-ordered vector of all nIds std::vector vRandom; @@ -207,6 +207,9 @@ class CAddrMan //! last time Good was called (memory only) int64_t nLastGood; + // discriminate entries based on port. Should be false on mainnet/testnet and can be true on devnet/regtest + bool discriminatePorts; + protected: //! secret key to randomize bucket select with uint256 nKey; @@ -215,7 +218,7 @@ class CAddrMan FastRandomContext insecure_rand; //! Find an entry. - CAddrInfo* Find(const CNetAddr& addr, int *pnId = NULL); + CAddrInfo* Find(const CService& addr, int *pnId = NULL); //! find an entry, creating it if necessary. //! nTime and nServices of the found node are updated, if necessary. @@ -469,7 +472,8 @@ class CAddrMan nLastGood = 1; //Initially at 1 so that "never" is strictly worse. } - CAddrMan() + CAddrMan(bool _discriminatePorts = false) : + discriminatePorts(_discriminatePorts) { Clear(); } diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 10313c9e9ee3..e01c9c8c09d2 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -501,7 +501,7 @@ class CDevNetParams : public CChainParams { fRequireStandard = false; fMineBlocksOnDemand = false; fAllowMultipleAddressesFromGroup = true; - fAllowMultiplePorts = false; + fAllowMultiplePorts = true; nPoolMaxTransactions = 3; nFulfilledRequestExpireTime = 5*60; // fulfilled requests expire in 5 minutes diff --git a/src/net.cpp b/src/net.cpp index b1087939b17a..1cb6e1cd020d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -348,8 +348,9 @@ bool CConnman::CheckIncomingNonce(uint64_t nonce) CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure) { if (pszDest == NULL) { - if (IsLocal(addrConnect)) + if (IsLocal(addrConnect) && (!Params().AllowMultiplePorts() || addrConnect.GetPort() == GetListenPort())) { return NULL; + } // Look for an existing connection CNode* pnode = FindNode((CService)addrConnect); @@ -1786,7 +1787,11 @@ void CConnman::ThreadOpenConnections() CAddrInfo addr = addrman.Select(fFeeler); // if we selected an invalid address, restart - if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr)) + if (!addr.IsValid() || setConnected.count(addr.GetGroup())) + break; + + // if we selected a local address, restart (local addresses are allowed in regtest and devnet) + if (IsLocal(addr) && (!Params().AllowMultiplePorts() || addr.GetPort() == GetListenPort())) break; // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman, @@ -1990,10 +1995,14 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai return false; } if (!pszDest) { - if (IsLocal(addrConnect) || - FindNode((CNetAddr)addrConnect) || IsBanned(addrConnect) || + if (IsBanned(addrConnect) || FindNode(addrConnect.ToStringIPPort())) return false; + if (IsLocal(addrConnect) && (!Params().AllowMultiplePorts() || addrConnect.GetPort() == GetListenPort())) + return false; + if ((!Params().AllowMultiplePorts() && FindNode((CNetAddr)addrConnect)) || + (Params().AllowMultiplePorts() && FindNode((CService)addrConnect))) + return false; } else if (FindNode(std::string(pszDest))) return false; @@ -2238,7 +2247,9 @@ void CConnman::SetNetworkActive(bool active) uiInterface.NotifyNetworkActiveChanged(fNetworkActive); } -CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In) : nSeed0(nSeed0In), nSeed1(nSeed1In) +CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In) : + nSeed0(nSeed0In), nSeed1(nSeed1In), + addrman(Params().AllowMultiplePorts()) { fNetworkActive = true; setBannedIsDirty = false; diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index 535faa2b161a..7a35ff6da127 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -33,7 +33,7 @@ class CAddrManTest : public CAddrMan return (unsigned int)(state % nMax); } - CAddrInfo* Find(const CNetAddr& addr, int* pnId = NULL) + CAddrInfo* Find(const CService& addr, int* pnId = NULL) { return CAddrMan::Find(addr, pnId); } diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 7a319570440d..fafab8907431 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -92,7 +92,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read) // Test that the de-serialization does not throw an exception. CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted); bool exceptionThrown = false; - CAddrMan addrman1; + CAddrMan addrman1(false); BOOST_CHECK(addrman1.size() == 0); try { @@ -109,7 +109,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read) // Test that CAddrDB::Read creates an addrman with the correct number of addrs. CDataStream ssPeers2 = AddrmanToStream(addrmanUncorrupted); - CAddrMan addrman2; + CAddrMan addrman2(false); CAddrDB adb; BOOST_CHECK(addrman2.size() == 0); adb.Read(addrman2, ssPeers2); @@ -125,7 +125,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted) // Test that the de-serialization of corrupted addrman throws an exception. CDataStream ssPeers1 = AddrmanToStream(addrmanCorrupted); bool exceptionThrown = false; - CAddrMan addrman1; + CAddrMan addrman1(false); BOOST_CHECK(addrman1.size() == 0); try { unsigned char pchMsgTmp[4]; @@ -141,7 +141,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted) // Test that CAddrDB::Read leaves addrman in a clean state if de-serialization fails. CDataStream ssPeers2 = AddrmanToStream(addrmanCorrupted); - CAddrMan addrman2; + CAddrMan addrman2(false); CAddrDB adb; BOOST_CHECK(addrman2.size() == 0); adb.Read(addrman2, ssPeers2); From 2d1ecdb84ed203a41747e32bc035ff6e3ae776bf Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Tue, 6 Mar 2018 12:57:26 +0100 Subject: [PATCH 3/5] Don't skip addresses with non-default port if it matches -port If the user specified -port, he very likely intends to connect to nodes with the same port. --- src/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index 1cb6e1cd020d..d0786d6d5515 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1823,7 +1823,7 @@ void CConnman::ThreadOpenConnections() } // do not allow non-default ports, unless after 50 invalid addresses selected already - if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50) + if (addr.GetPort() != Params().GetDefaultPort() && addr.GetPort() != GetListenPort() && nTries < 50) continue; addrConnect = addr; From 4b072c94db4b9ef9dd53a372fd179a5ca5e4fabb Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 6 Jul 2018 11:30:09 +0200 Subject: [PATCH 4/5] Don't pass false to CAddrMan constructor as it is already the default --- src/test/net_tests.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index fafab8907431..7a319570440d 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -92,7 +92,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read) // Test that the de-serialization does not throw an exception. CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted); bool exceptionThrown = false; - CAddrMan addrman1(false); + CAddrMan addrman1; BOOST_CHECK(addrman1.size() == 0); try { @@ -109,7 +109,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read) // Test that CAddrDB::Read creates an addrman with the correct number of addrs. CDataStream ssPeers2 = AddrmanToStream(addrmanUncorrupted); - CAddrMan addrman2(false); + CAddrMan addrman2; CAddrDB adb; BOOST_CHECK(addrman2.size() == 0); adb.Read(addrman2, ssPeers2); @@ -125,7 +125,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted) // Test that the de-serialization of corrupted addrman throws an exception. CDataStream ssPeers1 = AddrmanToStream(addrmanCorrupted); bool exceptionThrown = false; - CAddrMan addrman1(false); + CAddrMan addrman1; BOOST_CHECK(addrman1.size() == 0); try { unsigned char pchMsgTmp[4]; @@ -141,7 +141,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted) // Test that CAddrDB::Read leaves addrman in a clean state if de-serialization fails. CDataStream ssPeers2 = AddrmanToStream(addrmanCorrupted); - CAddrMan addrman2(false); + CAddrMan addrman2; CAddrDB adb; BOOST_CHECK(addrman2.size() == 0); adb.Read(addrman2, ssPeers2); From 795f1ee90ef956547ddb4151aece492fb8a2f81d Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 6 Jul 2018 11:40:14 +0200 Subject: [PATCH 5/5] Make if statements easier to read --- src/net.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index d0786d6d5515..f0bd58abbe5a 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -348,7 +348,8 @@ bool CConnman::CheckIncomingNonce(uint64_t nonce) CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure) { if (pszDest == NULL) { - if (IsLocal(addrConnect) && (!Params().AllowMultiplePorts() || addrConnect.GetPort() == GetListenPort())) { + bool fAllowLocal = Params().AllowMultiplePorts() && addrConnect.GetPort() != GetListenPort(); + if (!fAllowLocal && IsLocal(addrConnect)) { return NULL; } @@ -1791,7 +1792,8 @@ void CConnman::ThreadOpenConnections() break; // if we selected a local address, restart (local addresses are allowed in regtest and devnet) - if (IsLocal(addr) && (!Params().AllowMultiplePorts() || addr.GetPort() == GetListenPort())) + bool fAllowLocal = Params().AllowMultiplePorts() && addrConnect.GetPort() != GetListenPort(); + if (!fAllowLocal && IsLocal(addrConnect)) break; // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman, @@ -1995,13 +1997,16 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai return false; } if (!pszDest) { - if (IsBanned(addrConnect) || - FindNode(addrConnect.ToStringIPPort())) + // banned or exact match? + if (IsBanned(addrConnect) || FindNode(addrConnect.ToStringIPPort())) return false; - if (IsLocal(addrConnect) && (!Params().AllowMultiplePorts() || addrConnect.GetPort() == GetListenPort())) + // local and not a connection to itself? + bool fAllowLocal = Params().AllowMultiplePorts() && addrConnect.GetPort() != GetListenPort(); + if (!fAllowLocal && IsLocal(addrConnect)) return false; + // if multiple ports for same IP are allowed, search for IP:PORT match, otherwise search for IP-only match if ((!Params().AllowMultiplePorts() && FindNode((CNetAddr)addrConnect)) || - (Params().AllowMultiplePorts() && FindNode((CService)addrConnect))) + (Params().AllowMultiplePorts() && FindNode((CService)addrConnect))) return false; } else if (FindNode(std::string(pszDest))) return false;