Skip to content

Commit 4d8993b

Browse files
committed
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.
1 parent 862fd24 commit 4d8993b

File tree

3 files changed

+30
-31
lines changed

3 files changed

+30
-31
lines changed

src/main.cpp

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ uint64_t nPruneTarget = 0;
8080
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
8181
bool fEnableReplacement = DEFAULT_ENABLE_REPLACEMENT;
8282

83+
std::map<uint256, CTransaction> mapRelay;
84+
std::deque<std::pair<int64_t, uint256> > vRelayExpiration;
85+
CCriticalSection cs_mapRelay;
86+
8387
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
8488
CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
8589

@@ -4501,27 +4505,28 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
45014505
}
45024506
else if (inv.IsKnownType())
45034507
{
4508+
CTransaction tx;
45044509
// Send stream from relay memory
4505-
bool pushed = false;
4510+
bool push = false;
45064511
{
45074512
LOCK(cs_mapRelay);
45084513
map<uint256, CTransaction>::iterator mi = mapRelay.find(inv.hash);
45094514
if (mi != mapRelay.end()) {
4510-
pfrom->PushMessage(inv.GetCommand(), (*mi).second);
4511-
pushed = true;
4515+
tx = (*mi).second;
4516+
push = true;
45124517
}
45134518
}
4514-
if (!pushed && inv.type == MSG_TX) {
4515-
CTransaction tx;
4519+
if (!push && inv.type == MSG_TX) {
45164520
int64_t txtime;
45174521
// To protect privacy, do not answer getdata using the mempool when
45184522
// that TX couldn't have been INVed in reply to a MEMPOOL request.
45194523
if (mempool.lookup(inv.hash, tx, txtime) && txtime <= pfrom->timeLastMempoolReq) {
4520-
pfrom->PushMessage(NetMsgType::TX, tx);
4521-
pushed = true;
4524+
push = true;
45224525
}
45234526
}
4524-
if (!pushed) {
4527+
if (push) {
4528+
pfrom->PushMessage(inv.GetCommand(), tx);
4529+
} else {
45254530
vNotFound.push_back(inv);
45264531
}
45274532
}
@@ -5958,14 +5963,26 @@ bool SendMessages(CNode* pto)
59585963
if (filterrate && feeRate.GetFeePerK() < filterrate) {
59595964
continue;
59605965
}
5961-
if (pto->pfilter) {
5962-
CTransaction tx;
5963-
if (!mempool.lookup(hash, tx)) continue;
5964-
if (!pto->pfilter->IsRelevantAndUpdate(tx)) continue;
5965-
}
5966+
CTransaction tx;
5967+
if (!mempool.lookup(hash, tx)) continue;
5968+
if (pto->pfilter && !pto->pfilter->IsRelevantAndUpdate(tx)) continue;
59665969
// Send
59675970
vInv.push_back(CInv(MSG_TX, hash));
59685971
nRelayedTransactions++;
5972+
{
5973+
LOCK(cs_mapRelay);
5974+
// Expire old relay messages
5975+
while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
5976+
{
5977+
mapRelay.erase(vRelayExpiration.front().second);
5978+
vRelayExpiration.pop_front();
5979+
}
5980+
5981+
auto ret = mapRelay.insert(std::make_pair(hash, tx));
5982+
if (ret.second) {
5983+
vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, hash));
5984+
}
5985+
}
59695986
if (vInv.size() == MAX_INV_SZ) {
59705987
pto->PushMessage(NetMsgType::INV, vInv);
59715988
vInv.clear();

src/net.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,6 @@ std::string strSubVersion;
9090

9191
std::vector<CNode*> vNodes;
9292
CCriticalSection cs_vNodes;
93-
std::map<uint256, CTransaction> mapRelay;
94-
std::deque<std::pair<int64_t, uint256> > vRelayExpiration;
95-
CCriticalSection cs_mapRelay;
9693
limitedmap<uint256, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
9794

9895
static std::deque<std::string> vOneShots;
@@ -2081,18 +2078,6 @@ instance_of_cnetcleanup;
20812078
void RelayTransaction(const CTransaction& tx)
20822079
{
20832080
CInv inv(MSG_TX, tx.GetHash());
2084-
{
2085-
LOCK(cs_mapRelay);
2086-
// Expire old relay messages
2087-
while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
2088-
{
2089-
mapRelay.erase(vRelayExpiration.front().second);
2090-
vRelayExpiration.pop_front();
2091-
}
2092-
2093-
mapRelay.insert(std::make_pair(inv.hash, tx));
2094-
vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv.hash));
2095-
}
20962081
LOCK(cs_vNodes);
20972082
BOOST_FOREACH(CNode* pnode, vNodes)
20982083
{

src/net.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,6 @@ extern int nMaxConnections;
162162

163163
extern std::vector<CNode*> vNodes;
164164
extern CCriticalSection cs_vNodes;
165-
extern std::map<uint256, CTransaction> mapRelay;
166-
extern std::deque<std::pair<int64_t, uint256> > vRelayExpiration;
167-
extern CCriticalSection cs_mapRelay;
168165
extern limitedmap<uint256, int64_t> mapAlreadyAskedFor;
169166

170167
extern std::vector<std::string> vAddedNodes;

0 commit comments

Comments
 (0)