Feat: Single Sequencer #36
Open
tomatoishealthy wants to merge 9 commits into
Open
Conversation
- StateV2: roleCheckRoutine for dynamic role detection, SequencerHA interface - ApplyBlock: full mutex serialization + idempotent height check - VerifyBlockSignature: fail-close, all V2 blocks must have valid signatures - SignatureStore: independent block signature persistence (LevelDB) - BroadcastReactor: unified signature verification, SyncReq tracking, HasSigner filter - Interfaces: SequencerVerifier, Signer, SequencerHA Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove SequencerAddress, SetSequencerAddress, IsSequencerAddress, RecoverBlockV2Signer from types/block_v2.go (unused since SequencerVerifier) - Remove duplicate BlockV2ToProto/ProtoToBlockV2 from broadcast_reactor.go, use types.BlockV2ToProto instead - Clean up unused imports (fmt, crypto, math/big, seqproto) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
…ror) Reorg detection and idempotent checks are now handled in the Executor layer (morph node), not in StateV2: - L2Node.ApplyBlockV2 interface returns (applied bool, err error) so callers can distinguish real applies from idempotent skips - StateV2.ApplyBlock only updates latestBlock when applied=true, preventing state regression during HA Raft log replay - Remove reorg detection logic and common.Hash import from StateV2 (reorg log now emitted by Executor.ApplyBlockV2) - MockL2Node tracks maxAppliedHeight for idempotent behavior in tests - Remove mock reorg code (startMockReorgRoutine, triggerMockReorg) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bind the sequencer signature to the block body by rehashing BlockV2 fields in VerifyBlockSignature and rejecting on mismatch. Companion changes in go-ethereum and morph/node. Made-with: Cursor
…zation - Ban mechanism: in-memory bannedPeers map (10-min TTL) + isBanned check in AddPeer - Rate limiter: per-peer token bucket (50 req/s, burst 250) protecting L2 geth RPC - Height validation: reject blocks outside [localHeight-MaxPendingHeightBehind, localHeight+MaxPendingHeightAhead] - Timeout-ban: removeTimeoutPeers bans peers that declare height but never respond (20s TTL) - Error classification: ErrInvalidSignature (ban) vs ErrVerifierUnavailable (local problem, no ban) - Startup gate: routinesStarted atomic.Bool replaces waitSync; Receive() silently drops until routines start - OnBlockRequest sanity check: reject Height<=0 or Height>localHeight without touching cache/RPC - Decode failures in broadcast/sync handlers now trigger banPeer Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Audit finding M-02: switchToSequencerMode used time.Sleep(100ms) as a heuristic to wait for finalizeCommit to return before stopping the consensus reactor. This is a non-deterministic synchronization that may fail under high load or GC pauses. Changes: 1. consensus/state.go: in finalizeCommit's upgrade branch, call cs.Stop() BEFORE cs.onUpgrade(). Stop() closes the BaseService quit channel synchronously, which establishes the happens-before relationship that any goroutine started by onUpgrade can rely on. 2. node/node.go: replace time.Sleep(100ms) with consensusState.Wait(). Wait() blocks until cs.done is closed (the very last action of receiveRoutine), giving a deterministic synchronization point that replaces the time-based heuristic. 3. consensus/reactor.go: remove unused StopForUpgrade method. It had no callers and bypassed BaseService.Stop's atomic stopped flag, which would cause OnStop to be invoked twice during node shutdown. Verified via Docker integration test on feat/sequencer-optimize: - PBFT → V2 upgrade flow passes - HA cluster forms correctly (35/35 HA tests pass) - P2P security tests pass Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two indirect deps were missing from go.mod: - github.com/VictoriaMetrics/fastcache v1.12.1 - github.com/prometheus/tsdb v0.7.1 These are pulled in transitively. `go build` was failing with 'updates to go.mod needed'. `go mod tidy` fixes it without changing direct dependencies. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Allow operators to whitelist trusted upstream peers (sequencer / sentry / boot nodes) so that fullnodes do not accidentally ban them on transient faults. Whitelist is configured via the existing [p2p].persistent_peers setting — no new config option introduced. broadcast_reactor.go: banPeer now short-circuits for peers where Peer.IsPersistent() is true. The peer is still disconnected via Switch.StopPeerForError so connection state (sync requests, gossip cache, rate limiter) is fully reset by the RemovePeer callback chain. The peer is NOT added to bannedPeers, so the Switch's automatic reconnect will pass AddPeer's isBanned gate and the link recovers immediately instead of being unreachable for 10 minutes. A new log prefix '[WHITELIST_ALARM]' is emitted on each exemption so log-aggregation systems can alert when a whitelisted peer is misbehaving. signature_store.go: Add Close() method delegating to the underlying tm-db. Closes a code consistency gap where blockStore and stateStore were closed on shutdown but sigStore was not. node.go: Invoke sigStore.Close() in OnStop alongside blockStore and stateStore. Tests: TestBanPeer_PersistentPeerSkipsBanList — core invariant TestBanPeer_NonPersistentPeerEntersBanList — regression guard TestBanPeer_PersistentPeerAddPeerNotRejected — full reconnect cycle Note: the value of this exemption is verified end-to-end by an integration test on a separate disconnect-test branch (see ops/docker-sequencer-test follow-up). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
PR checklist
CHANGELOG_PENDING.mdupdated, or no changelog entry neededdocs/) and code comments, or nodocumentation updates needed