mempool: remove all subsequent tx in pkg on failure
What changed, and why it matters
This change tightens a safety check in Bitcoin Core's transaction memory pool (mempool) handling. When a group (package) of related transactions is submitted and one fails a final consensus check, the code now removes that failing transaction plus every transaction that comes after it in the package. The commit message calls it a 'belt-and-suspenders' fix to prevent the mempool from becoming internally inconsistent if a parent transaction fails but a child transaction does not. It is a defensive hardening patch rather than a confirmed exploitable bug.
Treat as a routine defensive fix. Review related package-submission logic and test coverage for parent/child consensus-failure scenarios. No emergency action is warranted based solely on this commit.
Security signals we found
Defensive hardening against mempool inconsistency
Potential inconsistent mempool state if parent fails consensus but child does not
Package transaction submission failure handling
No explicit vulnerability or exploit described in commit
Evidence from the diff
In src/validation.cpp, SubmitPackage previously removed only the single transaction whose ConsensusScriptChecks failed after PolicyScriptChecks had already succeeded. The patch moves the removal logic outside the error-message block and removes the first failing transaction and all subsequent transactions in the package. The stated concern is an inconsistent mempool state where a parent fails consensus validation but a child does not. The change uses the existing m_changeset mechanism to stage removals.
Changed components
src/validation.cppMemPoolAccept::SubmitPackagemempool package acceptanceInspect captured patch +3 / −1
diff --git a/src/validation.cpp b/src/validation.cpp
index fc15c26d..4cf38780 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -1264,7 +1264,9 @@ bool MemPoolAccept::SubmitPackage(const ATMPArgs& args, std::vector<Workspace>&
package_state.Invalid(PackageValidationResult::PCKG_MEMPOOL_ERROR,
strprintf("BUG! PolicyScriptChecks succeeded but ConsensusScriptChecks failed: %s",
ws.m_ptx->GetHash().ToString()));
- // Remove the transaction from the mempool.
+ }
+ // Remove first failing tx and all subsequent in package
+ if (!all_submitted) {
if (!m_subpackage.m_changeset) m_subpackage.m_changeset = m_pool.GetChangeSet();
m_subpackage.m_changeset->StageRemoval(m_pool.GetIter(ws.m_ptx->GetHash()).value());
}
Why this scored 39/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.