Skip to content

canonical_beacon_validators: store the real API value (FAR_FUTURE_EPOCH/0) instead of NULL#863

Merged
samcm merged 1 commit into
masterfrom
feat/canonical-validators-non-nullable
Jun 26, 2026
Merged

canonical_beacon_validators: store the real API value (FAR_FUTURE_EPOCH/0) instead of NULL#863
samcm merged 1 commit into
masterfrom
feat/canonical-validators-non-nullable

Conversation

@samcm

@samcm samcm commented Jun 26, 2026

Copy link
Copy Markdown
Member

The route's setOptionalEpoch mapped both 0 and FAR_FUTURE_EPOCH (2^64-1) to NULL and nulled a zero balance — discarding values the beacon API returns verbatim. The Validator schema marks these fields required and documents 'FAR_FUTURE_EPOCH if not exited/activated', so NULL was conflating real data with absence and making the column ambiguous.

No schema migration. canonical_beacon_validators is ~350B rows (≈2.3M validators × every epoch); a Nullable→UInt64 type-change mutation would rewrite the whole table for no benefit. Instead the columns stay Nullable(UInt64) and the flatten always writes the exact uint64 the API reports as a set value (balance 0, genesis epoch 0, and FAR_FUTURE_EPOCH all preserved). New rows are unambiguous immediately; historical NULLs remain losslessly recoverable by status (pending → FAR_FUTURE, else genesis 0) and can be backfilled later with a scoped ALTER UPDATE if wanted.

Also makes the validators routes strict (builds on #862's halt mechanism): halt on a missing index/status/data/slashed, and on empty pubkey/withdrawal_credentials in the fanout tables, instead of silently skipping or empty-filling.

The route's setOptionalEpoch mapped both 0 and FAR_FUTURE_EPOCH (2^64-1) to
NULL and nulled a zero balance — discarding values the beacon API returns
verbatim (the Validator spec marks these required and documents
'FAR_FUTURE_EPOCH if not exited/activated'). Conflating real data with
absence made NULL ambiguous.

Keep the columns Nullable(UInt64) (NO type migration — the table is ~350B
rows; a type-change mutation would be huge and pointless) and instead always
write the exact uint64 the API reports as a set value: balance 0, genesis
epoch 0, and FAR_FUTURE_EPOCH are all preserved. Halt (route.ErrInvalidEvent)
on a missing index/status/data/slashed, and on empty pubkey/withdrawal_credentials
in the fanout tables, rather than skipping or empty-filling. New rows are
unambiguous immediately; historical NULLs stay losslessly recoverable by
status and can be backfilled later if desired.
@samcm samcm force-pushed the feat/canonical-validators-non-nullable branch from 92e7411 to 4a4cf42 Compare June 26, 2026 06:31
@samcm samcm changed the title canonical_beacon_validators: Nullable→UInt64 + raw FAR_FUTURE_EPOCH, strict validate canonical_beacon_validators: store the real API value (FAR_FUTURE_EPOCH/0) instead of NULL Jun 26, 2026
@samcm samcm merged commit dc96b0b into master Jun 26, 2026
6 checks passed
@samcm samcm deleted the feat/canonical-validators-non-nullable branch June 26, 2026 06:42
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