Skip to content

Conversation

@karlem
Copy link
Contributor

@karlem karlem commented Oct 28, 2025

Closes #1441 and #1442


Note

High Risk
Touches consensus-critical topdown finality, genesis bootstrapping, and on-chain F3 light client state encoding; misconfiguration or state transition bugs could stall syncing or lead to incorrect finality/proof handling.

Overview
Enables an F3 proof-based topdown finality path alongside legacy vote-based topdown, with startup now selecting mode based on config+genesis consistency and bootstrapping a persistent proof cache + optional proof generator service.

Updates the f3-light-client actor to store the power table in a HAMT (exposing power_table_root), track processed_instance_id with monotonic/skip guards, and adjust constructor/update/get APIs and tests accordingly. Genesis-from-parent now fetches the F3 certificate to derive base_epoch + base_epoch_eth_block_hash, and parses power values as big integers (encoded big-endian bytes) instead of u64.

Adds fendermint_vm_evm_event_utils and a new interpreter event_extraction module to decode Solidity event proofs (NewTopDownMessage, NewPowerChangeRequest) from proof bundles using shared helpers; also refactors node topdown startup into service/topdown.rs, expands settings/default config docs for F3, and updates dependencies/lockfile to include new crates.

Written by Cursor Bugbot for commit 9d26e91. This will update automatically on new commits. Configure here.

@karlem karlem changed the title feat: init lifecycle feat: F3 e2e lifecycle Oct 29, 2025
@karlem karlem force-pushed the f3-lifecycle branch 2 times, most recently from 91db005 to cbce51c Compare November 4, 2025 17:20
Base automatically changed from f3-proofs-cache to main December 18, 2025 16:15
@karlem karlem marked this pull request as ready for review January 16, 2026 19:52
@karlem karlem requested a review from a team as a code owner January 16, 2026 19:52
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Comment on lines +303 to +304
//
// Note: the first epoch proven in a certificate does not have a previous cursor.

Choose a reason for hiding this comment

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

We should be able to initialize the cursor from the base tipset's storage commitment (used only as parent here), which is the same as the last tipset in the previous cert (used as child there). WDYT?

Choose a reason for hiding this comment

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

As a workaround, maybe we could fetch parent tipsets (which are not very useful anyway) right in generate_proof_for_epoch, call it for the base tipset, get the nonces from the resulting proof bundle and discard the proof. Perhaps, we can do this only once and then maintain the cursor in ProofGeneratorService struct.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the best way here is to store it on L2 ledger...

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.

F3 topdown: Proof Verification & Completeness Enforcement

3 participants