|
|
@ -839,7 +839,7 @@ struct NodeEvictionCandidate |
|
|
|
int64_t nTimeConnected; |
|
|
|
int64_t nTimeConnected; |
|
|
|
int64_t nMinPingUsecTime; |
|
|
|
int64_t nMinPingUsecTime; |
|
|
|
CAddress addr; |
|
|
|
CAddress addr; |
|
|
|
std::vector<unsigned char> vchKeyedNetGroup; |
|
|
|
uint64_t nKeyedNetGroup; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) |
|
|
|
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) |
|
|
@ -853,7 +853,7 @@ static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, cons |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) { |
|
|
|
static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) { |
|
|
|
return a.vchKeyedNetGroup < b.vchKeyedNetGroup; |
|
|
|
return a.nKeyedNetGroup < b.nKeyedNetGroup; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** Try to find a connection to evict when the node is full.
|
|
|
|
/** Try to find a connection to evict when the node is full.
|
|
|
@ -876,7 +876,7 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
if (node->fDisconnect) |
|
|
|
if (node->fDisconnect) |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr, node->vchKeyedNetGroup}; |
|
|
|
NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr, node->nKeyedNetGroup}; |
|
|
|
vEvictionCandidates.push_back(candidate); |
|
|
|
vEvictionCandidates.push_back(candidate); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -908,24 +908,24 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { |
|
|
|
|
|
|
|
|
|
|
|
// Identify the network group with the most connections and youngest member.
|
|
|
|
// Identify the network group with the most connections and youngest member.
|
|
|
|
// (vEvictionCandidates is already sorted by reverse connect time)
|
|
|
|
// (vEvictionCandidates is already sorted by reverse connect time)
|
|
|
|
std::vector<unsigned char> naMostConnections; |
|
|
|
uint64_t naMostConnections; |
|
|
|
unsigned int nMostConnections = 0; |
|
|
|
unsigned int nMostConnections = 0; |
|
|
|
int64_t nMostConnectionsTime = 0; |
|
|
|
int64_t nMostConnectionsTime = 0; |
|
|
|
std::map<std::vector<unsigned char>, std::vector<NodeEvictionCandidate> > mapAddrCounts; |
|
|
|
std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapAddrCounts; |
|
|
|
BOOST_FOREACH(const NodeEvictionCandidate &node, vEvictionCandidates) { |
|
|
|
BOOST_FOREACH(const NodeEvictionCandidate &node, vEvictionCandidates) { |
|
|
|
mapAddrCounts[node.addr.GetGroup()].push_back(node); |
|
|
|
mapAddrCounts[node.nKeyedNetGroup].push_back(node); |
|
|
|
int64_t grouptime = mapAddrCounts[node.addr.GetGroup()][0].nTimeConnected; |
|
|
|
int64_t grouptime = mapAddrCounts[node.nKeyedNetGroup][0].nTimeConnected; |
|
|
|
size_t groupsize = mapAddrCounts[node.addr.GetGroup()].size(); |
|
|
|
size_t groupsize = mapAddrCounts[node.nKeyedNetGroup].size(); |
|
|
|
|
|
|
|
|
|
|
|
if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) { |
|
|
|
if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) { |
|
|
|
nMostConnections = groupsize; |
|
|
|
nMostConnections = groupsize; |
|
|
|
nMostConnectionsTime = grouptime; |
|
|
|
nMostConnectionsTime = grouptime; |
|
|
|
naMostConnections = node.addr.GetGroup(); |
|
|
|
naMostConnections = node.nKeyedNetGroup; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Reduce to the network group with the most connections
|
|
|
|
// Reduce to the network group with the most connections
|
|
|
|
vEvictionCandidates = mapAddrCounts[naMostConnections]; |
|
|
|
vEvictionCandidates = std::move(mapAddrCounts[naMostConnections]); |
|
|
|
|
|
|
|
|
|
|
|
// Do not disconnect peers if there is only one unprotected connection from their network group.
|
|
|
|
// Do not disconnect peers if there is only one unprotected connection from their network group.
|
|
|
|
// This step excessively favors netgroup diversity, and should be removed once more protective criteria are established.
|
|
|
|
// This step excessively favors netgroup diversity, and should be removed once more protective criteria are established.
|
|
|
@ -2318,6 +2318,8 @@ unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", DEFAULT_MAX |
|
|
|
|
|
|
|
|
|
|
|
CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) : |
|
|
|
CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) : |
|
|
|
ssSend(SER_NETWORK, INIT_PROTO_VERSION), |
|
|
|
ssSend(SER_NETWORK, INIT_PROTO_VERSION), |
|
|
|
|
|
|
|
addr(addrIn), |
|
|
|
|
|
|
|
nKeyedNetGroup(CalculateKeyedNetGroup(addrIn)), |
|
|
|
addrKnown(5000, 0.001), |
|
|
|
addrKnown(5000, 0.001), |
|
|
|
filterInventoryKnown(50000, 0.000001) |
|
|
|
filterInventoryKnown(50000, 0.000001) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -2330,7 +2332,6 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa |
|
|
|
nRecvBytes = 0; |
|
|
|
nRecvBytes = 0; |
|
|
|
nTimeConnected = GetTime(); |
|
|
|
nTimeConnected = GetTime(); |
|
|
|
nTimeOffset = 0; |
|
|
|
nTimeOffset = 0; |
|
|
|
addr = addrIn; |
|
|
|
|
|
|
|
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn; |
|
|
|
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn; |
|
|
|
nVersion = 0; |
|
|
|
nVersion = 0; |
|
|
|
strSubVer = ""; |
|
|
|
strSubVer = ""; |
|
|
@ -2365,8 +2366,6 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa |
|
|
|
lastSentFeeFilter = 0; |
|
|
|
lastSentFeeFilter = 0; |
|
|
|
nextSendTimeFeeFilter = 0; |
|
|
|
nextSendTimeFeeFilter = 0; |
|
|
|
|
|
|
|
|
|
|
|
CalculateKeyedNetGroup(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes()) |
|
|
|
BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes()) |
|
|
|
mapRecvBytesPerMsgCmd[msg] = 0; |
|
|
|
mapRecvBytesPerMsgCmd[msg] = 0; |
|
|
|
mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; |
|
|
|
mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; |
|
|
@ -2599,3 +2598,17 @@ bool CBanDB::Read(banmap_t& banSet) |
|
|
|
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) { |
|
|
|
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) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
static uint64_t k0 = 0, k1 = 0; |
|
|
|
|
|
|
|
while (k0 == 0 && k1 == 0) { |
|
|
|
|
|
|
|
// Make sure this only runs on the first invocation.
|
|
|
|
|
|
|
|
GetRandBytes((unsigned char*)&k0, sizeof(k0)); |
|
|
|
|
|
|
|
GetRandBytes((unsigned char*)&k1, sizeof(k1)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<unsigned char> vchNetGroup(ad.GetGroup()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return CSipHasher(k0, k1).Write(&vchNetGroup[0], vchNetGroup.size()).Finalize(); |
|
|
|
|
|
|
|
} |
|
|
|