@ -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 push ed = 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 ) ;
push ed = 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 ;
}
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 ( ) ;