Merge #8688: Move static global randomizer seeds into CConnman
d9ff591
Move static global randomizer seeds into CConnman (Pieter Wuille)
This commit is contained in:
commit
047ded0b12
7 changed files with 34 additions and 24 deletions
|
@ -1116,7 +1116,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
// ********************************************************* Step 6: network initialization
|
// ********************************************************* Step 6: network initialization
|
||||||
|
|
||||||
assert(!g_connman);
|
assert(!g_connman);
|
||||||
g_connman = std::unique_ptr<CConnman>(new CConnman());
|
g_connman = std::unique_ptr<CConnman>(new CConnman(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max())));
|
||||||
CConnman& connman = *g_connman;
|
CConnman& connman = *g_connman;
|
||||||
|
|
||||||
RegisterNodeSignals(GetNodeSignals());
|
RegisterNodeSignals(GetNodeSignals());
|
||||||
|
|
|
@ -113,6 +113,8 @@ CScript COINBASE_FLAGS;
|
||||||
|
|
||||||
const string strMessageMagic = "Bitcoin Signed Message:\n";
|
const string strMessageMagic = "Bitcoin Signed Message:\n";
|
||||||
|
|
||||||
|
static const uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL; // SHA256("main address relay")[0:8]
|
||||||
|
|
||||||
// Internal stuff
|
// Internal stuff
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -4739,11 +4741,9 @@ static void RelayAddress(const CAddress& addr, bool fReachable, CConnman& connma
|
||||||
// Relay to a limited number of other nodes
|
// Relay to a limited number of other nodes
|
||||||
// Use deterministic randomness to send to the same nodes for 24 hours
|
// Use deterministic randomness to send to the same nodes for 24 hours
|
||||||
// at a time so the addrKnowns of the chosen nodes prevent repeats
|
// at a time so the addrKnowns of the chosen nodes prevent repeats
|
||||||
static const uint64_t salt0 = GetRand(std::numeric_limits<uint64_t>::max());
|
|
||||||
static const uint64_t salt1 = GetRand(std::numeric_limits<uint64_t>::max());
|
|
||||||
uint64_t hashAddr = addr.GetHash();
|
uint64_t hashAddr = addr.GetHash();
|
||||||
std::multimap<uint64_t, CNode*> mapMix;
|
std::multimap<uint64_t, CNode*> mapMix;
|
||||||
const CSipHasher hasher = CSipHasher(salt0, salt1).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24*60*60));
|
const CSipHasher hasher = connman.GetDeterministicRandomizer(RANDOMIZER_ID_ADDRESS_RELAY).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24*60*60));
|
||||||
|
|
||||||
auto sortfunc = [&mapMix, &hasher](CNode* pnode) {
|
auto sortfunc = [&mapMix, &hasher](CNode* pnode) {
|
||||||
if (pnode->nVersion >= CADDR_TIME_VERSION) {
|
if (pnode->nVersion >= CADDR_TIME_VERSION) {
|
||||||
|
|
23
src/net.cpp
23
src/net.cpp
|
@ -63,6 +63,7 @@
|
||||||
|
|
||||||
const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
|
const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
|
||||||
|
|
||||||
|
static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8]
|
||||||
//
|
//
|
||||||
// Global state variables
|
// Global state variables
|
||||||
//
|
//
|
||||||
|
@ -387,7 +388,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
||||||
addrman.Attempt(addrConnect, fCountFailure);
|
addrman.Attempt(addrConnect, fCountFailure);
|
||||||
|
|
||||||
// Add node
|
// Add node
|
||||||
CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addrConnect, pszDest ? pszDest : "", false);
|
CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), pszDest ? pszDest : "", false);
|
||||||
GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
|
GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
|
||||||
pnode->AddRef();
|
pnode->AddRef();
|
||||||
|
|
||||||
|
@ -1022,7 +1023,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addr, "", true);
|
CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), "", true);
|
||||||
GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
|
GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
|
||||||
pnode->AddRef();
|
pnode->AddRef();
|
||||||
pnode->fWhitelisted = whitelisted;
|
pnode->fWhitelisted = whitelisted;
|
||||||
|
@ -2023,7 +2024,7 @@ void Discover(boost::thread_group& threadGroup)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CConnman::CConnman()
|
CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In) : nSeed0(nSeed0In), nSeed1(nSeed1In)
|
||||||
{
|
{
|
||||||
setBannedIsDirty = false;
|
setBannedIsDirty = false;
|
||||||
fAddressesInitialized = false;
|
fAddressesInitialized = false;
|
||||||
|
@ -2109,7 +2110,7 @@ bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, st
|
||||||
if (pnodeLocalHost == NULL) {
|
if (pnodeLocalHost == NULL) {
|
||||||
CNetAddr local;
|
CNetAddr local;
|
||||||
LookupHost("127.0.0.1", local, false);
|
LookupHost("127.0.0.1", local, false);
|
||||||
pnodeLocalHost = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices));
|
pnodeLocalHost = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices), 0);
|
||||||
GetNodeSignals().InitializeNode(pnodeLocalHost->GetId(), pnodeLocalHost);
|
GetNodeSignals().InitializeNode(pnodeLocalHost->GetId(), pnodeLocalHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2499,10 +2500,10 @@ void CNode::Fuzz(int nChance)
|
||||||
unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
|
unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
|
||||||
unsigned int CConnman::GetSendBufferSize() const{ return nSendBufferMaxSize; }
|
unsigned int CConnman::GetSendBufferSize() const{ return nSendBufferMaxSize; }
|
||||||
|
|
||||||
CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) :
|
CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, const std::string& addrNameIn, bool fInboundIn) :
|
||||||
ssSend(SER_NETWORK, INIT_PROTO_VERSION),
|
ssSend(SER_NETWORK, INIT_PROTO_VERSION),
|
||||||
addr(addrIn),
|
addr(addrIn),
|
||||||
nKeyedNetGroup(CalculateKeyedNetGroup(addrIn)),
|
nKeyedNetGroup(nKeyedNetGroupIn),
|
||||||
addrKnown(5000, 0.001),
|
addrKnown(5000, 0.001),
|
||||||
filterInventoryKnown(50000, 0.000001)
|
filterInventoryKnown(50000, 0.000001)
|
||||||
{
|
{
|
||||||
|
@ -2695,12 +2696,14 @@ int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
|
||||||
return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
|
return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ uint64_t CNode::CalculateKeyedNetGroup(const CAddress& ad)
|
CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id)
|
||||||
{
|
{
|
||||||
static const uint64_t k0 = GetRand(std::numeric_limits<uint64_t>::max());
|
return CSipHasher(nSeed0, nSeed1).Write(id);
|
||||||
static const uint64_t k1 = GetRand(std::numeric_limits<uint64_t>::max());
|
}
|
||||||
|
|
||||||
|
uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& ad)
|
||||||
|
{
|
||||||
std::vector<unsigned char> vchNetGroup(ad.GetGroup());
|
std::vector<unsigned char> vchNetGroup(ad.GetGroup());
|
||||||
|
|
||||||
return CSipHasher(k0, k1).Write(&vchNetGroup[0], vchNetGroup.size()).Finalize();
|
return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(&vchNetGroup[0], vchNetGroup.size()).Finalize();
|
||||||
}
|
}
|
||||||
|
|
13
src/net.h
13
src/net.h
|
@ -11,6 +11,7 @@
|
||||||
#include "amount.h"
|
#include "amount.h"
|
||||||
#include "bloom.h"
|
#include "bloom.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
#include "hash.h"
|
||||||
#include "limitedmap.h"
|
#include "limitedmap.h"
|
||||||
#include "netaddress.h"
|
#include "netaddress.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
@ -125,7 +126,7 @@ public:
|
||||||
uint64_t nMaxOutboundTimeframe = 0;
|
uint64_t nMaxOutboundTimeframe = 0;
|
||||||
uint64_t nMaxOutboundLimit = 0;
|
uint64_t nMaxOutboundLimit = 0;
|
||||||
};
|
};
|
||||||
CConnman();
|
CConnman(uint64_t seed0, uint64_t seed1);
|
||||||
~CConnman();
|
~CConnman();
|
||||||
bool Start(boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError, Options options);
|
bool Start(boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError, Options options);
|
||||||
void Stop();
|
void Stop();
|
||||||
|
@ -298,6 +299,8 @@ public:
|
||||||
void SetBestHeight(int height);
|
void SetBestHeight(int height);
|
||||||
int GetBestHeight() const;
|
int GetBestHeight() const;
|
||||||
|
|
||||||
|
/** Get a unique deterministic randomizer. */
|
||||||
|
CSipHasher GetDeterministicRandomizer(uint64_t id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ListenSocket {
|
struct ListenSocket {
|
||||||
|
@ -315,6 +318,8 @@ private:
|
||||||
void ThreadSocketHandler();
|
void ThreadSocketHandler();
|
||||||
void ThreadDNSAddressSeed();
|
void ThreadDNSAddressSeed();
|
||||||
|
|
||||||
|
uint64_t CalculateKeyedNetGroup(const CAddress& ad);
|
||||||
|
|
||||||
CNode* FindNode(const CNetAddr& ip);
|
CNode* FindNode(const CNetAddr& ip);
|
||||||
CNode* FindNode(const CSubNet& subNet);
|
CNode* FindNode(const CSubNet& subNet);
|
||||||
CNode* FindNode(const std::string& addrName);
|
CNode* FindNode(const std::string& addrName);
|
||||||
|
@ -392,6 +397,9 @@ private:
|
||||||
int nMaxFeeler;
|
int nMaxFeeler;
|
||||||
std::atomic<int> nBestHeight;
|
std::atomic<int> nBestHeight;
|
||||||
CClientUIInterface* clientInterface;
|
CClientUIInterface* clientInterface;
|
||||||
|
|
||||||
|
/** SipHasher seeds for deterministic randomness */
|
||||||
|
const uint64_t nSeed0, nSeed1;
|
||||||
};
|
};
|
||||||
extern std::unique_ptr<CConnman> g_connman;
|
extern std::unique_ptr<CConnman> g_connman;
|
||||||
void Discover(boost::thread_group& threadGroup);
|
void Discover(boost::thread_group& threadGroup);
|
||||||
|
@ -660,14 +668,13 @@ public:
|
||||||
CAmount lastSentFeeFilter;
|
CAmount lastSentFeeFilter;
|
||||||
int64_t nextSendTimeFeeFilter;
|
int64_t nextSendTimeFeeFilter;
|
||||||
|
|
||||||
CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, const std::string &addrNameIn = "", bool fInboundIn = false);
|
CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, const std::string &addrNameIn = "", bool fInboundIn = false);
|
||||||
~CNode();
|
~CNode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CNode(const CNode&);
|
CNode(const CNode&);
|
||||||
void operator=(const CNode&);
|
void operator=(const CNode&);
|
||||||
|
|
||||||
static uint64_t CalculateKeyedNetGroup(const CAddress& ad);
|
|
||||||
|
|
||||||
uint64_t nLocalHostNonce;
|
uint64_t nLocalHostNonce;
|
||||||
ServiceFlags nLocalServices;
|
ServiceFlags nLocalServices;
|
||||||
|
|
|
@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
|
||||||
{
|
{
|
||||||
connman->ClearBanned();
|
connman->ClearBanned();
|
||||||
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
|
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
|
||||||
CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, "", true);
|
CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, "", true);
|
||||||
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
|
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
|
||||||
dummyNode1.nVersion = 1;
|
dummyNode1.nVersion = 1;
|
||||||
Misbehaving(dummyNode1.GetId(), 100); // Should get banned
|
Misbehaving(dummyNode1.GetId(), 100); // Should get banned
|
||||||
|
@ -57,7 +57,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
|
||||||
BOOST_CHECK(!connman->IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
|
BOOST_CHECK(!connman->IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
|
||||||
|
|
||||||
CAddress addr2(ip(0xa0b0c002), NODE_NONE);
|
CAddress addr2(ip(0xa0b0c002), NODE_NONE);
|
||||||
CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, "", true);
|
CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, 1, "", true);
|
||||||
GetNodeSignals().InitializeNode(dummyNode2.GetId(), &dummyNode2);
|
GetNodeSignals().InitializeNode(dummyNode2.GetId(), &dummyNode2);
|
||||||
dummyNode2.nVersion = 1;
|
dummyNode2.nVersion = 1;
|
||||||
Misbehaving(dummyNode2.GetId(), 50);
|
Misbehaving(dummyNode2.GetId(), 50);
|
||||||
|
@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
|
||||||
connman->ClearBanned();
|
connman->ClearBanned();
|
||||||
mapArgs["-banscore"] = "111"; // because 11 is my favorite number
|
mapArgs["-banscore"] = "111"; // because 11 is my favorite number
|
||||||
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
|
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
|
||||||
CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, "", true);
|
CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 3, "", true);
|
||||||
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
|
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
|
||||||
dummyNode1.nVersion = 1;
|
dummyNode1.nVersion = 1;
|
||||||
Misbehaving(dummyNode1.GetId(), 100);
|
Misbehaving(dummyNode1.GetId(), 100);
|
||||||
|
@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
|
||||||
SetMockTime(nStartTime); // Overrides future calls to GetTime()
|
SetMockTime(nStartTime); // Overrides future calls to GetTime()
|
||||||
|
|
||||||
CAddress addr(ip(0xa0b0c001), NODE_NONE);
|
CAddress addr(ip(0xa0b0c001), NODE_NONE);
|
||||||
CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, "", true);
|
CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, 4, "", true);
|
||||||
GetNodeSignals().InitializeNode(dummyNode.GetId(), &dummyNode);
|
GetNodeSignals().InitializeNode(dummyNode.GetId(), &dummyNode);
|
||||||
dummyNode.nVersion = 1;
|
dummyNode.nVersion = 1;
|
||||||
|
|
||||||
|
|
|
@ -164,12 +164,12 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
|
||||||
bool fInboundIn = false;
|
bool fInboundIn = false;
|
||||||
|
|
||||||
// Test that fFeeler is false by default.
|
// Test that fFeeler is false by default.
|
||||||
CNode* pnode1 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, pszDest, fInboundIn);
|
CNode* pnode1 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, pszDest, fInboundIn);
|
||||||
BOOST_CHECK(pnode1->fInbound == false);
|
BOOST_CHECK(pnode1->fInbound == false);
|
||||||
BOOST_CHECK(pnode1->fFeeler == false);
|
BOOST_CHECK(pnode1->fFeeler == false);
|
||||||
|
|
||||||
fInboundIn = true;
|
fInboundIn = true;
|
||||||
CNode* pnode2 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, pszDest, fInboundIn);
|
CNode* pnode2 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, pszDest, fInboundIn);
|
||||||
BOOST_CHECK(pnode2->fInbound == true);
|
BOOST_CHECK(pnode2->fInbound == true);
|
||||||
BOOST_CHECK(pnode2->fFeeler == false);
|
BOOST_CHECK(pnode2->fFeeler == false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
|
||||||
nScriptCheckThreads = 3;
|
nScriptCheckThreads = 3;
|
||||||
for (int i=0; i < nScriptCheckThreads-1; i++)
|
for (int i=0; i < nScriptCheckThreads-1; i++)
|
||||||
threadGroup.create_thread(&ThreadScriptCheck);
|
threadGroup.create_thread(&ThreadScriptCheck);
|
||||||
g_connman = std::unique_ptr<CConnman>(new CConnman());
|
g_connman = std::unique_ptr<CConnman>(new CConnman(0x1337, 0x1337)); // Deterministic randomness for tests.
|
||||||
connman = g_connman.get();
|
connman = g_connman.get();
|
||||||
RegisterNodeSignals(GetNodeSignals());
|
RegisterNodeSignals(GetNodeSignals());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue