From 16b0e12385f4c67d4f69f275c9ab38d6a64f5345 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Fri, 20 May 2016 16:19:26 +0000 Subject: [PATCH] Do not use mempool for GETDATA for tx accepted after the last mempoolreq --- src/main.cpp | 11 ++++++----- src/net.cpp | 1 + src/net.h | 3 +++ src/txmempool.cpp | 10 +++++++++- src/txmempool.h | 1 + 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b42d7e039..257e77977 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4899,11 +4899,11 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam } if (!pushed && inv.type == MSG_TX) { CTransaction tx; - if (mempool.lookup(inv.hash, tx)) { - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss.reserve(1000); - ss << tx; - pfrom->PushMessage(NetMsgType::TX, ss); + int64_t txtime; + // To protect privacy, do not answer getdata using the mempool when + // that TX couldn't have been INVed in reply to a MEMPOOL request. + if (mempool.lookup(inv.hash, tx, txtime) && txtime <= pfrom->timeLastMempoolReq) { + pfrom->PushMessage(NetMsgType::TX, tx); pushed = true; } } @@ -6581,6 +6581,7 @@ bool SendMessages(CNode* pto) vInv.clear(); } } + pto->timeLastMempoolReq = GetTime(); } // Determine transactions to relay diff --git a/src/net.cpp b/src/net.cpp index 3d0e0bbbe..3c8a21a83 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2364,6 +2364,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nNextInvSend = 0; fRelayTxes = false; pfilter = new CBloomFilter(); + timeLastMempoolReq = 0; nPingNonceSent = 0; nPingUsecStart = 0; nPingUsecTime = 0; diff --git a/src/net.h b/src/net.h index 4c7fa0d3f..cf96516d9 100644 --- a/src/net.h +++ b/src/net.h @@ -17,6 +17,7 @@ #include "sync.h" #include "uint256.h" +#include #include #include @@ -409,6 +410,8 @@ public: // Used for BIP35 mempool sending, also protected by cs_inventory bool fSendMempool; + // Last time a "MEMPOOL" request was serviced. + std::atomic timeLastMempoolReq; // Ping time measurement: // The pong reply we're expecting, or 0 if no pong expected. uint64_t nPingNonceSent; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 0e5e28648..9a0f78279 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -801,15 +801,23 @@ void CTxMemPool::queryHashes(vector& vtxid) std::sort(vtxid.begin(), vtxid.end(), DepthAndScoreComparator(this)); } -bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const + +bool CTxMemPool::lookup(uint256 hash, CTransaction& result, int64_t& time) const { LOCK(cs); indexed_transaction_set::const_iterator i = mapTx.find(hash); if (i == mapTx.end()) return false; result = i->GetTx(); + time = i->GetTime(); return true; } +bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const +{ + int64_t time; + return CTxMemPool::lookup(hash, result, time); +} + bool CTxMemPool::lookupFeeRate(const uint256& hash, CFeeRate& feeRate) const { LOCK(cs); diff --git a/src/txmempool.h b/src/txmempool.h index 521c9cf7c..53a0887fd 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -597,6 +597,7 @@ public: } bool lookup(uint256 hash, CTransaction& result) const; + bool lookup(uint256 hash, CTransaction& result, int64_t& time) const; bool lookupFeeRate(const uint256& hash, CFeeRate& feeRate) const; /** Estimate fee rate needed to get into the next nBlocks