Skip to content

feat: SequencerHA interface + StateV2 dynamic block interval#32

Open
tomatoishealthy wants to merge 1 commit intofeat/p2p-broadcast-validationfrom
feat/sequencer-ha-v2
Open

feat: SequencerHA interface + StateV2 dynamic block interval#32
tomatoishealthy wants to merge 1 commit intofeat/p2p-broadcast-validationfrom
feat/sequencer-ha-v2

Conversation

@tomatoishealthy
Copy link
Copy Markdown

Summary

  • Introduce SequencerHA interface (sequencer/interfaces.go) abstracting the Raft cluster for StateV2. Methods: Start, Stop, IsLeader, Join, Commit, Subscribe, SetOnBlockApplied.
  • Refactor StateV2 block production with a dynamic interval strategy: fastTicker (300ms) polls txpool via assembleBlock and commits immediately when transactions are found; slowTimer (3s) produces empty blocks as a chain-liveness fallback.
  • Split produceBlock into assembleBlock (read-only block assembly, safe to call and discard) and commitBlock (sign + Raft commit or local apply + broadcast).
  • Add HA path in commitBlock: leader calls ha.Commit for Raft replication; FSM callback handles ApplyBlock + SaveSignature for all nodes.
  • ApplyBlock: reorg detection, idempotent skip (same block.Number + same hash), signature enforcement.
  • node/node.go: accept SequencerHA parameter and inject SetOnBlockApplied callback.
  • Remove blockInterval from NewStateV2 constructor; use package-level constants BlockInterval (3s) and FastBlockInterval (300ms).

Test plan

  • go test ./sequencer/... -v — 37 tests pass (block_cache + state_v2)
  • HA integration tests pass in docker-sequencer-test: run-ha-test.sh test (29/29)
  • Dynamic block interval verified on devnet: empty blocks at ~3s, tx blocks at <1s

🤖 Generated with Claude Code

SequencerHA interface (sequencer/interfaces.go):
- Start/Stop/IsLeader/Join/Commit/Subscribe/SetOnBlockApplied
- Abstracts Raft cluster for StateV2 block production

StateV2 changes (sequencer/state_v2.go):
- Dynamic block interval: fastTicker (300ms) polls txpool, slowTimer (3s)
  produces empty blocks as fallback for chain liveness
- Split produceBlock into assembleBlock + commitBlock for clean separation
  of block assembly (read-only) vs signing+committing (side-effecting)
- HA path: signBlock -> ha.Commit (Raft replication, FSM handles apply)
- Non-HA path: signBlock -> ApplyBlock -> broadcastCh
- ApplyBlock: reorg detection + idempotent skip + signature enforcement
- Remove blockInterval constructor parameter, use package-level constants

node/node.go:
- Accept SequencerHA parameter, inject SetOnBlockApplied callback

Test fixes:
- Add Start/Stop/SetOnBlockApplied to mockSequencerHA
- Add Signature field to ApplyBlock test blocks (signature enforcement)
- Fix RollbackTo_All assertion (count should be 0, not 1)
- Remove blockInterval parameter from all NewStateV2 test calls

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tomatoishealthy tomatoishealthy requested a review from a team as a code owner April 9, 2026 06:02
@tomatoishealthy tomatoishealthy requested review from SecurityLife and removed request for a team April 9, 2026 06:02
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.

1 participant