Skip to content

feat(consensus): migrate liveness + total_minted to state trie post-fork (SIP-6, PR 3/N)#757

Merged
github-actions[bot] merged 2 commits into
mainfrom
feat/sip-6-liveness-totalminted-trie
Jun 1, 2026
Merged

feat(consensus): migrate liveness + total_minted to state trie post-fork (SIP-6, PR 3/N)#757
github-actions[bot] merged 2 commits into
mainfrom
feat/sip-6-liveness-totalminted-trie

Conversation

@satyakwok
Copy link
Copy Markdown
Collaborator

@satyakwok satyakwok commented Jun 1, 2026

Summary

PR 3/N in the SIP-6 series. Extends PR #756's apply-path trie write with two more off-trie consensus state pieces — per-validator liveness + jail state, and the global `Blockchain.total_minted` counter. Pre-fork (`STATE_IN_TRIE_HEIGHT == u64::MAX`) is bit-identical.

What this PR adds to the trie post-fork

State piece Source Drift class closed
`signed_count` / `missed_count` per validator `SlashingEngine.liveness.get_stats(addr)` (sliding window) Halt #9 mainnet — `LivenessTracker` drifted across validators → different `is_downtime_at` verdicts → divergent `JailEvidenceBundle` → fork.
`jail_until` / `is_jailed` per validator `ValidatorStake` fields Active-set drift — vals disagree on who's eligible to sign → BFT quorum math diverges → fork at next round.
`total_minted` global `Blockchain.total_minted` Tokenomics drift (halving math, ClaimRewards budget) consumed by downstream txs.

What changes

  • `crates/sentrix-trie/src/address.rs` — `validator_liveness_key(addr)` (domain `b"sentrix/v1/liveness/"`) + 25-byte fixed-layout encoder/decoder. `total_minted_key()` (single global key) + 8-byte encoder/decoder. 7 new unit tests, including domain separation against balance / pending_rewards / liveness keys.
  • `crates/sentrix-trie/src/lib.rs` — re-export the 6 new symbols.
  • `crates/sentrix-core/src/blockchain_trie_ops.rs::update_trie_for_block`:
    • Phase 1c (extended) — snapshot `(addr, signed, missed, jail_until, is_jailed)` per validator + `Option<total_minted>` BEFORE the `state_trie.as_mut()` re-borrow. Sorted by addr for cross-validator determinism. Empty / `None` pre-fork.
    • Phase 2c (new) — write per-validator liveness under `validator_liveness_key`. Always insert (never delete) — `(0,0,0,false)` is a legitimate "registered, no signing yet, not jailed" state distinct from "not in registry".
    • Phase 2d (new) — write single global `total_minted` under `total_minted_key()`.

Self-review notes

  • Borrow split: Phase 1c reads `self.stake_registry` + `self.slashing` + `self.total_minted` before mut-borrowing `self.state_trie`. All distinct fields → split-borrow OK.
  • Determinism: liveness Vec sorted by addr after `HashMap.iter()` collect (HashMap iteration order is per-process; sorted Vec is identical across hosts).
  • Cost per block: ~21 trie inserts max on mainnet (vals × 2 components each + 1 global). Each insert is O(log N) on a Merkle-Patricia tree. Tiny vs the balance updates that already dominate.
  • `LivenessTracker.get_stats` cost: O(LIVENESS_WINDOW) per call * num_validators ≈ 21 × 600 = 12.6k record scans per block. Cheap.
  • Validators NOT in stake_registry but with stale trie entries: not possible — tombstoned vals stay in the registry HashMap; cleanup is a separate concern. No stale-entry GC needed in this PR.

Tests

  • `sentrix-trie` 73/73 pass (7 new for SIP-6 liveness / total_minted helpers, including all-namespace-distinct domain separation test).
  • `sentrix-core` existing trie-ops tests still pass (pre-fork bit-identical).
  • `RUSTFLAGS="-D warnings" cargo check --release -p sentrix-core` clean.

Activation hazard (same as PR #756)

The first post-fork block writes EVERY validator's current liveness + total_minted. If those values have already drifted across validators (the bug this PR closes), state_root will diverge at the activation block. Mitigation = operator-set canonical override env vars at activation time (modelled on `STATE_ROOT_V2_TREASURY_BALANCE`). Out of scope here.

Next PRs

  • 4/N — `epoch_state` (epoch boundary + active-set rotation accumulators). Last off-trie piece.
  • 5/N — testnet activation height + bake ≥1 week + mainnet activation.

Summary by CodeRabbit

  • New Features
    • Extended blockchain state storage to persistently track validator liveness metrics (signing activity and status) and cumulative network minting totals.

@github-actions github-actions Bot enabled auto-merge (squash) June 1, 2026 06:27
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 1, 2026

Codecov Report

❌ Patch coverage is 98.97959% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/sentrix-trie/src/address.rs 98.97% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

Warning

Review limit reached

@satyakwok, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 22 minutes and 7 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: cfd31fe1-551c-43d5-8afd-1f35c649b924

📥 Commits

Reviewing files that changed from the base of the PR and between 2ba3685 and 0013f2e.

📒 Files selected for processing (2)
  • crates/sentrix-core/src/blockchain_trie_ops.rs
  • crates/sentrix-trie/src/address.rs
📝 Walkthrough

Walkthrough

This PR extends the state trie persistence layer to store validator liveness and total_minted state alongside existing pending_rewards. It defines new domain-separated trie keys and fixed-layout value codecs in the address module, then updates the block trie operation to collect liveness stats and total_minted from blockchain state, encode them according to the new codecs, and write them to the trie under their respective keys. The changes gate new collection/write phases on a trie-height predicate.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • sentrix-labs/sentrix#750: Implements the F2 architectural fix to move pending_rewards, total_minted, and liveness into the state trie to prevent off-trie drift.

Possibly related PRs

  • sentrix-labs/sentrix#755: Introduces the get_state_in_trie_height and is_state_in_trie_height predicates used by this PR to gate the new trie migration phases.

  • sentrix-labs/sentrix#661: Refactors the trie operation implementation in the same update_trie_for_block function that this PR extends with new liveness and total_minted persistence logic.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically identifies the main change: migrating liveness and total_minted state to the state trie post-fork as part of the SIP-6 series (PR 3/N).
Description check ✅ Passed The PR description comprehensively covers all required sections: Summary explains the change and why it matters, Scope indicates contract changes with drift-class closures, Checks lists verification steps (tests pass, build clean), Deploy impact covers compatibility, and Linked issue and activation hazards are addressed.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/sip-6-liveness-totalminted-trie

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot merged commit e191eb9 into main Jun 1, 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