diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2015-04-08 11:20:00 -0700 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2015-12-11 22:20:38 +0100 |
commit | 5400ef6bcb9d243b2b21697775aa6491115420f3 (patch) | |
tree | bb8bb37f0db1e2a48318f64fb42de0a95d5f997b /src/main.cpp | |
parent | 9ee02cf564d1ce79d2981899cb4d38c914210dc7 (diff) |
Replace trickle nodes with per-node/message Poisson delays
We used to have a trickle node, a node which was chosen in each iteration of
the send loop that was privileged and allowed to send out queued up non-time
critical messages. Since the removal of the fixed sleeps in the network code,
this resulted in fast and attackable treatment of such broadcasts.
This pull request changes the 3 remaining trickle use cases by random delays:
* Local address broadcast (while also removing the the wiping of the seen filter)
* Address relay
* Inv relay (for transactions; blocks are always relayed immediately)
The code is based on older commits by Patrick Strateman.
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 34 |
1 files changed, 14 insertions, 20 deletions
diff --git a/src/main.cpp b/src/main.cpp index d2e736d421..41fc0b8098 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5326,7 +5326,7 @@ bool ProcessMessages(CNode* pfrom) } -bool SendMessages(CNode* pto, bool fSendTrickle) +bool SendMessages(CNode* pto) { const Consensus::Params& consensusParams = Params().GetConsensus(); { @@ -5368,28 +5368,17 @@ bool SendMessages(CNode* pto, bool fSendTrickle) return true; // Address refresh broadcast - static int64_t nLastRebroadcast; - if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60)) - { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - { - // Periodically clear addrKnown to allow refresh broadcasts - if (nLastRebroadcast) - pnode->addrKnown.reset(); - - // Rebroadcast our address - AdvertizeLocal(pnode); - } - if (!vNodes.empty()) - nLastRebroadcast = GetTime(); + int64_t nNow = GetTimeMicros(); + if (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) { + AdvertizeLocal(pto); + pto->nNextLocalAddrSend = PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL); } // // Message: addr // - if (fSendTrickle) - { + if (pto->nNextAddrSend < nNow) { + pto->nNextAddrSend = PoissonNextSend(nNow, AVG_ADDRESS_BROADCAST_INTERVAL); vector<CAddress> vAddr; vAddr.reserve(pto->vAddrToSend.size()); BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend) @@ -5563,8 +5552,13 @@ bool SendMessages(CNode* pto, bool fSendTrickle) vector<CInv> vInv; vector<CInv> vInvWait; { + bool fSendTrickle = pto->fWhitelisted; + if (pto->nNextInvSend < nNow) { + fSendTrickle = true; + pto->nNextInvSend = PoissonNextSend(nNow, AVG_INVENTORY_BROADCAST_INTERVAL); + } LOCK(pto->cs_inventory); - vInv.reserve(pto->vInventoryToSend.size()); + vInv.reserve(std::min<size_t>(1000, pto->vInventoryToSend.size())); vInvWait.reserve(pto->vInventoryToSend.size()); BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend) { @@ -5604,7 +5598,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) pto->PushMessage(NetMsgType::INV, vInv); // Detect whether we're stalling - int64_t nNow = GetTimeMicros(); + nNow = GetTimeMicros(); if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) { // Stalling only triggers when the block download window cannot move. During normal steady state, // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection |