feat(node): spec-declared state-sync rpc-servers; hold STS while gate blocks plan#456
Conversation
… blocks plan Add SnapshotSource.rpcServers: a spec-declared witness set that replaces the controller-level canonical-syncer registry for that node, so self-serve chains (eng namespaces) can use state-sync bootstrap without per-chain platform config. Admission enforces the CometBFT floor (minItems=2), uniqueness (listType=set), and bare host:port shape; the gate keeps a live fail-closed floor that falls through to the registry path. Also hold initial StatefulSet creation while the state-sync gate suppresses the init plan: EnsureDataPVC is the only creator of the data PVC the pod mounts by claimName, so an STS created during the block stranded a Pending pod on a claim nothing creates (eng-yiming/yiming-migration-mock-4-rpc-1, 2026-07-08: StateSyncBlocked/NoSyncersConfigured with a pod unschedulable on a nonexistent PVC). Only initial creation is held — a Running node's STS keeps syncing through transient syncer-source errors. The NoSyncersConfigured message now names both remediations. New envtest suite exercises the admission rules against a real apiserver. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…comment Cross-review findings: the rpcServers field doc conflated light-client witnesses with p2p snapshot delivery, overstated what admission validation guarantees (shape only — chain membership, reachability, and snapshot existence are runtime concerns surfaced by the sidecar), and statefulset.go's impostor paragraph contradicted the actual Status.StatefulSet clearing in noderesource/sync.go. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PR SummaryMedium Risk Overview Pre-Running nodes no longer get an initial StatefulSet while Planner/docs and Reviewed by Cursor Bugbot for commit 8a70fde. Bugbot is set up for automated code reviews on this repo. Configure here. |
Summary
spec.fullNode.snapshot.rpcServers— a spec-declared CometBFT witness set that replaces the controller-level canonical-syncer registry for that node, so self-serve chains (eng namespaces) can use state-sync bootstrap without per-chain platform config. Admission enforces the CometBFT floor (minItems=2), uniqueness (listType=set), and barehost:portshape; the reconcile gate keeps a live fail-closed floor that falls through to the registry path (CRD-downgrade backstop).EnsureDataPVC(a plan task) is the sole creator of the data PVC the pod mounts by direct claimName, so an STS created during the block stranded a Pending pod on a claim nothing creates. The hold is create-only (StateSyncBlocksPlan && Status.StatefulSet == nil): Running nodes and existing STSes are never touched, so a transient registry blip cannot stall an image roll.NoSyncersConfiguredcondition message now names both remediations (registry entry or specrpcServers); new envtest suite exercises the admission rules against a real apiserver; fixed a stale impostor-branch comment instatefulset.gothat contradictednoderesource/sync.go.Motivating incident
eng-yiming/yiming-migration-mock-4-rpc-1 (2026-07-08): an RPC node added to a self-owned chain with
stateSync: {}fail-closed on the empty registry (StateSyncReady=False/NoSyncersConfigured, correct) — but the ungated STS had already created a pod that sat Pending forever ondata-...-rpc-1 not found, with the real cause buried in a SeiNode condition. Both halves are fixed: the config gap gets a self-serve field, and a blocked node now holds the STS so the only signal is the accurate one.Design decisions
minItems=2enforceable at admission. Changing to merge later is a breaking semantic change on a served field — route through a new API version.SnapshotSource, notStateSyncSource: s3-restore applies via CometBFT state-sync and verifies against the same witnesses, so both variants need it (same reasoning astrustPeriod).Review evidence
Cross-reviewed by five independent lenses (systems, kubernetes, sei-network as assigned dissenter, platform, idiomatic) — unanimous after a resolution round; ledger:
bdchatham-designs/designs/sei-k8s-controller-stack/xreview/feat-statesync-explicit-rpc-servers.md. The dissenter's headline objection (validators can't serve RPC witnesses) was empirically refuted against the live motivating chain (validator answers/statuson 26657).Accepted risk (tracked): a wrong-chain or dead spec-declared witness passes shape-only admission and fails at runtime in the sidecar — the sidecar does not yet assert the witness's chain-id. Eliminating fix is PLT-793 (seictl: chain-id assertion in trust-point queries + pad-to-1 hardening).
Rollout notes
config/defaultordering (Flux); skew windows fail closed to the registry.?ref=that includes this change.🤖 Generated with Claude Code