Skip to content

Feat: Single Sequencer#949

Open
tomatoishealthy wants to merge 18 commits intomainfrom
feat/sequencer-optimize
Open

Feat: Single Sequencer#949
tomatoishealthy wants to merge 18 commits intomainfrom
feat/sequencer-optimize

Conversation

@tomatoishealthy
Copy link
Copy Markdown
Contributor

No description provided.

@tomatoishealthy tomatoishealthy requested a review from a team as a code owner May 9, 2026 15:28
@tomatoishealthy tomatoishealthy requested review from twcctop and removed request for a team May 9, 2026 15:28
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 9, 2026

Warning

Rate limit exceeded

@tomatoishealthy has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 41 minutes and 1 second before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d59ad385-0201-4c2a-985e-59b8aa0370a2

📥 Commits

Reviewing files that changed from the base of the PR and between 58c70f9 and 8f4c5ee.

⛔ Files ignored due to path filters (10)
  • bindings/go.sum is excluded by !**/*.sum
  • contracts/go.sum is excluded by !**/*.sum
  • go.work is excluded by !**/*.work
  • go.work.sum is excluded by !**/*.sum
  • node/go.sum is excluded by !**/*.sum
  • ops/l2-genesis/go.sum is excluded by !**/*.sum
  • ops/tools/go.sum is excluded by !**/*.sum
  • oracle/go.sum is excluded by !**/*.sum
  • token-price-oracle/go.sum is excluded by !**/*.sum
  • tx-submitter/go.sum is excluded by !**/*.sum
📒 Files selected for processing (43)
  • Makefile
  • bindings/bindings/l1sequencer.go
  • bindings/go.mod
  • contracts/contracts/l1/L1Sequencer.sol
  • contracts/contracts/test/L1Sequencer.t.sol
  • contracts/contracts/test/base/L1SequencerBase.t.sol
  • contracts/deploy/022-SequencerInit.ts
  • contracts/go.mod
  • go-ethereum
  • node/cmd/node/main.go
  • node/core/executor.go
  • node/flags/flags.go
  • node/go.mod
  • node/hakeeper/block_fsm.go
  • node/hakeeper/block_payload.go
  • node/hakeeper/config.go
  • node/hakeeper/ha.toml.example
  • node/hakeeper/ha_service.go
  • node/hakeeper/leader_monitor.go
  • node/hakeeper/rpc/api.go
  • node/hakeeper/rpc/auth.go
  • node/hakeeper/rpc/auth_test.go
  • node/hakeeper/rpc/backend.go
  • node/hakeeper/rpc/client.go
  • node/hakeeper/rpc/server.go
  • node/hakeeper/rpc/types.go
  • node/l1sequencer/signer.go
  • node/l1sequencer/verifier.go
  • node/sequencer/tm_node.go
  • node/sync/syncer.go
  • node/types/retryable_client.go
  • node/types/retryable_client_test.go
  • ops/docker-sequencer-test/docker-compose.ha-override.yml
  • ops/docker-sequencer-test/docker-compose.override.yml
  • ops/docker-sequencer-test/run-ha-test.sh
  • ops/docker-sequencer-test/run-perf-test.sh
  • ops/docker-sequencer-test/run-test.sh
  • ops/docker/.env
  • ops/l2-genesis/go.mod
  • ops/tools/go.mod
  • oracle/go.mod
  • token-price-oracle/go.mod
  • tx-submitter/go.mod
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/sequencer-optimize

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

allen.wu and others added 18 commits May 9, 2026 23:42
- L1Sequencer.sol: sequencerHistory[], updateSequencer, getSequencerAt, initializeHistory
- Bindings: updated ABI for new contract interface
- SequencerVerifier: L1 history cache with interval cursor optimization
- Signer: simplified interface (removed IsActiveSequencer)
- 022-SequencerInit.ts: fixed initialize call (1 param instead of 2)
- Docker: added L1_SEQUENCER_CONTRACT env for all nodes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- run-test.sh: added build-malicious and p2p-test commands
- docker-compose.override.yml: malicious-geth-0 and malicious-node-0 services
- Tests: T-01~T-05 (active attacks) + T-06 (BlockSync pollution) + T-07 (resilience)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix grep -c multiline: use || true instead of || echo "0"
- Fix env var loss: malicious override must include full env list
- Swap approach: reuse synced sentry instead of fresh malicious container
- Uncomment CONSENSUS_SWITCH_HEIGHT for V2 mode activation
- Add SEQUENCER_PRIVATE_KEY to node-0 override

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use staking key (0xd998...) as SEQUENCER_PRIVATE_KEY for node-0
- Add initializeHistory() call in setup to register sequencer on L1
- Fixes "no sequencer record" error in V2 mode

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- T-06: use blocksync-forge (blocksync/reactor.go) instead of sync-forge
  (broadcast_reactor.go) - targets the actual V1 vulnerability path
- T-06: stop node-3 to create gap, restart to trigger BlockSync
- Phase 0: explicit checks for V2 mode, signer, and switch height
- T-04: use futureHeight (currentHeight+10000) for deterministic unsolicited test
- Separate log files per phase to prevent cross-contamination

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add L1Sequencer.t.sol: 27 Foundry tests covering initialize,
  initializeHistory, updateSequencer, getSequencerAt binary search
  edge cases, and access control
- Regenerate l1sequencer.go with abigen (bytecode now matches current
  contract with sequencerHistory[], binary search, etc.)
- Update verifier.go: L1SequencerHistoryRecord -> L1SequencerSequencerRecord
- Add exponential backoff retry (10s -> 20s -> ... -> 5min) when initial
  history load fails, instead of waiting full 5 minutes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Avoids stuttering in abigen output (L1SequencerSequencerRecord ->
L1SequencerHistoryRecord). No ABI/storage layout change.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…om L1 contract

Unify the upgrade height source: instead of a CLI flag / env var, the
verifier now sets upgrade.UpgradeBlockHeight from the first history
record fetched from the L1Sequencer contract.

- node/l1sequencer/verifier.go: call SetUpgradeBlockHeight on first
  successful history load (prev==0)
- node/cmd/node/main.go: remove ConsensusSwitchHeight flag read;
  require L1 Sequencer contract address
- node/flags/flags.go: delete ConsensusSwitchHeight flag definition
- docker-compose.override.yml: remove 5× MORPH_NODE_CONSENSUS_SWITCH_HEIGHT
- run-test.sh: remove set_upgrade_height function, add wait_for_l1_finalized
  to ensure L1 contract data is finalized before L2 nodes start

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
These env var overrides (DEPOSIT_CONTRACT_ADDRESS, SYNC_START_HEIGHT)
and the malicious_geth_data volume should be managed via overlay/override
files, not by modifying the base compose file directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ncer

Add hakeeper module implementing a 3-node Raft cluster for sequencer HA.
The HA cluster provides automatic leader election, block replication, and
failover without changing the on-chain sequencer identity.

node/hakeeper/:
- HAService: wraps hashicorp/raft, implements SequencerHA interface
- Config: layered loading (defaults -> TOML file -> CLI flags -> resolve -> validate)
  supports auto-detection of server_id (hostname) and advertised_addr (local IP)
- BlockFSM: Raft FSM for block replication; onApplied callback drives geth apply
- leaderMonitor: gates block production behind Barrier to ensure log catch-up
- rpc/: JSON-RPC admin API (ha_leader, ha_clusterMembership, ha_addServerAsVoter,
  ha_removeServer, ha_transferLeader, ha_transferLeaderToServer)
  with HTTP middleware token auth on write operations

node/flags/flags.go:
- New flags: --ha.enabled, --ha.config, --ha.bootstrap, --ha.join,
  --ha.server-id, --ha.advertised-addr, --ha.rpc-token

node/cmd/node/main.go:
- initHAService(): init HA from flags/config when --ha.enabled is set
- Fix typed-nil interface bug: pass untyped nil when HA is disabled

node/sequencer/tm_node.go:
- Pass HA service to tendermint node setup

node/go.mod:
- Add hashicorp/raft v1.7.1, raft-boltdb/v2

ops/docker-sequencer-test/:
- docker-compose.ha-override.yml: 3-node Raft cluster config for devnet
- run-ha-test.sh: 29-case integration test suite (config, cluster, block
  production, failover, admin API, lifecycle)
- run-perf-test.sh: performance test harness

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wire up the new engine_newL2BlockV2 API for reorg support:

- Executor.ApplyBlockV2 now returns (applied bool, err error) matching
  the updated L2Node interface; detects idempotent skips and reorgs
  using BlockNumber + BlockByNumber checks before calling NewL2BlockV2
- RetryableClient.NewL2BlockV2 wraps the new authclient method with
  exponential backoff retry; excludes WrongBlockNumberError and
  ParentNotFoundError from retry (permanent errors)
- RetryableClient.AssembleL2BlockV2 added for parent-hash-based block
  assembly

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add BlockHashMismatchError and InvalidNextL1MsgIndexError to the
retryableError() exclusion list so the executor stops re-sending
invalid payloads back to geth.

Made-with: Cursor
… not in PBFT validator set

- Add Syncer()/SetSyncer() accessors to Executor for explicit syncer wiring
- Start L1 syncer eagerly in main.go for separated-deployment / HA sequencers
  that are not PBFT validators (lazy-init path never fires for them)
- Guard Syncer.Start() with atomic flag to prevent duplicate goroutines

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Increase blockCh buffer from 200 to 1000 to reduce drops under load.
- Panic on nil onApplied callback in BlockFSM.Apply: this can only happen
  due to a programmer error (forgot to wire SetOnBlockApplied) and would
  otherwise silently succeed on the leader while followers diverge.
- gofmt: realign one-line method bodies.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- go-ethereum: v0.0.0-20260508105911-56deb7072ae4
- tendermint: v0.0.0-20260508065906-9e56b04da3c8

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add explicit replace directives in every go.mod to override MVS,
because token-price-oracle indirectly required v1.10.14-..., which
caused all workspace modules to resolve to the older version and
miss new APIs (NewL2BlockV2, AssembleL2BlockV2, SetBlockTags,
MorphTxType, updated AssembleL2Block/NewL2Block signatures).

Drop the local-path replace block from go.work so the pinned
pseudo-version is actually used.

Follow-up: investigate the indirect dep that requires v1.10.14
and bump it so these per-module replaces can be removed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tomatoishealthy tomatoishealthy force-pushed the feat/sequencer-optimize branch from 650d038 to 8f4c5ee Compare May 9, 2026 15:46
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