Browse Source

Limit setAskFor and retire requested entries only when a getdata returns.

The setAskFor duplicate elimination was too eager and removed entries
 when we still had no getdata response, allowing the peer to keep
 INVing and not responding.
pull/4/head
Gregory Maxwell 9 years ago
committed by
parent
commit
e2190f8017
  1. 5
      src/main.cpp
  2. 4
      src/net.cpp
  3. 2
      src/net.h

5
src/main.cpp

@ -4657,6 +4657,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
bool fMissingInputs = false;
CValidationState state;
pfrom->setAskFor.erase(inv.hash);
mapAlreadyAskedFor.erase(inv);
// Check for recently rejected (and do other quick existence checks)
@ -5451,8 +5452,10 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
pto->PushMessage("getdata", vGetData);
vGetData.clear();
}
} else {
//If we're not going to ask, don't expect a response.
pto->setAskFor.erase(inv.hash);
}
pto->setAskFor.erase(inv.hash);
pto->mapAskFor.erase(pto->mapAskFor.begin());
}
if (!vGetData.empty())

4
src/net.cpp

@ -2178,9 +2178,9 @@ CNode::~CNode()
void CNode::AskFor(const CInv& inv)
{
if (mapAskFor.size() > MAPASKFOR_MAX_SZ)
if (mapAskFor.size() > MAPASKFOR_MAX_SZ || setAskFor.size() > SETASKFOR_MAX_SZ)
return;
// a peer may not occupy multiple positions in an inv's request queue
// a peer may not have multiple non-responded queue positions for a single inv item
if (!setAskFor.insert(inv.hash).second)
return;

2
src/net.h

@ -59,6 +59,8 @@ static const bool DEFAULT_UPNP = false;
#endif
/** The maximum number of entries in mapAskFor */
static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ;
/** The maximum number of entries in setAskFor (larger due to getdata latency)*/
static const size_t SETASKFOR_MAX_SZ = 2 * MAX_INV_SZ;
unsigned int ReceiveFloodSize();
unsigned int SendBufferSize();

Loading…
Cancel
Save