diff --git a/src/txmempool.cpp b/src/txmempool.cpp index d3221b3cc60..ecba5ca3e2c 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -606,6 +606,7 @@ void CTxMemPool::removeRecursive(const CTransaction &origTx, MemPoolRemovalReaso { // Remove transaction from memory pool AssertLockHeld(cs); + Assume(!m_have_changeset); setEntries txToRemove; txiter origit = mapTx.find(origTx.GetHash()); if (origit != mapTx.end()) { @@ -637,6 +638,7 @@ void CTxMemPool::removeForReorg(CChain& chain, std::function check // Remove transactions spending a coinbase which are now immature and no-longer-final transactions AssertLockHeld(cs); AssertLockHeld(::cs_main); + Assume(!m_have_changeset); setEntries txToRemove; for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { @@ -675,6 +677,7 @@ void CTxMemPool::removeConflicts(const CTransaction &tx) void CTxMemPool::removeForBlock(const std::vector& vtx, unsigned int nBlockHeight) { AssertLockHeld(cs); + Assume(!m_have_changeset); std::vector txs_removed_for_block; txs_removed_for_block.reserve(vtx.size()); for (const auto& tx : vtx) @@ -1093,6 +1096,7 @@ void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants, MemPool int CTxMemPool::Expire(std::chrono::seconds time) { AssertLockHeld(cs); + Assume(!m_have_changeset); indexed_transaction_set::index::type::iterator it = mapTx.get().begin(); setEntries toremove; while (it != mapTx.get().end() && it->GetTime() < time) { @@ -1163,6 +1167,7 @@ void CTxMemPool::trackPackageRemoved(const CFeeRate& rate) { void CTxMemPool::TrimToSize(size_t sizelimit, std::vector* pvNoSpendsRemaining) { AssertLockHeld(cs); + Assume(!m_have_changeset); unsigned nTxnRemoved = 0; CFeeRate maxFeeRateRemoved(0); diff --git a/src/validation.cpp b/src/validation.cpp index d8b21ba282c..8adc76d72cc 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1820,6 +1820,11 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptPackage(const Package& package, AcceptSubPackage(txns_package_eval, args); PackageValidationState& package_state_final = multi_submission_result.m_state; + // This is invoked by AcceptSubPackage() already, so this is just here for + // clarity (since it's not permitted to invoke LimitMempoolSize() while a + // changeset is outstanding). + ClearSubPackageState(); + // Make sure we haven't exceeded max mempool size. // Package transactions that were submitted to mempool or already in mempool may be evicted. LimitMempoolSize(m_pool, m_active_chainstate.CoinsTip());