Skip to content

u128 precision Phase 3: decide + (if feasible) backfill already-lossy historical rows #2923

Description

@JSONbored

Part of #2588. Do NOT start this until Phase 1 (#2921) and Phase 2 (#2922) have shipped. This is the risky phase — real production data, may not be fully feasible, requires staging rehearsal before any live execution.

Context

Every row written before Phase 1 lands is already lossy, via one of two mechanisms:

  • Mechanism A (neurons.stake_tao/emission_tao, neuron_daily.stake_tao, subnet_snapshots.total_stake_tao): the exact rao value was discarded inside the Bittensor SDK's Balance.__float__() before this repo's code ever ran. Recovering it requires re-querying the chain at the exact historical block height for every affected row — this is not a code fix, it's a full re-derivation project, and it may not even be possible for the oldest rows if an archive node isn't reachable that far back.
  • Mechanism B (neuron_daily.emission_tao from the backfill script, account_events.amount_tao/alpha_amount): also already-lossy, but since these came from SCALE-decoded raw chain events, re-deriving exact values is more mechanical (same event-decode logic, just skip the premature division) — IF the raw source blocks/events are still replayable, which again depends on archive-node reachability.

Requirements — go/no-go gate before any implementation

  1. Confirm archive-node reachability at historical block heights. This project now runs a self-hosted full-archive node (JSO-1926/infra(archive-node): bare-metal buildout — provision → sync → first-party RPC origin #2111) — check whether it (or the public archive RPC fallback) can actually serve state queries far enough back to cover the oldest affected rows in neurons/neuron_daily/account_events. If not reachable that far back, full recovery for the oldest data may be impossible — this must be established and documented before deciding to proceed, not discovered mid-implementation.
  2. Rehearse against a staging D1 copy first, never live. This directly matters given a live incident earlier in this project's timeline from an under-verified schema/data assumption on a large production table (neuron_daily alone is 10M+ rows) — do not repeat that failure mode here.
  3. Explicit rollback/verification plan before any live run: row-count diffs before/after, spot-checks against independently-known-correct values (e.g. cross-check a handful of known large validators' stake against a manual chain query), and a clear way to abort/roll back mid-run if something looks wrong.
  4. Decide whether backfill is even worth doing. Per the audit: today's actual magnitudes are nowhere near the ~9M TAO precision ceiling, so the practical impact of NOT backfilling is small (low-order-bit imprecision on old rows, not a functionally broken product). Weigh the real engineering cost (a full re-derivation project against chain history) against that low practical impact before committing to it.

Deliverables

  • Archive-node reachability confirmed (or ruled out) for the full historical range needing backfill
  • Explicit go/no-go decision documented, with reasoning, on whether to backfill at all
  • If go: a staging-rehearsed migration/backfill plan with rollback strategy, executed only after rehearsal succeeds
  • If no-go: the historical imprecision documented as a known, accepted limitation (e.g. in docs/adr/ or this repo's data-integrity documentation), so it isn't rediscovered as a "mystery bug" later

Expected outcome

Either: historical rows are corrected via a carefully-rehearsed, low-risk backfill; or: a clear, documented decision that backfill isn't worth the cost/risk given today's magnitudes, with the limitation recorded for future reference.

Explicitly out of scope

  • Any live schema/data change without a prior staging rehearsal.
  • Changing the REAL column types to INTEGER/TEXT as part of this issue (that's Phase 4/a separate decision if the contract itself ever needs to change).

maintainer-only (owner)

Metadata

Metadata

Assignees

Labels

backendmaintainer-onlyOwner-only work — yields no Gittensor points.

Projects

Status
Backlog

Relationships

None yet

Development

No branches or pull requests

Issue actions