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.
This commit is contained in:
parent
8844ef15de
commit
7e908c7b82
5 changed files with 19 additions and 2 deletions
|
@ -4503,7 +4503,10 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
||||||
}
|
}
|
||||||
if (!pushed && inv.type == MSG_TX) {
|
if (!pushed && inv.type == MSG_TX) {
|
||||||
CTransaction 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);
|
pfrom->PushMessage(NetMsgType::TX, tx);
|
||||||
pushed = true;
|
pushed = true;
|
||||||
}
|
}
|
||||||
|
@ -5902,6 +5905,7 @@ bool SendMessages(CNode* pto)
|
||||||
vInv.clear();
|
vInv.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pto->timeLastMempoolReq = GetTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine transactions to relay
|
// Determine transactions to relay
|
||||||
|
|
|
@ -2396,6 +2396,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
|
||||||
fRelayTxes = false;
|
fRelayTxes = false;
|
||||||
fSentAddr = false;
|
fSentAddr = false;
|
||||||
pfilter = new CBloomFilter();
|
pfilter = new CBloomFilter();
|
||||||
|
timeLastMempoolReq = 0;
|
||||||
nPingNonceSent = 0;
|
nPingNonceSent = 0;
|
||||||
nPingUsecStart = 0;
|
nPingUsecStart = 0;
|
||||||
nPingUsecTime = 0;
|
nPingUsecTime = 0;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
@ -413,6 +414,8 @@ public:
|
||||||
// Used for BIP35 mempool sending, also protected by cs_inventory
|
// Used for BIP35 mempool sending, also protected by cs_inventory
|
||||||
bool fSendMempool;
|
bool fSendMempool;
|
||||||
|
|
||||||
|
// Last time a "MEMPOOL" request was serviced.
|
||||||
|
std::atomic<int64_t> timeLastMempoolReq;
|
||||||
// Ping time measurement:
|
// Ping time measurement:
|
||||||
// The pong reply we're expecting, or 0 if no pong expected.
|
// The pong reply we're expecting, or 0 if no pong expected.
|
||||||
uint64_t nPingNonceSent;
|
uint64_t nPingNonceSent;
|
||||||
|
|
|
@ -789,15 +789,23 @@ void CTxMemPool::queryHashes(vector<uint256>& vtxid)
|
||||||
std::sort(vtxid.begin(), vtxid.end(), DepthAndScoreComparator(this));
|
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);
|
LOCK(cs);
|
||||||
indexed_transaction_set::const_iterator i = mapTx.find(hash);
|
indexed_transaction_set::const_iterator i = mapTx.find(hash);
|
||||||
if (i == mapTx.end()) return false;
|
if (i == mapTx.end()) return false;
|
||||||
result = i->GetTx();
|
result = i->GetTx();
|
||||||
|
time = i->GetTime();
|
||||||
return true;
|
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
|
bool CTxMemPool::lookupFeeRate(const uint256& hash, CFeeRate& feeRate) const
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
|
|
|
@ -602,6 +602,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lookup(uint256 hash, CTransaction& result) const;
|
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;
|
bool lookupFeeRate(const uint256& hash, CFeeRate& feeRate) const;
|
||||||
|
|
||||||
/** Estimate fee rate needed to get into the next nBlocks
|
/** Estimate fee rate needed to get into the next nBlocks
|
||||||
|
|
Loading…
Reference in a new issue