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.
Github-Pull: #7125
Rebased-From: 5400ef6bcb
This commit is contained in:
committed by
Wladimir J. van der Laan
parent
06c6a58463
commit
10b88be798
34
src/main.cpp
34
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
|
||||
|
||||
Reference in New Issue
Block a user