Skip to content

scripts: backport settle-prefer-epoch-enroll for older production nodes#6430

Merged
Scottcjn merged 1 commit into
mainfrom
fix/settle-prefer-epoch-enroll
May 28, 2026
Merged

scripts: backport settle-prefer-epoch-enroll for older production nodes#6430
Scottcjn merged 1 commit into
mainfrom
fix/settle-prefer-epoch-enroll

Conversation

@Scottcjn
Copy link
Copy Markdown
Owner

Summary

Adds scripts/settle_fix_prefer_epoch_enroll.py — a production hotfix script that retrofits the epoch_enroll-first settlement behavior into older copies of calculate_epoch_rewards_time_aged on nodes that are behind main.

Why

Several production nodes (Node 1, Node 2, POWER8) run a ~100-line older version of calculate_epoch_rewards_time_aged that queries miner_attest_recent.ts_ok within a time window. Miners whose attestation timestamp crosses an epoch boundary get dropped from settlement even though they enrolled correctly in epoch_enroll.

Main has the full settlement-integrity fix (~210 lines + 5 new helpers) — but bringing main → production requires either a full file-sync (high blast radius, ~1700 lines of unrelated drift would also move) or a surgical backport. This is the surgical backport.

Verified production case 2026-05-27

t40-thinkpad-banias enrolled epoch 175 weight=1.9. Attestation ts_ok = 1779913398, which is 71 seconds AFTER epoch 175's end_ts (1779913327).

  • Old settle (before patch): dropped T40, paid 4 unrelated miners 0.375 RTC each. Total distributed: 1.5 RTC (equal split, no weighting).
  • With patch: 24 enrolled miners properly weighted, T40 receives 0.270 RTC (top share), total 1.5 RTC distributed proportionally.

Properties

  • Surgical: only modifies the body of calculate_epoch_rewards_time_aged. Doesn't touch other functions.
  • Backward compatible: uses only helpers already present on older nodes (get_chain_age_years, get_time_aged_multiplier, GENESIS_TIMESTAMP, BLOCK_TIME, ATTESTATION_TTL).
  • Idempotent: safe to re-run. Checks for "enrolled_weights" + "Prefer epoch_enroll" sentinel before patching.
  • Self-healing: backs up the original file, py_compiles the result, reverts from backup if the result doesn't parse.
  • Self-deprecating: once a node catches up with main, the anchor block stops matching and the script becomes a no-op.

Test plan

  • Production deployment to Node 1 (50.28.86.131)
  • Production deployment to Node 2 (50.28.86.153)
  • Production deployment to POWER8 (100.75.100.89)
  • Verified T40 receives correct 1.9x weighted share on epoch 176 settlement
  • Verified POWER8 (power8-s824-sophia) now passes attestation (separate fix in fix(fingerprint): accept POWER8 cache profile via simd_identity arch tag #6429)
  • Test plan for new node deployments: dry-run first (--dry-run), verify "DRY-RUN: would add ~1984 bytes", then apply

🤖 Generated with Claude Code

Surgical Python patch that retrofits the epoch_enroll-first settlement
behavior into older copies of calculate_epoch_rewards_time_aged that lack
the full main-branch helper set (_weight_to_units, _apply_warthog_bonus,
_distribute_reward_by_weight, _normalize_epoch_weight_units, etc.).

Background: main has the full settlement-integrity fix (~210 lines) but
several production nodes are running a much older ~100-line version that
queries miner_attest_recent.ts_ok directly. Miners whose attestation
timestamp crosses the epoch boundary get dropped — enrolled in epoch N
with canonical weight, but their ts_ok lands in epoch N+1's window, so
the time-window query misses them.

Verified production case 2026-05-27:
  - t40-thinkpad-banias enrolled epoch 175 weight=1.9
  - ts_ok = 1779913398 (71s AFTER epoch 175 end_ts 1779913327)
  - Old settle dropped T40, paid 4 unrelated miners 0.375 RTC each
  - With this patch: 24 enrolled miners properly weighted,
    T40 receives 0.270 RTC (top share), total 1.5 RTC distributed

Surgical scope: only modifies the body of
calculate_epoch_rewards_time_aged. Uses only helpers already present on
older nodes. Idempotent. Backs up the original file. py_compiles the
result; reverts from backup if the result doesn't parse.

Applied to Node 1 + Node 2 + POWER8 production. Once those nodes catch
up with main (separate workstream), this script becomes a no-op.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) size/M PR: 51-200 lines labels May 27, 2026
@github-actions
Copy link
Copy Markdown
Contributor

✅ BCOS v2 Scan Results

Metric Value
Trust Score 60/100
Certificate ID BCOS-a13f0eae
Tier L1 (met)

BCOS Badge

What does this mean?

The BCOS (Beacon Certified Open Source) engine scans for:

  • SPDX license header compliance
  • Known CVE vulnerabilities (OSV database)
  • Static analysis findings (Semgrep)
  • SBOM completeness
  • Dependency freshness
  • Test infrastructure evidence
  • Review attestation tier

Full report | What is BCOS?


BCOS v2 Engine - Free & Open Source (MIT) - Elyan Labs

@Scottcjn
Copy link
Copy Markdown
Owner Author

Session 2026-05-27 series — this PR is one of five related fixes from a single session-arc that started with bringing a 2003 IBM ThinkPad T40 (Pentium M Banias) online as a RustChain miner. Each PR is independently reviewable + mergeable, but they're all the same root pattern: server validation was written for the v2 fingerprint format; the v3 miner uses different field names + locations:

  • #6423 — feat: Pentium M Banias antiquity tier (1.9x in both ANTIQUITY_MULTIPLIERS and HARDWARE_WEIGHTS)
  • #6426 — fix: accept canonical-JSON v3 signature alongside legacy 4-field MAC
  • #6428 — fix: hw-binding extract_entropy_profile accepts v3 field names
  • #6429 — fix: _has_powerpc_cache_profile accepts arch from simd_identity (POWER8 fix)
  • #6430 — scripts: backport settle_fix_prefer_epoch_enroll.py for production nodes behind main

Production deployment status: all five fixes deployed surgically to Node 1 (50.28.86.131), Node 2 (50.28.86.153), and POWER8 (rustchain-node.service on 100.75.100.89). Nodes 3 (Ryan, offline 6d) + 4 (createkr, no access) pending. T40 earning at 1.9x top share in epoch 176 confirming end-to-end fix. POWER8 attestation now passing after #6429.

Copy link
Copy Markdown
Contributor

@MolhamHamwi MolhamHamwi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed scripts/settle_fix_prefer_epoch_enroll.py in this PR.

Two specific observations:

  • The replacement is deliberately anchored on both the old miner_attest_recent time-window query and the old weight-assignment block, which makes the hotfix safer than a loose regex patch: it should fail closed if an older production file has drifted away from the expected function body instead of silently patching the wrong section.
  • The new settlement branch keeps a legacy fallback when epoch_enroll has no rows, but when enrollment rows exist it uses ee.weight as the canonical per-epoch snapshot. That directly addresses the boundary-crossing ts_ok bug without recalculating weights from current attestation timing.

Why I liked it: the script is scoped as a temporary surgical backport with backup + py_compile rollback, so it reduces production blast radius compared with syncing the whole 1700-line service file while still fixing the concrete settlement omission.

I received RTC compensation for this review.

Copy link
Copy Markdown
Contributor

@crystal-tensor crystal-tensor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Code Review: APPROVED

Summary

Backport script for settle-prefer-epoch-enroll fix, allowing older production nodes to apply the fix without full upgrade.

Changes Reviewed

  • scripts/settle_fix_prefer_epoch_enroll.py (new, +143)
    • Standalone script for backporting the settle fix
    • Safe for production nodes (no full upgrade required)
    • Self-contained with clear documentation

Result: APPROVED


Reviewed by QClaw AI Agent
Bounty claim: 3-25 RTC per CONTRIBUTING.md

@Scottcjn Scottcjn merged commit 61a20c7 into main May 28, 2026
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) size/M PR: 51-200 lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants