Move bloom and feerate filtering to just prior to tx sending.

This commit is contained in:
Gregory Maxwell
2016-04-20 07:05:23 +00:00
committed by lateminer
parent 80803b1de0
commit c41eb3a831
3 changed files with 38 additions and 21 deletions

View File

@@ -4994,12 +4994,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
vRecv >> LIMITED_STRING(pfrom->strSubVer, MAX_SUBVERSION_LENGTH);
pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
}
if (!vRecv.empty())
if (!vRecv.empty()) {
vRecv >> pfrom->nStartingHeight;
if (!vRecv.empty())
vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
else
pfrom->fRelayTxes = true;
}
{
LOCK(pfrom->cs_filter);
if (!vRecv.empty())
vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
else
pfrom->fRelayTxes = true;
}
// Disconnect if we connected to ourself
if (nNonce == nLocalHostNonce && nNonce > 1)
@@ -6031,12 +6035,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CBloomFilter filter;
vRecv >> filter;
LOCK(pfrom->cs_filter);
if (!filter.IsWithinSizeConstraints())
// There is no excuse for sending a too-large filter
Misbehaving(pfrom->GetId(), 100);
else
{
LOCK(pfrom->cs_filter);
delete pfrom->pfilter;
pfrom->pfilter = new CBloomFilter(filter);
pfrom->pfilter->UpdateEmptyFull();
@@ -6535,6 +6540,12 @@ bool SendMessages(CNode* pto)
pto->nNextInvSend = PoissonNextSend(nNow, INVENTORY_BROADCAST_INTERVAL >> !pto->fInbound);
}
// Time to send but the peer has requested we not relay transactions.
if (fSendTrickle) {
LOCK(pto->cs_filter);
if (!pto->fRelayTxes) pto->setInventoryTxToSend.clear();
}
// Respond to BIP35 mempool requests
if (fSendTrickle && pto->fSendMempool) {
std::vector<uint256> vtxid;
@@ -6580,6 +6591,11 @@ bool SendMessages(CNode* pto)
for (std::set<uint256>::iterator it = pto->setInventoryTxToSend.begin(); it != pto->setInventoryTxToSend.end(); it++) {
vInvTx.push_back(it);
}
CAmount filterrate = 0;
{
LOCK(pto->cs_feeFilter);
filterrate = pto->minFeeFilter;
}
// Topologically and fee-rate sort the inventory we send for privacy and priority reasons.
// A heap is used so that not all items need sorting if only a few are being sent.
CompareInvMempoolOrder compareInvMempoolOrder(&mempool);
@@ -6587,6 +6603,7 @@ bool SendMessages(CNode* pto)
// No reason to drain out at many times the network's capacity,
// especially since we have many peers and some will draw much shorter delays.
unsigned int nRelayedTransactions = 0;
LOCK(pto->cs_filter);
while (!vInvTx.empty() && nRelayedTransactions < INVENTORY_BROADCAST_MAX) {
// Fetch the top element from the heap
std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
@@ -6599,6 +6616,19 @@ bool SendMessages(CNode* pto)
if (pto->filterInventoryKnown.contains(hash)) {
continue;
}
// Not in the mempool anymore? don't bother sending it.
CFeeRate feeRate;
if (!mempool.lookupFeeRate(hash, feeRate)) {
continue;
}
if (filterrate && feeRate.GetFeePerK() < filterrate) {
continue;
}
if (pto->pfilter) {
CTransaction tx;
if (!mempool.lookup(hash, tx)) continue;
if (!pto->pfilter->IsRelevantAndUpdate(tx)) continue;
}
// Send
vInv.push_back(CInv(MSG_TX, hash));
nRelayedTransactions++;