fix: reject invalid transactions at mempool entry with dry-run apply#620
Merged
Conversation
Transactions that pass well_formed() (ZK proofs/signatures) but fail apply() (guaranteed execution) were getting stuck in the mempool indefinitely. The soft cache was caching Ok(()) after well_formed() alone, so pool revalidation always saw success even though pre_dispatch kept rejecting the tx. Three changes to do_validate_transaction flow: - Remove soft cache write from get_verified_transaction so that do_validate_transaction is the sole owner of the soft cache - Add dry-run apply() in do_validate_transaction after well_formed(), only caching successes (failures are not cached) - Invalidate soft cache entry at start of do_validate_guaranteed_execution to force full re-validation after block authoring attempts
Contributor
justinfrevert
approved these changes
Feb 6, 2026
justinfrevert
left a comment
Contributor
There was a problem hiding this comment.
If it resolves the stuck tx issue for now, seems fine. We might want to come back and find a way to not run apply for every tx though.
12 tasks
gilescope
pushed a commit
that referenced
this pull request
Apr 8, 2026
* add multi-sig operations to integration tests * test: remove multisig confest removed: - multisig conftest not needed because it was handled in `set_governance_to_multisig` fixture * test(fix): xdist_group name * test(fix): restore governance to single key after module is finished * test: skip multisig if not configured * test: remove unnecesary docstring * test: fix incorrect cli parameters --------- Co-authored-by: Radosław Sporny <404@rspo.dev>
m2ux
added a commit
that referenced
this pull request
Apr 23, 2026
* add multi-sig operations to integration tests * test: remove multisig confest removed: - multisig conftest not needed because it was handled in `set_governance_to_multisig` fixture * test(fix): xdist_group name * test(fix): restore governance to single key after module is finished * test: skip multisig if not configured * test: remove unnecesary docstring * test: fix incorrect cli parameters --------- Co-authored-by: Radosław Sporny <404@rspo.dev> Signed-off-by: Mike Clay <mike.clay@shielded.io>
m2ux
added a commit
that referenced
this pull request
Apr 23, 2026
* add multi-sig operations to integration tests * test: remove multisig confest removed: - multisig conftest not needed because it was handled in `set_governance_to_multisig` fixture * test(fix): xdist_group name * test(fix): restore governance to single key after module is finished * test: skip multisig if not configured * test: remove unnecesary docstring * test: fix incorrect cli parameters --------- Co-authored-by: Radosław Sporny <404@rspo.dev> Signed-off-by: Mike Clay <mike.clay@shielded.io>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.








Overview
Identified by Christos - after merging of #608 , transactions would get stuck in the mempool and never enter a block:
Problem
Transactions that pass ZK proof/signature validation (
well_formed()) but whose guaranteed part would fail against the current ledger state get stuck in the mempool indefinitely.The root cause is a validation gap between pool admission and block authoring:
do_validate_transaction(pool entry/revalidation) only checkswell_formed()— ZK proofs and signatures — but not whether the guaranteed part can actually be applied to the current ledger stateget_verified_transactionwritesOk(())to the soft cache afterwell_formed()passes — so pool revalidation always sees a cached success, even thoughpre_dispatchkeeps rejecting the txpre_dispatchreject → soft cache hit → still "ready" → repeatSolution
Three targeted changes in
ledger/src/versions/common/mod.rs, all focused on makingdo_validate_transactionthe single owner of the soft cache:Remove soft cache write from
get_verified_transaction— the soft cache should only be written bydo_validate_transaction, which has full context (including the apply result) to decide what to cacheAdd dry-run
apply()indo_validate_transaction— afterwell_formed()passes, dry-run the transaction against current ledger state. Only cacheOk(())on success (SuccessorPartialSuccess). Failures are not cached, so the tx will be fully re-checked on next revalidationInvalidate soft cache on entering
do_validate_guaranteed_execution— always evict the soft cache entry when enteringpre_dispatch, regardless of outcome. This forces the pool to fully re-validate the transaction after any block authoring attemptFlow after fix
do_validate_transaction:well_formed()+apply()→ if both pass, cacheOk(())in soft cacheOk(())→ stays "ready"do_validate_guaranteed_execution(pre_dispatch):well_formed()+apply()against current state)🗹 TODO before merging
📌 Submission Checklist
🧪 Testing Evidence
Please describe any additional testing aside from CI:
🔱 Fork Strategy
Links