Auto merge of #1407 - bitcartel:master_bitcoin_7079, r=daira

Upstream patch: Prevent peer flooding inv request queue

https://github.com/bitcoin/bitcoin/pull/7079
5029698186445bf3cd69d0e720f019c472661bff
ebb25f4c23adbcb55796c402bafd6064a136f16f
This commit is contained in:
zkbot
2016-09-20 19:11:28 -04:00
3 changed files with 12 additions and 1 deletions

View File

@@ -4657,6 +4657,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);
// Check for recently rejected (and do other quick existence checks) // Check for recently rejected (and do other quick existence checks)
@@ -5451,6 +5452,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

@@ -2178,8 +2178,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

@@ -59,6 +59,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;
unsigned int ReceiveFloodSize(); unsigned int ReceiveFloodSize();
unsigned int SendBufferSize(); unsigned int SendBufferSize();
@@ -310,6 +312,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;
// Ping time measurement: // Ping time measurement: