diff options
Diffstat (limited to 'src/validation.cpp')
-rw-r--r-- | src/validation.cpp | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/src/validation.cpp b/src/validation.cpp index 1fd8f0e326..b2f4283e16 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -11,6 +11,7 @@ #include <arith_uint256.h> #include <chain.h> #include <checkqueue.h> +#include <common/args.h> #include <consensus/amount.h> #include <consensus/consensus.h> #include <consensus/merkle.h> @@ -845,9 +846,18 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws) return state.Invalid(TxValidationResult::TX_NOT_STANDARD, "bad-txns-too-many-sigops", strprintf("%d", nSigOpsCost)); - // No individual transactions are allowed below the min relay feerate and mempool min feerate except from - // disconnected blocks and transactions in a package. Package transactions will be checked using - // package feerate later. + // No individual transactions are allowed below the min relay feerate except from disconnected blocks. + // This requirement, unlike CheckFeeRate, cannot be bypassed using m_package_feerates because, + // while a tx could be package CPFP'd when entering the mempool, we do not have a DoS-resistant + // method of ensuring the tx remains bumped. For example, the fee-bumping child could disappear + // due to a replacement. + if (!bypass_limits && ws.m_modified_fees < m_pool.m_min_relay_feerate.GetFee(ws.m_vsize)) { + return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "min relay fee not met", + strprintf("%d < %d", ws.m_modified_fees, m_pool.m_min_relay_feerate.GetFee(ws.m_vsize))); + } + // No individual transactions are allowed below the mempool min feerate except from disconnected + // blocks and transactions in a package. Package transactions will be checked using package + // feerate later. if (!bypass_limits && !args.m_package_feerates && !CheckFeeRate(ws.m_vsize, ws.m_modified_fees, state)) return false; ws.m_iters_conflicting = m_pool.GetIterSet(ws.m_conflicts); @@ -1191,6 +1201,7 @@ bool MemPoolAccept::SubmitPackage(const ATMPArgs& args, std::vector<Workspace>& } else { all_submitted = false; ws.m_state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "mempool full"); + package_state.Invalid(PackageValidationResult::PCKG_TX, "transaction failed"); results.emplace(ws.m_ptx->GetWitnessHash(), MempoolAcceptResult::Failure(ws.m_state)); } } @@ -4931,7 +4942,6 @@ bool Chainstate::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size) } else { // Otherwise, flush state to disk and deallocate the in-memory coins map. ret = FlushStateToDisk(state, FlushStateMode::ALWAYS); - CoinsTip().ReallocateCache(); } return ret; } |