Skip to content

fix: mempool occasional panics when store is ahead by a block#1984

Merged
Mirko-von-Leipzig merged 8 commits intomainfrom
mirko/fix-mempool-panic
Apr 24, 2026
Merged

fix: mempool occasional panics when store is ahead by a block#1984
Mirko-von-Leipzig merged 8 commits intomainfrom
mirko/fix-mempool-panic

Conversation

@Mirko-von-Leipzig
Copy link
Copy Markdown
Collaborator

@Mirko-von-Leipzig Mirko-von-Leipzig commented Apr 22, 2026

This PR fixes an occasional panic when submitting a transaction or batch to the mempool.

The panic is handled correctly, that is, the mempool is not corrupted and continues to function. However, on v0.14 I've observed the panic unwinding holding onto the mempool lock for several seconds, making this more of a priority performance fix.

The bug occurs due to a race condition between a block being committed in the store and the mempool. A block first lands in the store, which means incoming transactions can get authenticated against store.chain_tip, while mempool.chain_tip = store.chain_tip - 1. The mempool then panics since its being given "bad" data from a trusted source.

This PR fixes this issue by having the mempool consider the current pending block as its chain tip, instead of only the latest committed block. This fixes the above issue, and also more correctly models things imo.

Fixes #1856


On a separate note, this does highlight that we should consider alternatives to a global mempool mutex.

@Mirko-von-Leipzig Mirko-von-Leipzig marked this pull request as ready for review April 22, 2026 15:20
Copy link
Copy Markdown
Collaborator

@igamigo igamigo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Left just a couple of minor comments. I think this does change the semantics of add_transaction and add_user_batch minimally, so I wonder if it's worth updating the comments/docs. For instance:

// Submits proven transaction to the Miden network. Returns the node's current block height.
rpc SubmitProvenTransaction(transaction.ProvenTransaction) returns (blockchain.BlockNumber) {}

now may return a block number that has not been committed yet (and may be reverted, etc.). The alternative is to roll back the return values in those functions, but I think in any case the returned value is more useful now (originally it was meant to signal, e.g. after which block number your note may be created).

this does highlight that we should consider alternatives to a global mempool mutex.

Agreed

Comment thread crates/block-producer/src/mempool/mod.rs Outdated
Comment thread crates/block-producer/src/mempool/mod.rs
///
/// This reflects the latest committed block that the block producer is aware of.
/// This includes the block currently being built, if any.
pub fn chain_tip(&self) -> BlockNumber {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we may want to rename this. Reading the code, some places still use self.chain_tip and some others have moved to self.chain_tip(), so the difference is not immediately obvious to the reader. Or maybe the field itself could be renamed (committed_chain_tip?)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. I think renaming the field is a great idea, thank you!

Copy link
Copy Markdown
Collaborator Author

@Mirko-von-Leipzig Mirko-von-Leipzig Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@igamigo on the point of the RPC now returning the pending block height.. are you saying that's okay? This was an unintended side effect for me which I am going to revert.

But it sounds like you're in favor of it, or okay with it? My main concern would be that its possible this block does not become committed.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I went back and forth, but I think we want to remove this as well. As I said, that return value is supposed to be a hint for clients to know after which block their transaction would be committed (and so, when output notes would be created in the chain). Since that block number may not be committed, it may not be always accurate (ie we may return block 5 but it may turn out that the transaction we are submitting is committed in block 5).

@bobbinth
Copy link
Copy Markdown
Contributor

now may return a block number that has not been committed yet (and may be reverted, etc.). The alternative is to roll back the return values in those functions, but I think in any case the returned value is more useful now (originally it was meant to signal, e.g. after which block number your note may be created).

I would keep returning the latest committed block number - this way, there should be no ambiguity about whether we get latest committed or the upcoming block number. The client can then make adjustments (if any needed) to estimate which block the transaction is going to land in.

@Mirko-von-Leipzig
Copy link
Copy Markdown
Collaborator Author

now may return a block number that has not been committed yet (and may be reverted, etc.). The alternative is to roll back the return values in those functions, but I think in any case the returned value is more useful now (originally it was meant to signal, e.g. after which block number your note may be created).

I would keep returning the latest committed block number - this way, there should be no ambiguity about whether we get latest committed or the upcoming block number. The client can then make adjustments (if any needed) to estimate which block the transaction is going to land in.

I've reverted to this behaviour.

@Mirko-von-Leipzig Mirko-von-Leipzig merged commit 9fe7ec4 into main Apr 24, 2026
18 checks passed
@Mirko-von-Leipzig Mirko-von-Leipzig deleted the mirko/fix-mempool-panic branch April 24, 2026 08:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants