aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGregory Maxwell <greg@xiph.org>2016-05-20 16:19:26 +0000
committerGregory Maxwell <greg@xiph.org>2016-05-25 18:05:58 +0000
commit7e908c7b826cedbf29560ce7a668af809ee71524 (patch)
treeb28d1f37652e06bde2db6127cbb3378ee35c7617 /src
parent8844ef15ded02d5ed86fb95aaf251235fcef2396 (diff)
downloadbitcoin-7e908c7b826cedbf29560ce7a668af809ee71524.tar.xz
Do not use mempool for GETDATA for tx accepted after the last mempool req.
The ability to GETDATA a transaction which has not (yet) been relayed is a privacy loss vector. The use of the mempool for this was added as part of the mempool p2p message and is only needed to fetch transactions returned by it.
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp6
-rw-r--r--src/net.cpp1
-rw-r--r--src/net.h3
-rw-r--r--src/txmempool.cpp10
-rw-r--r--src/txmempool.h1
5 files changed, 19 insertions, 2 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 9ba90b4ead..2ee6bc5310 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -4503,7 +4503,10 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
}
if (!pushed && inv.type == MSG_TX) {
CTransaction tx;
- if (mempool.lookup(inv.hash, tx)) {
+ 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;
}
@@ -5902,6 +5905,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 bbd23d292a..df3221e841 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -2396,6 +2396,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
fRelayTxes = false;
fSentAddr = false;
pfilter = new CBloomFilter();
+ timeLastMempoolReq = 0;
nPingNonceSent = 0;
nPingUsecStart = 0;
nPingUsecTime = 0;
diff --git a/src/net.h b/src/net.h
index 998ee49260..66cc912a52 100644
--- a/src/net.h
+++ b/src/net.h
@@ -17,6 +17,7 @@
#include "sync.h"
#include "uint256.h"
+#include <atomic>
#include <deque>
#include <stdint.h>
@@ -413,6 +414,8 @@ public:
// Used for BIP35 mempool sending, also protected by cs_inventory
bool fSendMempool;
+ // Last time a "MEMPOOL" request was serviced.
+ std::atomic<int64_t> 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 aa5df6ca4e..4f17e7f8ca 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -789,15 +789,23 @@ void CTxMemPool::queryHashes(vector<uint256>& 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 3e1d387975..75cf0f4c12 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -602,6 +602,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