Skip to content

perf(early-kickout): base seed blacklist on anchor last-final block#16072

Draft
stedfn wants to merge 2 commits into
stedfn/early-kickout-thresholdsfrom
stedfn/early-kickout-seed-walk-cost
Draft

perf(early-kickout): base seed blacklist on anchor last-final block#16072
stedfn wants to merge 2 commits into
stedfn/early-kickout-thresholdsfrom
stedfn/early-kickout-seed-walk-cost

Conversation

@stedfn

@stedfn stedfn commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Stacked on #16049 (thresholds). Follow-up to the early-kickout writer.

The record-block seeder computed the chunk-producer blacklist from the aggregator walked up to the unfinalized anchor. During a finality stall that rescans the growing not-yet-finalized suffix on every block, an O(stall-depth) per-block walk under the epoch-manager write lock.

This bases the blacklist on the anchor's last-final block instead (BlockInfo::last_final_block_hash / last_finalized_height).

  • Deterministic: the last-final hash is copied verbatim from the block header, so it is identical across nodes for a given canonical anchor. Required because the seeded row is read on the strict consensus path (get_chunk_producer_info_anchored) with no recompute.
  • Bounds the walk: the aggregator's sync point already sits at the last-final block, so the walk covers only blocks finalized since the previous record (~1 in steady state, 0 during a stall) and never the unfinalized suffix.
  • Grace window now gates on the last-final block height too, matching the blacklist basis so the seeder is internally consistent.
  • get_chunk_producer_blacklist accessor updated to the same basis.

Tests: model 2-block finality in the block helper, shift the grace-boundary anchors, and retighten the finality-stall walk guard from O(depth^2) to constant-per-block across two stall depths.

Stale/old-fork anchors whose last-final is an ancestor of the cached sync point still walk (rare, non-canonical, bounded by epoch length). A protocol-fixed budget cap for that case is left as a follow-up.

stedfn and others added 2 commits July 15, 2026 12:02
The record-block seeder computed the chunk-producer blacklist from the
aggregator walked up to the unfinalized anchor. During a finality stall
that rescans the growing not-yet-finalized suffix every block, an
O(stall-depth) per-block walk under the epoch-manager write lock.

Base the blacklist on the anchor's last-final block instead
(BlockInfo::last_final_block_hash / last_finalized_height). This is
copied verbatim from the block header, so it is identical across nodes
for a given canonical anchor - required because the seeded row is read
on the strict consensus path (get_chunk_producer_info_anchored) with no
recompute. It also bounds the walk: the aggregator's sync point already
sits at the last-final block, so the walk covers only blocks finalized
since the previous record (~1 in steady state, 0 during a stall) and
never the unfinalized suffix.

Gate the start-of-epoch grace window on the last-final block height too,
matching the blacklist basis so the seeder is internally consistent.
Update the get_chunk_producer_blacklist accessor to the same basis, and
the epoch-manager tests: model 2-block finality in the block helper,
shift the grace-boundary anchors, and retighten the finality-stall walk
guard from O(depth^2) to constant-per-block across two stall depths.

Stale/old-fork anchors whose last-final is an ancestor of the cached
sync point still walk (rare, non-canonical, bounded by epoch length); a
protocol-fixed budget cap for that case is left as a follow-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.87097% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.21%. Comparing base (657a026) to head (bd0e342).

Files with missing lines Patch % Lines
chain/epoch-manager/src/adapter.rs 66.66% 1 Missing and 2 partials ⚠️
chain/epoch-manager/src/lib.rs 90.90% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@                       Coverage Diff                        @@
##           stedfn/early-kickout-thresholds   #16072   +/-   ##
================================================================
  Coverage                            73.20%   73.21%           
================================================================
  Files                                  856      856           
  Lines                               188485   188499   +14     
  Branches                            188485   188499   +14     
================================================================
+ Hits                                137979   138006   +27     
+ Misses                               46086    46068   -18     
- Partials                              4420     4425    +5     
Flag Coverage Δ
pytests-nightly 1.22% <0.00%> (-0.01%) ⬇️
unittests 69.86% <47.05%> (+0.01%) ⬆️
unittests-nightly 69.86% <82.75%> (-0.01%) ⬇️
unittests-spice 65.46% <82.75%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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