Follow-up from #30.
Three methods compute epoch fields from a hardcoded mainnet schedule (DEFAULT_SLOTS_PER_EPOCH = 432000, warmup off), so on any cluster whose genesis enables warmup they're silently wrong. Example from that thread: at slot 1,000,000 real Solana is on epoch 15, superbank reports epoch 2.
Affected methods
They all assume mainnet because the RPC layer has no source for the cluster's real schedule. Scoped to the epoch schedule only (no leader-schedule method exists today).
Approach (ingest-and-store, per #30)
- Ingest: the ingestor already fetches the real schedule in one path (it builds an RPC client and calls
get_epoch_schedule() in the bigtable epoch-range resolution). Generalize it: when --rpc-url is set, fetch the schedule once at startup and store it. --rpc-url is a global optional arg, so this covers the rpc source (which requires it) and anything else run with one; sources without it just get no schedule.
- Store: a small
epoch_schedule table holding the five fields (slots_per_epoch, leader_schedule_slot_offset, warmup, first_normal_epoch, first_normal_slot) as a single row. This would be the first config-style (single-row) table in the repo, so the engine/shape is worth a quick look (local/cluster/replicated variants).
- Read: the RPC server loads it once at startup (natural fit next to
discover_bucket_moduli) into AppState, and the three methods derive their epoch fields from it (warmup included) instead of the hardcoded constant.
Open questions
- Gate mechanism. You mentioned a feature flag. Compile-time Cargo feature (like
grpc-head-cache), or a runtime gate on whether the schedule is present (or a plain config flag)? Runtime feels closer for per-deployment data availability, but your call.
- No-schedule behavior, and getInflationReward rollout. When the schedule isn't available I'd rather gate the methods off than silently fall back to the mainnet default, since that silent fallback is the exact thing this fixes. An explicit "assume mainnet" opt-in works too if you prefer. The wrinkle: getInflationReward is already live on
main, so gating it removes a method from deployments that don't set --rpc-url or the opt-in. Fine, or should the "assume mainnet" opt-in default to on to preserve today's behavior?
@notwedtm
Follow-up from #30.
Three methods compute epoch fields from a hardcoded mainnet schedule (
DEFAULT_SLOTS_PER_EPOCH= 432000, warmup off), so on any cluster whose genesis enables warmup they're silently wrong. Example from that thread: at slot 1,000,000 real Solana is on epoch 15, superbank reports epoch 2.Affected methods
main): the default-epoch math inhandle_get_inflation_rewardand the epoch-to-slot bounds ininflation_epoch_slot_bounds.epoch,slotIndex,slotsInEpoch.They all assume mainnet because the RPC layer has no source for the cluster's real schedule. Scoped to the epoch schedule only (no leader-schedule method exists today).
Approach (ingest-and-store, per #30)
get_epoch_schedule()in the bigtable epoch-range resolution). Generalize it: when--rpc-urlis set, fetch the schedule once at startup and store it.--rpc-urlis a global optional arg, so this covers the rpc source (which requires it) and anything else run with one; sources without it just get no schedule.epoch_scheduletable holding the five fields (slots_per_epoch,leader_schedule_slot_offset,warmup,first_normal_epoch,first_normal_slot) as a single row. This would be the first config-style (single-row) table in the repo, so the engine/shape is worth a quick look (local/cluster/replicated variants).discover_bucket_moduli) intoAppState, and the three methods derive their epoch fields from it (warmup included) instead of the hardcoded constant.Open questions
grpc-head-cache), or a runtime gate on whether the schedule is present (or a plain config flag)? Runtime feels closer for per-deployment data availability, but your call.main, so gating it removes a method from deployments that don't set--rpc-urlor the opt-in. Fine, or should the "assume mainnet" opt-in default to on to preserve today's behavior?@notwedtm