@ -81,9 +81,6 @@ uint64_t nPruneTarget = 0;
@@ -81,9 +81,6 @@ 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 ;
@ -216,6 +213,12 @@ namespace {
@@ -216,6 +213,12 @@ namespace {
/** Number of peers from which we're downloading blocks. */
int nPeersWithValidatedDownloads = 0 ;
/** Relay map, protected by cs_main. */
typedef std : : map < uint256 , std : : shared_ptr < const CTransaction > > MapRelay ;
MapRelay mapRelay ;
/** Expiration-time ordered list of (expire time, relay map entry) pairs, protected by cs_main). */
std : : deque < std : : pair < int64_t , MapRelay : : iterator > > vRelayExpiration ;
} // anon namespace
//////////////////////////////////////////////////////////////////////////////
@ -1443,8 +1446,10 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::P
@@ -1443,8 +1446,10 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::P
LOCK ( cs_main ) ;
if ( mempool . lookup ( hash , txOut ) )
std : : shared_ptr < const CTransaction > ptx = mempool . get ( hash ) ;
if ( ptx )
{
txOut = * ptx ;
return true ;
}
@ -4521,30 +4526,24 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
@@ -4521,30 +4526,24 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
}
}
}
else if ( inv . IsKnownType ( ) )
else if ( inv . type = = MSG_TX )
{
CTransaction tx ;
// Send stream from relay memory
bool push = false ;
{
LOCK ( cs_mapRelay ) ;
map < uint256 , CTransaction > : : iterator mi = mapRelay . find ( inv . hash ) ;
auto mi = mapRelay . find ( inv . hash ) ;
if ( mi ! = mapRelay . end ( ) ) {
tx = ( * mi ) . second ;
pfrom - > PushMessage ( NetMsgType : : TX , * mi - > second ) ;
push = true ;
}
}
if ( ! push & & inv . type = = MSG_TX ) {
int64_t txtime ;
} else if ( pfrom - > timeLastMempoolReq ) {
auto txinfo = mempool . info ( inv . hash ) ;
// 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 ) {
if ( txinfo . tx & & txinfo . nTime < = pfrom - > timeLastMempoolReq ) {
pfrom - > PushMessage ( NetMsgType : : TX , * txinfo . tx ) ;
push = true ;
}
}
if ( push ) {
pfrom - > PushMessage ( inv . GetCommand ( ) , tx ) ;
} else {
if ( ! push ) {
vNotFound . push_back ( inv ) ;
}
}
@ -5923,8 +5922,7 @@ bool SendMessages(CNode* pto)
@@ -5923,8 +5922,7 @@ bool SendMessages(CNode* pto)
// Respond to BIP35 mempool requests
if ( fSendTrickle & & pto - > fSendMempool ) {
std : : vector < uint256 > vtxid ;
mempool . queryHashes ( vtxid ) ;
auto vtxinfo = mempool . infoAll ( ) ;
pto - > fSendMempool = false ;
CAmount filterrate = 0 ;
{
@ -5934,20 +5932,16 @@ bool SendMessages(CNode* pto)
@@ -5934,20 +5932,16 @@ bool SendMessages(CNode* pto)
LOCK ( pto - > cs_filter ) ;
BOOST_FOREACH ( const uint256 & hash , vtxid ) {
for ( const auto & txinfo : vtxinfo ) {
const uint256 & hash = txinfo . tx - > GetHash ( ) ;
CInv inv ( MSG_TX , hash ) ;
pto - > setInventoryTxToSend . erase ( hash ) ;
if ( filterrate ) {
CFeeRate feeRate ;
mempool . lookupFeeRate ( hash , feeRate ) ;
if ( feeRate . GetFeePerK ( ) < filterrate )
if ( txinfo . feeRate . GetFeePerK ( ) < filterrate )
continue ;
}
if ( pto - > pfilter ) {
CTransaction tx ;
bool fInMemPool = mempool . lookup ( hash , tx ) ;
if ( ! fInMemPool ) continue ; // another thread removed since queryHashes, maybe...
if ( ! pto - > pfilter - > IsRelevantAndUpdate ( tx ) ) continue ;
if ( ! pto - > pfilter - > IsRelevantAndUpdate ( * txinfo . tx ) ) continue ;
}
pto - > filterInventoryKnown . insert ( hash ) ;
vInv . push_back ( inv ) ;
@ -5993,31 +5987,28 @@ bool SendMessages(CNode* pto)
@@ -5993,31 +5987,28 @@ bool SendMessages(CNode* pto)
continue ;
}
// Not in the mempool anymore? don't bother sending it.
CFeeRate feeRate ;
if ( ! mempool . lookupFeeRate ( hash , feeRate ) ) {
auto txinfo = mempool . info ( hash ) ;
if ( ! txinfo . tx ) {
continue ;
}
if ( filterrate & & feeRate . GetFeePerK ( ) < filterrate ) {
if ( filterrate & & txinfo . feeRate . GetFeePerK ( ) < filterrate ) {
continue ;
}
CTransaction tx ;
if ( ! mempool . lookup ( hash , tx ) ) continue ;
if ( pto - > pfilter & & ! pto - > pfilter - > IsRelevantAndUpdate ( tx ) ) continue ;
if ( pto - > pfilter & & ! pto - > pfilter - > IsRelevantAndUpdate ( * txinfo . 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 ( ) )
while ( ! vRelayExpiration . empty ( ) & & vRelayExpiration . front ( ) . first < nNow )
{
mapRelay . erase ( vRelayExpiration . front ( ) . second ) ;
vRelayExpiration . pop_front ( ) ;
}
auto ret = mapRelay . insert ( std : : make_pair ( hash , tx ) ) ;
auto ret = mapRelay . insert ( std : : make_pair ( hash , std : : move ( txinfo . tx ) ) ) ;
if ( ret . second ) {
vRelayExpiration . push_back ( std : : make_pair ( GetTime ( ) + 15 * 60 , hash ) ) ;
vRelayExpiration . push_back ( std : : make_pair ( nNow + 15 * 60 * 1000000 , ret . first ) ) ;
}
}
if ( vInv . size ( ) = = MAX_INV_SZ ) {