@ -384,7 +384,9 @@ void UpdateMempoolForReorg(DisconnectedBlockTransactions &disconnectpool, bool f
while ( it ! = disconnectpool . queuedTx . get < insertion_order > ( ) . rend ( ) ) {
while ( it ! = disconnectpool . queuedTx . get < insertion_order > ( ) . rend ( ) ) {
// ignore validation errors in resurrected transactions
// ignore validation errors in resurrected transactions
CValidationState stateDummy ;
CValidationState stateDummy ;
if ( ! fAddToMempool | | ( * it ) - > IsCoinBase ( ) | | ! AcceptToMemoryPool ( mempool , stateDummy , * it , false , nullptr , nullptr , true ) ) {
if ( ! fAddToMempool | | ( * it ) - > IsCoinBase ( ) | |
! AcceptToMemoryPool ( mempool , stateDummy , * it , nullptr /* pfMissingInputs */ ,
nullptr /* plTxnReplaced */ , true /* bypass_limits */ , 0 /* nAbsurdFee */ ) ) {
// If the transaction doesn't make it in to the mempool, remove any
// If the transaction doesn't make it in to the mempool, remove any
// transactions that depend on it (which would now be orphans).
// transactions that depend on it (which would now be orphans).
mempool . removeRecursive ( * * it , MemPoolRemovalReason : : REORG ) ;
mempool . removeRecursive ( * * it , MemPoolRemovalReason : : REORG ) ;
@ -443,9 +445,9 @@ static bool CheckInputsFromMempoolAndCache(const CTransaction& tx, CValidationSt
return CheckInputs ( tx , state , view , true , flags , cacheSigStore , true , txdata ) ;
return CheckInputs ( tx , state , view , true , flags , cacheSigStore , true , txdata ) ;
}
}
static bool AcceptToMemoryPoolWorker ( const CChainParams & chainparams , CTxMemPool & pool , CValidationState & state , const CTransactionRef & ptx , bool fLimitFree ,
static bool AcceptToMemoryPoolWorker ( const CChainParams & chainparams , CTxMemPool & pool , CValidationState & state , const CTransactionRef & ptx ,
bool * pfMissingInputs , int64_t nAcceptTime , std : : list < CTransactionRef > * plTxnReplaced ,
bool * pfMissingInputs , int64_t nAcceptTime , std : : list < CTransactionRef > * plTxnReplaced ,
bool fOverrideMempoolLimit , const CAmount & nAbsurdFee , std : : vector < COutPoint > & coins_to_uncache )
bool bypass_limits , const CAmount & nAbsurdFee , std : : vector < COutPoint > & coins_to_uncache )
{
{
const CTransaction & tx = * ptx ;
const CTransaction & tx = * ptx ;
const uint256 hash = tx . GetHash ( ) ;
const uint256 hash = tx . GetHash ( ) ;
@ -618,12 +620,12 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
strprintf ( " %d " , nSigOpsCost ) ) ;
strprintf ( " %d " , nSigOpsCost ) ) ;
CAmount mempoolRejectFee = pool . GetMinFee ( gArgs . GetArg ( " -maxmempool " , DEFAULT_MAX_MEMPOOL_SIZE ) * 1000000 ) . GetFee ( nSize ) ;
CAmount mempoolRejectFee = pool . GetMinFee ( gArgs . GetArg ( " -maxmempool " , DEFAULT_MAX_MEMPOOL_SIZE ) * 1000000 ) . GetFee ( nSize ) ;
if ( mempoolRejectFee > 0 & & nModifiedFees < mempoolRejectFee ) {
if ( ! bypass_limits & & mempoolRejectFee > 0 & & nModifiedFees < mempoolRejectFee ) {
return state . DoS ( 0 , false , REJECT_INSUFFICIENTFEE , " mempool min fee not met " , false , strprintf ( " %d < %d " , nFees , mempoolRejectFee ) ) ;
return state . DoS ( 0 , false , REJECT_INSUFFICIENTFEE , " mempool min fee not met " , false , strprintf ( " %d < %d " , nFees , mempoolRejectFee ) ) ;
}
}
// No transactions are allowed below minRelayTxFee except from disconnected blocks
// No transactions are allowed below minRelayTxFee except from disconnected blocks
if ( fLimitFree & & nModifiedFees < : : minRelayTxFee . GetFee ( nSize ) ) {
if ( ! bypass_limits & & nModifiedFees < : : minRelayTxFee . GetFee ( nSize ) ) {
return state . DoS ( 0 , false , REJECT_INSUFFICIENTFEE , " min relay fee not met " ) ;
return state . DoS ( 0 , false , REJECT_INSUFFICIENTFEE , " min relay fee not met " ) ;
}
}
@ -855,17 +857,18 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
}
}
pool . RemoveStaged ( allConflicting , false , MemPoolRemovalReason : : REPLACED ) ;
pool . RemoveStaged ( allConflicting , false , MemPoolRemovalReason : : REPLACED ) ;
// This transaction should only count for fee estimation if it isn't a
// This transaction should only count for fee estimation if:
// BIP 125 replacement transaction (may not be widely supported), the
// - it isn't a BIP 125 replacement transaction (may not be widely supported)
// node is not behind, and the transaction is not dependent on any other
// - it's not being readded during a reorg which bypasses typical mempool fee limits
// transactions in the mempool.
// - the node is not behind
bool validForFeeEstimation = ! fReplacementTransaction & & IsCurrentForFeeEstimation ( ) & & pool . HasNoInputsOf ( tx ) ;
// - the transaction is not dependent on any other transactions in the mempool
bool validForFeeEstimation = ! fReplacementTransaction & & ! bypass_limits & & IsCurrentForFeeEstimation ( ) & & pool . HasNoInputsOf ( tx ) ;
// Store transaction in memory
// Store transaction in memory
pool . addUnchecked ( hash , entry , setAncestors , validForFeeEstimation ) ;
pool . addUnchecked ( hash , entry , setAncestors , validForFeeEstimation ) ;
// trim mempool and check if tx was trimmed
// trim mempool and check if tx was trimmed
if ( ! fOverrideMempoolLimit ) {
if ( ! bypass_limits ) {
LimitMempoolSize ( pool , gArgs . GetArg ( " -maxmempool " , DEFAULT_MAX_MEMPOOL_SIZE ) * 1000000 , gArgs . GetArg ( " -mempoolexpiry " , DEFAULT_MEMPOOL_EXPIRY ) * 60 * 60 ) ;
LimitMempoolSize ( pool , gArgs . GetArg ( " -maxmempool " , DEFAULT_MAX_MEMPOOL_SIZE ) * 1000000 , gArgs . GetArg ( " -mempoolexpiry " , DEFAULT_MEMPOOL_EXPIRY ) * 60 * 60 ) ;
if ( ! pool . exists ( hash ) )
if ( ! pool . exists ( hash ) )
return state . DoS ( 0 , false , REJECT_INSUFFICIENTFEE , " mempool full " ) ;
return state . DoS ( 0 , false , REJECT_INSUFFICIENTFEE , " mempool full " ) ;
@ -878,12 +881,12 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
}
}
/** (try to) add transaction to memory pool with a specified acceptance time **/
/** (try to) add transaction to memory pool with a specified acceptance time **/
static bool AcceptToMemoryPoolWithTime ( const CChainParams & chainparams , CTxMemPool & pool , CValidationState & state , const CTransactionRef & tx , bool fLimitFree ,
static bool AcceptToMemoryPoolWithTime ( const CChainParams & chainparams , CTxMemPool & pool , CValidationState & state , const CTransactionRef & tx ,
bool * pfMissingInputs , int64_t nAcceptTime , std : : list < CTransactionRef > * plTxnReplaced ,
bool * pfMissingInputs , int64_t nAcceptTime , std : : list < CTransactionRef > * plTxnReplaced ,
bool fOverrideMempoolLimit , const CAmount nAbsurdFee )
bool bypass_limits , const CAmount nAbsurdFee )
{
{
std : : vector < COutPoint > coins_to_uncache ;
std : : vector < COutPoint > coins_to_uncache ;
bool res = AcceptToMemoryPoolWorker ( chainparams , pool , state , tx , fLimitFree , pfMissingInputs , nAcceptTime , plTxnReplaced , fOverrideMempoolLimit , nAbsurdFee , coins_to_uncache ) ;
bool res = AcceptToMemoryPoolWorker ( chainparams , pool , state , tx , pfMissingInputs , nAcceptTime , plTxnReplaced , bypass_limits , nAbsurdFee , coins_to_uncache ) ;
if ( ! res ) {
if ( ! res ) {
for ( const COutPoint & hashTx : coins_to_uncache )
for ( const COutPoint & hashTx : coins_to_uncache )
pcoinsTip - > Uncache ( hashTx ) ;
pcoinsTip - > Uncache ( hashTx ) ;
@ -894,12 +897,12 @@ static bool AcceptToMemoryPoolWithTime(const CChainParams& chainparams, CTxMemPo
return res ;
return res ;
}
}
bool AcceptToMemoryPool ( CTxMemPool & pool , CValidationState & state , const CTransactionRef & tx , bool fLimitFree ,
bool AcceptToMemoryPool ( CTxMemPool & pool , CValidationState & state , const CTransactionRef & tx ,
bool * pfMissingInputs , std : : list < CTransactionRef > * plTxnReplaced ,
bool * pfMissingInputs , std : : list < CTransactionRef > * plTxnReplaced ,
bool fOverrideMempoolLimit , const CAmount nAbsurdFee )
bool bypass_limits , const CAmount nAbsurdFee )
{
{
const CChainParams & chainparams = Params ( ) ;
const CChainParams & chainparams = Params ( ) ;
return AcceptToMemoryPoolWithTime ( chainparams , pool , state , tx , fLimitFree , pfMissingInputs , GetTime ( ) , plTxnReplaced , fOverrideMempoolLimit , nAbsurdFee ) ;
return AcceptToMemoryPoolWithTime ( chainparams , pool , state , tx , pfMissingInputs , GetTime ( ) , plTxnReplaced , bypass_limits , nAbsurdFee ) ;
}
}
/** Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock */
/** Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock */
@ -4306,7 +4309,8 @@ bool LoadMempool(void)
CValidationState state ;
CValidationState state ;
if ( nTime + nExpiryTimeout > nNow ) {
if ( nTime + nExpiryTimeout > nNow ) {
LOCK ( cs_main ) ;
LOCK ( cs_main ) ;
AcceptToMemoryPoolWithTime ( chainparams , mempool , state , tx , true , nullptr , nTime , nullptr , false , 0 ) ;
AcceptToMemoryPoolWithTime ( chainparams , mempool , state , tx , nullptr /* pfMissingInputs */ , nTime ,
nullptr /* plTxnReplaced */ , false /* bypass_limits */ , 0 /* nAbsurdFee */ ) ;
if ( state . IsValid ( ) ) {
if ( state . IsValid ( ) ) {
+ + count ;
+ + count ;
} else {
} else {