Skip to content

fix(core): b3b uses emission schedule, not per-block disk reads#716

Merged
github-actions[bot] merged 1 commit into
mainfrom
fix/b3b-arithmetic-recompute
May 25, 2026
Merged

fix(core): b3b uses emission schedule, not per-block disk reads#716
github-actions[bot] merged 1 commit into
mainfrom
fix/b3b-arithmetic-recompute

Conversation

@satyakwok
Copy link
Copy Markdown
Collaborator

@satyakwok satyakwok commented May 25, 2026

Hotfix for the v2.2.16 boot-stall regression. The original B3b helper iterated load_block(h) from 1..=tip to sum coinbase amounts. At mainnet h~2.2M with six containers booting in parallel after a halt-all, MDBX I/O contention turned the "~30-60s sanity pass" estimate from the commit message into a multi-minute per-container stall — every node sat past Blockchain state loaded without proceeding to the BFT round loop. Public RPC stayed down, health checks failed, the v2.2.16 deploy rolled back at T+~24 min.

C-04 at block_executor.rs:336 enforces coinbase.amount == reward for every accepted block. The schedule sum (TOTAL_PREMINE + accumulated BLOCK_REWARD >> halvings_at(h) over 1..=tip) is therefore identical to the disk sum — but 6 orders of magnitude cheaper. New cost at mainnet h2.2M: ~2 ms in a tight CPU loop.

The detection + repair contract is unchanged. Blob's total_minted is compared against the recomputed value; mismatch triggers warn + overwrite + atomic save-back through the existing B1 path.

Regression test renamed to test_recompute_total_minted_is_disk_independent (was _skips_missing_blocks) — asserts the helper returns the same value whether or not blocks are persisted to MDBX. Guards against a future refactor accidentally reintroducing the O(N) disk-read cost.

Also bumps workspace 2.2.16 -> 2.2.17.

Summary

Risk tier

Check ONE:

  • 🟢 Low — docs, tools/, tests/, CI configs, dependency patch bumps in dev-only crates, comments
  • 🟡 Medium — non-consensus production code (RPC handlers, network plumbing, observability, ops scripts)
  • 🟠 High — consensus-critical crates (sentrix-core, sentrix-trie, sentrix-staking, sentrix-bft), block_executor, apply_block_*, state_root path
  • 🔴 Critical — Voyager activation, fork-height changes, hard-fork rollouts, anything that flips env vars on mainnet

Required by tier

🟢 Low — minimum bar

  • CI green (tests + clippy + audit + gitleaks)

🟡 Medium — adds

  • New public function or behavioural change has at least one corresponding #[test] in same PR
  • Brief description of how this was tested (manual run, integration test, etc.)

🟠 High — adds

  • Regression test that fails on main and passes with this change — paste test name in PR body
  • Designed against documented invariant (link the audit/runbook/design doc)
  • Fresh-brain review by someone other than the author (per the consensus-change review checklist)
  • Single conceptual unit per PR (no bundling — bundling consensus changes burned us on v2.1.12 → 2026-04-25 livelock)

🔴 Critical — adds

  • Testnet rehearsal completed with success criteria + log evidence linked here
  • Bake window observed: minimum 2h on testnet at the same configuration before mainnet
  • Coordinated rollback plan documented in PR body — exact commands operator runs if it fails
  • Operator sign-off at activation moment (not just PR approval — separate moment for the actual flip)

Test plan

Rollback plan

Related

Summary by CodeRabbit

  • Chores

    • Version bumped to 2.2.17
  • Bug Fixes

    • Total minted now recomputed from the canonical emission schedule rather than relying on persisted block data, making ledger totals resilient to missing or deleted on-disk blocks.
    • Tests updated to verify disk-independent recomputation.

Review Change Stack

@github-actions github-actions Bot enabled auto-merge (squash) May 25, 2026 18:37
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'sentrix-trie benches'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: d248350 Previous: c6ae261 Ratio
insert_single 183168 ns/iter (± 15493) 83470 ns/iter (± 10721) 2.19

This comment was automatically generated by workflow using github-action-benchmark.

@satyakwok satyakwok self-assigned this May 25, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 25, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@satyakwok satyakwok disabled auto-merge May 25, 2026 18:40
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f6860d61-d777-492c-9cc3-016553c70469

📥 Commits

Reviewing files that changed from the base of the PR and between d248350 and 597377d.

⛔ Files ignored due to path filters (1)
  • CHANGELOG.md is excluded by !**/CHANGELOG.md
📒 Files selected for processing (2)
  • Cargo.toml
  • crates/sentrix-core/src/storage.rs

📝 Walkthrough

Walkthrough

This PR updates the workspace version to 2.2.17 and refactors the recomputation of total_minted in crates/sentrix-core/src/storage.rs to derive it from the canonical emission schedule (TOTAL_PREMINE + sum of per-height rewards using halvings_at and BLOCK_REWARD) instead of summing persisted block coinbases. B3b repair documentation is updated and tests are changed to delete block META entries and assert the recomputed total_minted is unchanged.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • sentrix-labs/sentrix#712: Both PRs modify the B3b total_minted recomputation logic in crates/sentrix-core/src/storage.rs, but differ in approach—this PR uses canonical emission-schedule recomputation while the other iterates persisted block coinbases.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description covers the issue, solution, testing approach, and risk tier assessment, but lacks explicit confirmation that CI is green and doesn't include specific regression test names in all required sections. Explicitly confirm CI status (forge build, test, fmt, slither, storage checks) and ensure the regression test name 'test_recompute_total_minted_is_disk_independent' is listed in the Test plan section for clarity.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: replacing per-block disk reads with emission schedule computation for the B3b helper.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/b3b-arithmetic-recompute

Comment @coderabbitai help to get the list of available commands and usage tips.

Hotfix for the v2.2.16 boot-stall regression. The original B3b helper
iterated `load_block(h)` from 1..=tip to sum coinbase amounts. At
mainnet h~2.2M with six containers booting in parallel after a halt-all,
MDBX I/O contention turned the "~30-60s sanity pass" estimate from the
commit message into a multi-minute per-container stall — every node sat
past `Blockchain state loaded` without proceeding to the BFT round loop.
Public RPC stayed down, health checks failed, the v2.2.16 deploy rolled
back at T+~24 min.

C-04 at `block_executor.rs:336` enforces `coinbase.amount == reward`
for every accepted block. The schedule sum (TOTAL_PREMINE + accumulated
`BLOCK_REWARD >> halvings_at(h)` over 1..=tip) is therefore identical
to the disk sum — but ~6 orders of magnitude cheaper. New cost at
mainnet h~2.2M: ~2 ms in a tight CPU loop.

The detection + repair contract is unchanged. Blob's `total_minted` is
compared against the recomputed value; mismatch triggers warn +
overwrite + atomic save-back through the existing B1 path.

Regression test renamed to `test_recompute_total_minted_is_disk_independent`
(was `_skips_missing_blocks`) — asserts the helper returns the same
value whether or not blocks are persisted to MDBX. Guards against a
future refactor accidentally reintroducing the O(N) disk-read cost.

Also bumps workspace 2.2.16 -> 2.2.17.
@satyakwok satyakwok force-pushed the fix/b3b-arithmetic-recompute branch from d248350 to 597377d Compare May 25, 2026 18:42
@github-actions github-actions Bot enabled auto-merge (squash) May 25, 2026 18:43
@github-actions github-actions Bot merged commit 92938e2 into main May 25, 2026
18 checks passed
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