aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2016-09-09 13:56:03 +0200
committerPieter Wuille <pieter.wuille@gmail.com>2016-11-03 00:20:04 -0700
commita33b1691f11316f839ddfdf51e1950acf0bc08aa (patch)
tree0fdc559b2fccfb42f14adf669d5ef4b22c7fb731 /src
parent508404de98a8a5435f52916cef8f328e82651961 (diff)
downloadbitcoin-a33b1691f11316f839ddfdf51e1950acf0bc08aa.tar.xz
Do not fully sort all nodes for addr relay
As we only need 1 or 2, explicitly keep track of the best ones.
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp23
1 files changed, 16 insertions, 7 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 44031e69e7..f5e94d8ec7 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -4804,26 +4804,35 @@ static void RelayTransaction(const CTransaction& tx, 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
// Use deterministic randomness to send to the same nodes for 24 hours
// at a time so the addrKnowns of the chosen nodes prevent repeats
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));
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) {
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] {
- for (auto mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
- mi->second->PushAddress(addr, insecure_rand);
+ auto pushfunc = [&addr, &best, nRelayNodes, &insecure_rand] {
+ for (unsigned int i = 0; i < nRelayNodes && best[i].first != 0; i++) {
+ best[i].second->PushAddress(addr, insecure_rand);
+ }
};
connman.ForEachNodeThen(std::move(sortfunc), std::move(pushfunc));