|
|
@ -4804,26 +4804,35 @@ static void RelayTransaction(const CTransaction& tx, CConnman& connman) |
|
|
|
|
|
|
|
|
|
|
|
static void RelayAddress(const CAddress& addr, bool fReachable, CConnman& connman) |
|
|
|
static void RelayAddress(const CAddress& addr, bool fReachable, CConnman& connman) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
|
|
|
|
unsigned int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
|
|
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
uint64_t hashAddr = addr.GetHash(); |
|
|
|
uint64_t hashAddr = addr.GetHash(); |
|
|
|
std::multimap<uint64_t, CNode*> mapMix; |
|
|
|
|
|
|
|
const CSipHasher hasher = connman.GetDeterministicRandomizer(RANDOMIZER_ID_ADDRESS_RELAY).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)); |
|
|
|
FastRandomContext insecure_rand; |
|
|
|
FastRandomContext insecure_rand; |
|
|
|
|
|
|
|
|
|
|
|
auto sortfunc = [&mapMix, &hasher](CNode* pnode) { |
|
|
|
std::array<std::pair<uint64_t, CNode*>,2> best{{{0, nullptr}, {0, nullptr}}}; |
|
|
|
|
|
|
|
assert(nRelayNodes <= best.size()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto sortfunc = [&best, &hasher, nRelayNodes](CNode* pnode) { |
|
|
|
if (pnode->nVersion >= CADDR_TIME_VERSION) { |
|
|
|
if (pnode->nVersion >= CADDR_TIME_VERSION) { |
|
|
|
uint64_t hashKey = CSipHasher(hasher).Write(pnode->id).Finalize(); |
|
|
|
uint64_t hashKey = CSipHasher(hasher).Write(pnode->id).Finalize(); |
|
|
|
mapMix.emplace(hashKey, pnode); |
|
|
|
for (unsigned int i = 0; i < nRelayNodes; i++) { |
|
|
|
|
|
|
|
if (hashKey > best[i].first) { |
|
|
|
|
|
|
|
std::copy(best.begin() + i, best.begin() + nRelayNodes - 1, best.begin() + i + 1); |
|
|
|
|
|
|
|
best[i] = std::make_pair(hashKey, pnode); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
auto pushfunc = [&addr, &mapMix, &nRelayNodes, &insecure_rand] { |
|
|
|
auto pushfunc = [&addr, &best, nRelayNodes, &insecure_rand] { |
|
|
|
for (auto mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi) |
|
|
|
for (unsigned int i = 0; i < nRelayNodes && best[i].first != 0; i++) { |
|
|
|
mi->second->PushAddress(addr, insecure_rand); |
|
|
|
best[i].second->PushAddress(addr, insecure_rand); |
|
|
|
|
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
connman.ForEachNodeThen(std::move(sortfunc), std::move(pushfunc)); |
|
|
|
connman.ForEachNodeThen(std::move(sortfunc), std::move(pushfunc)); |
|
|
|