mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-18 22:35:39 +01:00
Defer inserting into maprelay until just before relaying.
This reduces the rate of not founds by better matching the far end expectations, it also improves privacy by removing the ability to use getdata to probe for a node having a txn before it has been relayed.
This commit is contained in:
43
src/main.cpp
43
src/main.cpp
@@ -80,6 +80,10 @@ uint64_t nPruneTarget = 0;
|
||||
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
|
||||
bool fEnableReplacement = DEFAULT_ENABLE_REPLACEMENT;
|
||||
|
||||
std::map<uint256, CTransaction> mapRelay;
|
||||
std::deque<std::pair<int64_t, uint256> > vRelayExpiration;
|
||||
CCriticalSection cs_mapRelay;
|
||||
|
||||
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
|
||||
CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
|
||||
|
||||
@@ -4501,27 +4505,28 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
||||
}
|
||||
else if (inv.IsKnownType())
|
||||
{
|
||||
CTransaction tx;
|
||||
// Send stream from relay memory
|
||||
bool pushed = false;
|
||||
bool push = false;
|
||||
{
|
||||
LOCK(cs_mapRelay);
|
||||
map<uint256, CTransaction>::iterator mi = mapRelay.find(inv.hash);
|
||||
if (mi != mapRelay.end()) {
|
||||
pfrom->PushMessage(inv.GetCommand(), (*mi).second);
|
||||
pushed = true;
|
||||
tx = (*mi).second;
|
||||
push = true;
|
||||
}
|
||||
}
|
||||
if (!pushed && inv.type == MSG_TX) {
|
||||
CTransaction tx;
|
||||
if (!push && inv.type == MSG_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;
|
||||
push = true;
|
||||
}
|
||||
}
|
||||
if (!pushed) {
|
||||
if (push) {
|
||||
pfrom->PushMessage(inv.GetCommand(), tx);
|
||||
} else {
|
||||
vNotFound.push_back(inv);
|
||||
}
|
||||
}
|
||||
@@ -5958,14 +5963,26 @@ bool SendMessages(CNode* pto)
|
||||
if (filterrate && feeRate.GetFeePerK() < filterrate) {
|
||||
continue;
|
||||
}
|
||||
if (pto->pfilter) {
|
||||
CTransaction tx;
|
||||
if (!mempool.lookup(hash, tx)) continue;
|
||||
if (!pto->pfilter->IsRelevantAndUpdate(tx)) continue;
|
||||
}
|
||||
CTransaction tx;
|
||||
if (!mempool.lookup(hash, tx)) continue;
|
||||
if (pto->pfilter && !pto->pfilter->IsRelevantAndUpdate(tx)) continue;
|
||||
// Send
|
||||
vInv.push_back(CInv(MSG_TX, hash));
|
||||
nRelayedTransactions++;
|
||||
{
|
||||
LOCK(cs_mapRelay);
|
||||
// Expire old relay messages
|
||||
while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
|
||||
{
|
||||
mapRelay.erase(vRelayExpiration.front().second);
|
||||
vRelayExpiration.pop_front();
|
||||
}
|
||||
|
||||
auto ret = mapRelay.insert(std::make_pair(hash, tx));
|
||||
if (ret.second) {
|
||||
vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, hash));
|
||||
}
|
||||
}
|
||||
if (vInv.size() == MAX_INV_SZ) {
|
||||
pto->PushMessage(NetMsgType::INV, vInv);
|
||||
vInv.clear();
|
||||
|
||||
Reference in New Issue
Block a user