@@ -80,6 +80,10 @@ uint64_t nPruneTarget = 0;
80
80
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
81
81
bool fEnableReplacement = DEFAULT_ENABLE_REPLACEMENT;
82
82
83
+ std::map<uint256, CTransaction> mapRelay;
84
+ std::deque<std::pair<int64_t , uint256> > vRelayExpiration;
85
+ CCriticalSection cs_mapRelay;
86
+
83
87
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
84
88
CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
85
89
@@ -4501,27 +4505,28 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
4501
4505
}
4502
4506
else if (inv.IsKnownType ())
4503
4507
{
4508
+ CTransaction tx;
4504
4509
// Send stream from relay memory
4505
- bool pushed = false ;
4510
+ bool push = false ;
4506
4511
{
4507
4512
LOCK (cs_mapRelay);
4508
4513
map<uint256, CTransaction>::iterator mi = mapRelay.find (inv.hash );
4509
4514
if (mi != mapRelay.end ()) {
4510
- pfrom-> PushMessage (inv. GetCommand (), (*mi).second ) ;
4511
- pushed = true ;
4515
+ tx = (*mi).second ;
4516
+ push = true ;
4512
4517
}
4513
4518
}
4514
- if (!pushed && inv.type == MSG_TX) {
4515
- CTransaction tx;
4519
+ if (!push && inv.type == MSG_TX) {
4516
4520
int64_t txtime;
4517
4521
// To protect privacy, do not answer getdata using the mempool when
4518
4522
// that TX couldn't have been INVed in reply to a MEMPOOL request.
4519
4523
if (mempool.lookup (inv.hash , tx, txtime) && txtime <= pfrom->timeLastMempoolReq ) {
4520
- pfrom->PushMessage (NetMsgType::TX, tx);
4521
- pushed = true ;
4524
+ push = true ;
4522
4525
}
4523
4526
}
4524
- if (!pushed) {
4527
+ if (push) {
4528
+ pfrom->PushMessage (inv.GetCommand (), tx);
4529
+ } else {
4525
4530
vNotFound.push_back (inv);
4526
4531
}
4527
4532
}
@@ -5958,14 +5963,26 @@ bool SendMessages(CNode* pto)
5958
5963
if (filterrate && feeRate.GetFeePerK () < filterrate) {
5959
5964
continue ;
5960
5965
}
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 ;
5966
5969
// Send
5967
5970
vInv.push_back (CInv (MSG_TX, hash));
5968
5971
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
+ }
5969
5986
if (vInv.size () == MAX_INV_SZ) {
5970
5987
pto->PushMessage (NetMsgType::INV, vInv);
5971
5988
vInv.clear ();
0 commit comments