Simplex: Find last non-simplex block - #5783
Draft
yacovm wants to merge 1 commit into
Draft
Conversation
Simplex can be activated for the first time either on top of a genesis block (new L1), or on top of a snowman block built by proposerVM (migration from snowman to Simplex). (And in the future, via state-sync assisted boostrapping). In any of the above cases, Simplex needs to identity the last block that is not a Simplex block, in order for Simplex to know: 1. What is the next sequence number / block height to build on (to continue from the next sequence where snowman left off) 2. Which previous block hash to point to 3. What is the P-chain height that the Simplex L1 starts with, which is encoded by the proposerVM and not by Simplex. This commit adds a function - locateLastNonSimplexBlock() which given the genesis block, the proposerVM, the DB simplex stores finalizations in, and the number of blocks in the L1 chain, returns the last non-simplex block, if applicable. Signed-off-by: Yacov Manevich <yacov.manevich@avalabs.org>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a helper to identify the last pre-Simplex (non-Simplex) block by combining proposerVM height lookups with a DB-backed binary search over stored Simplex finalizations. This supports first-time Simplex activation on a fresh chain, on top of an existing Snowman chain (migration), and scenarios where historical proposerVM blocks may be missing (e.g., state-sync windows).
Changes:
- Add
locateLastNonSimplexBlockand supporting helpers to detect whether the chain tip is pre-Simplex and, if not, find the first Simplex-accepted block viasort.Searchover finalization keys. - Add comprehensive unit tests covering activation positions, missing proposerVM history, DB failures, and unexpected proposerVM errors.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
simplex/storage.go |
Introduces locateLastNonSimplexBlock with helpers to find the first Simplex finalization and return the preceding non-Simplex block when retrievable. |
simplex/storage_test.go |
Adds unit tests for the locator logic across expected edge cases and error paths. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
yacovm
marked this pull request as draft
August 7, 2026 10:42
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.
Why this should be merged
Simplex can be activated for the first time either on top of a genesis block (new L1), or on top of a snowman block built by proposerVM (migration from snowman to Simplex).
(And in the future, via state-sync assisted boostrapping).
In any of the above cases, Simplex needs to identity the last block that is not a Simplex block, in order for Simplex to know:
How this works
This commit adds a function - locateLastNonSimplexBlock() which given the genesis block, the proposerVM, the DB simplex stores finalizations in, and the number of blocks in the L1 chain, returns the last non-simplex block, if applicable.
The function performs a binary search for the simplex block with the lowest sequence, and returns the block before it.
How this was tested
unit tests are included.
Need to be documented in RELEASES.md?