Skip to content

fix: anchor scoring cadence and prune horizon to block height (#372)#374

Open
greatjourney589 wants to merge 1 commit into
entrius:testfrom
greatjourney589:fix/scoring-cadence-block-anchored
Open

fix: anchor scoring cadence and prune horizon to block height (#372)#374
greatjourney589 wants to merge 1 commit into
entrius:testfrom
greatjourney589:fix/scoring-cadence-block-anchored

Conversation

@greatjourney589
Copy link
Copy Markdown

Summary

The validator's scoring cadence was driven by self.step % SCORING_WINDOW_BLOCKS,
a per-process counter, and every scoring pass scored a fixed trailing window
ending at self.block. When the forward loop advances more than one block per
step (catch-up after a restart/outage, fast chain), consecutive windows leave
gaps on the block axis — so a miner holding crown across the gap is only
credited for the final window, not the full span. Validators also diverged
because self.step and restart history differ across processes.

This change anchors the cadence and the windows to block height via a new
persisted last_scored_block frontier:

  • Scoring fires once the event-watcher cursor has caught up to the chain tip
    and a full SCORING_WINDOW_BLOCKS has elapsed since last_scored_block.
  • Consecutive windows are (last_scored, window_end], so they tile the block
    axis contiguously — no gap, no overlap. window_end is clamped to the
    watcher cursor so a window never runs ahead of loaded events.
  • last_scored_block is persisted in event_watcher_meta, so a fresh process
    resumes from its frontier instead of re-deriving from self.step.
  • The event prune horizon now trails the unscored frontier
    (min(current_block, last_scored_block)), so a not-yet-scored window keeps
    its busy/active inputs until scoring consumes them.
  • A long-outage cold boot resets the frontier to 0 (pre-bootstrap blocks are
    unreachable), falling back to the trailing window.

Two replaying validators starting from the same last_scored_block now score
identical windows regardless of step counts.

Changes

  • allways/validator/scoring.py — add scoring_due() / scoring_window();
    derive the window from last_scored_block; advance the frontier after scores
    update; anchor prune_rate_events on the unscored frontier.
  • allways/validator/forward.py — gate scoring on scoring_due(self) instead
    of self.step % SCORING_WINDOW_BLOCKS.
  • allways/validator/event_watcher.py — prune cutoff trails the unscored
    frontier; cold bootstrap resets last_scored_block to 0.
  • allways/validator/state_store.pyget_/set_last_scored_block().
  • neurons/validator.py — drop the initial_scoring_done flag.

Testing

  • uv run pytest tests/ — passes
  • uv run ruff check allways/ neurons/ — clean

New tests cover block-anchored cadence, contiguous window tiling, the full-span
crediting case (issue #372), prune-horizon tracking, frontier round-trip, and
cold-boot reset.

Fixes #372

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

1 participant