Fix: sync sequencer info after state-prune replay#3941
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
There was a problem hiding this comment.
Pull request overview
This PR fixes a critical issue where sequencer_info.last_order could remain stale (potentially 0) after state-prune replay when no trimming was needed. The fix ensures sequencer_info is always synchronized to the target order, and adds a consistency verification between startup_info and sequencer_info.
Changes:
- Refactored
trim_output_storeto always refresh sequencer_info before checking if trimming is needed, eliminating the gap that left last_order stale - Added
verify_startup_sequencer_consistencyfunction to validate that sequencer_info.last_order matches the expected order after replay - Positioned the consistency check after trim/refresh operations to catch any synchronization issues
| output_store: &MoveOSStore, | ||
| expected_order: u64, | ||
| ) -> Result<()> { | ||
| let output_rooch_store = self.load_output_rooch_store(output_store)?; |
There was a problem hiding this comment.
The verify_startup_sequencer_consistency function loads output_rooch_store again, but this is already loaded in trim_output_store at line 480. Consider passing output_rooch_store as a parameter to avoid redundant database initialization, which can be expensive.
| sequencer_info.last_order | ||
| )); | ||
| } | ||
|
|
There was a problem hiding this comment.
The verification function only checks that sequencer_info.last_order matches expected_order, but doesn't verify consistency between startup_info and sequencer_info state roots or transaction accumulator info. Consider adding a check to ensure the state_root in startup_info corresponds to the transaction at sequencer_info.last_order, to provide more comprehensive consistency verification.
| // Verify that the startup state root is consistent with the sequencer progress. | |
| // For genesis (order 0), the startup state root must be the canonical genesis state root. | |
| if sequencer_info.last_order == 0 { | |
| if startup_info.state_root != GENESIS_STATE_ROOT { | |
| return Err(anyhow::anyhow!( | |
| "Startup info inconsistency: expected genesis state_root for order 0, got {:x}", | |
| startup_info.state_root | |
| )); | |
| } | |
| } else { | |
| // For non-genesis orders, the startup state root must not be the genesis state root. | |
| if startup_info.state_root == GENESIS_STATE_ROOT { | |
| return Err(anyhow::anyhow!( | |
| "Startup info inconsistency: non-zero order {} has genesis state_root {:x}", | |
| sequencer_info.last_order, | |
| startup_info.state_root | |
| )); | |
| } | |
| } |
|
Docker images for this PR are available:
Pull commands:
|
Summary
Testing