Merge pull request #7079

ebb25f4 Limit setAskFor and retire requested entries only when a getdata returns. (Gregory Maxwell)
5029698 prevent peer flooding request queue for an inv (kazcw)
This commit is contained in:
Wladimir J. van der Laan 2015-12-01 08:56:43 +01:00
commit 1b5118bfa0
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
3 changed files with 12 additions and 1 deletions

View File

@ -4675,6 +4675,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
bool fMissingInputs = false; bool fMissingInputs = false;
CValidationState state; CValidationState state;
pfrom->setAskFor.erase(inv.hash);
mapAlreadyAskedFor.erase(inv); mapAlreadyAskedFor.erase(inv);
if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs)) if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
@ -5623,6 +5624,9 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
pto->PushMessage("getdata", vGetData); pto->PushMessage("getdata", vGetData);
vGetData.clear(); vGetData.clear();
} }
} else {
//If we're not going to ask, don't expect a response.
pto->setAskFor.erase(inv.hash);
} }
pto->mapAskFor.erase(pto->mapAskFor.begin()); pto->mapAskFor.erase(pto->mapAskFor.begin());
} }

View File

@ -2407,8 +2407,12 @@ CNode::~CNode()
void CNode::AskFor(const CInv& inv) void CNode::AskFor(const CInv& inv)
{ {
if (mapAskFor.size() > MAPASKFOR_MAX_SZ) if (mapAskFor.size() > MAPASKFOR_MAX_SZ || setAskFor.size() > SETASKFOR_MAX_SZ)
return; return;
// a peer may not have multiple non-responded queue positions for a single inv item
if (!setAskFor.insert(inv.hash).second)
return;
// We're using mapAskFor as a priority queue, // We're using mapAskFor as a priority queue,
// the key is the earliest time the request can be sent // the key is the earliest time the request can be sent
int64_t nRequestTime; int64_t nRequestTime;

View File

@ -58,6 +58,8 @@ static const bool DEFAULT_UPNP = false;
#endif #endif
/** The maximum number of entries in mapAskFor */ /** The maximum number of entries in mapAskFor */
static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ; 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;
/** The maximum number of peer connections to maintain. */ /** The maximum number of peer connections to maintain. */
static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125; static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
/** The default for -maxuploadtarget. 0 = Unlimited */ /** The default for -maxuploadtarget. 0 = Unlimited */
@ -389,6 +391,7 @@ public:
mruset<CInv> setInventoryKnown; mruset<CInv> setInventoryKnown;
std::vector<CInv> vInventoryToSend; std::vector<CInv> vInventoryToSend;
CCriticalSection cs_inventory; CCriticalSection cs_inventory;
std::set<uint256> setAskFor;
std::multimap<int64_t, CInv> mapAskFor; std::multimap<int64_t, CInv> mapAskFor;
// Used for headers announcements - unfiltered blocks to relay // Used for headers announcements - unfiltered blocks to relay
// Also protected by cs_inventory // Also protected by cs_inventory