Skip to content

Validator Voluntary Exit Message Builder with Offline Cold Storage Signing #52

Description

@JamesEjembi

Problem Statement / Feature Objective

Voluntary exits require an unsigned exit message (containing validator index, epoch, and signature domain) to be signed by the withdrawal key – often held in cold storage or an air-gapped machine. Operators need a guided workflow that: constructs the unsigned exit message, presents it as a QR-encoded hex blob for air-gapped signing, accepts the signed result back, and broadcasts it to the beacon chain. The workflow must prevent accidental exits via a mandatory 3-step confirmation with cooldown timers.

Technical Invariants & Bounds

  • Unsigned exit message format: SSZ(VoluntaryExit{epoch, validator_index}) signed with domain DOMAIN_VOLUNTARY_EXIT
  • QR encoding must use binary QR (not alphanumeric) to minimize scan failures – max payload size 2,953 bytes (Version 40 QR with medium error correction)
  • Cooldown timer: after initiating exit for a validator, a 60-second "confirm cooldown" must elapse before broadcast is enabled
  • 3-step confirmation: (1) Initiate → (2) Sign (accept signed blob) → (3) Broadcast
  • Rate limiting: max 4 validator exits per epoch per operator account
  • All unsigned messages must be logged with SHA-256 hash to a signed audit trail in IndexedDB
  • Abort: user can cancel within the cooldown window; after broadcast, exit is irreversible (clear warning displayed)

Codebase Navigation Guide

  • src/hooks/useVoluntaryExit.ts – main workflow hook
  • src/components/validators/ExitWorkflowWizard.tsx – multi-step wizard UI
  • src/utils/sszSerialization.ts – SSZ encoding utilities for consensus types
  • src/utils/qrEncoder.ts – binary QR generation using qrcode library
  • src/services/beaconChainService.ts – extend with postVoluntaryExit method
  • src/store/exitSlice.ts – exit workflow state management

Implementation Blueprint

  1. Create src/utils/exitMessageBuilder.ts – builds the SSZ-encoded VoluntaryExit message from validator index + current epoch (fetched from /eth/v1/beacon/genesis)
  2. Implement src/utils/qrEncoder.ts – wraps qrcode binary mode to encode the unsigned exit hex as a QR canvas; validates payload fits Version 40 limits
  3. Build src/hooks/useVoluntaryExit.ts – manages workflow steps, 60s cooldown timer, abort logic, 4-per-epoch rate limiter, and audit log
  4. Create src/components/validators/ExitWorkflowWizard.tsx – 3-step wizard:
    • Step 1: Validator selection + unsigned message display (QR + hex text) + cooldown timer start
    • Step 2: Signed blob input (QR scanner via react-qr-reader or paste hex) + signature validation
    • Step 3: Broadcast confirmation with final warning + rate limit check
  5. Implement IndexedDB audit log in src/services/exitAuditStore.ts – stores unsinged_msg_hash, timestamp, validator_index, broadcast_status
  6. Mount in ValidatorDetail.tsx accessible via "Voluntary Exit" button in the validator actions toolbar

Metadata

Metadata

Assignees

Labels

Complexity: HardcoreExtremely difficult, high-complexity engineering taskGrantFox OSSIssue tracked in GrantFox OSSLayer: Core-EngineCore engine layerMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official CampaignType: Core-ArchitectureCore architecture design and structural concern

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions