Skip to content

SIP-6 draft: off-trie consensus state commitment (Bug A fix)#3

Merged
satyakwok merged 1 commit into
mainfrom
feat/sip-6-bug-a-off-trie-state
May 31, 2026
Merged

SIP-6 draft: off-trie consensus state commitment (Bug A fix)#3
satyakwok merged 1 commit into
mainfrom
feat/sip-6-bug-a-off-trie-state

Conversation

@satyakwok
Copy link
Copy Markdown
Member

Draft SIP for Bug A fix — off-trie consensus state (pending_rewards, total_minted, liveness, epoch) lives outside state_root and drifts silently across vals.

Summary

distribute_reward / record_block_signatures / epoch_manager.record_block mutations fire AFTER bc.add_block(blk) — too late for state_root to reflect them. Drift undetectable until a consuming tx (ClaimRewards drain, Unjail floor check, AddSelfStake) — then 3-way state_root fork. Verified live 2026-05-31 testnet h=5,817,131 cascade.

Approaches

# Approach Trade-off
F2 Move off-trie state INTO state trie. Drift detected every block. ~1-2k LoC, ~1ms per block, migration with drift reconciliation
F3 B3b-style epoch-boundary reconciliation system tx Cheaper (~500 LoC) but accepts up to 1 epoch (~1 day) drift
F1 Gate consuming ops via fork height ~10 LoC but blocks legit users indefinitely

Recommendation: F2.

Interaction with SIP-5

Both surfaced from same incident. Recommend coordinated activation (same fork height) so operators activate both in one halt-all + simul-start window.

Migration challenge

Existing testnet has unrecovered drift (post 2026-05-31 cascade). Migration must address pre-fork drift via either:

  • M1: pre-migration reconciliation system tx (consensus-agreed snapshot)
  • M2: bootstrap from canonical val (loses some validator history)
  • M3: reset to zero (loses pending rewards)

Operator preference needed.

Review questions

  1. F2 vs F3: agree with F2 recommendation, or push back on the migration complexity?
  2. Coordinate with SIP-5 same fork window, or stagger?
  3. Migration approach M1/M2/M3 for existing testnet drift?
  4. Epoch_manager state — move to trie too, or stay separate?

Links

Test plan

  • One round of feedback from maintainers + operator
  • After acceptance, implementation PR opened against sentrix-labs/sentrix
  • Testnet bake ≥2 weeks (state migration is heavy)
  • Mainnet activation height set in follow-up PR

pending_rewards, total_minted, liveness counters, epoch state live outside
state_root commitment. Mutated POST add_block via distribute_reward /
record_block_signatures / epoch_manager calls. Drift accumulates silently
across vals; undetectable until tx CONSUMES drifted state (ClaimRewards
drain, Unjail floor check, AddSelfStake) → state_root forks.

Discovered live 2026-05-31 testnet h=5,817,131: val3 ClaimRewards surfaced
existing drift, 3-way fork across val1/val2/val4. Earlier instance per
project_total_minted_drift_real_v2_2_17 (2026-05-26, 7 SRX delta).

This SIP evaluates three fixes:

- F2 (recommended): move off-trie state INTO state trie. Every mutation
  participates in state_root. Drift detected at next block apply.
  Cost: ~1-2k LoC, ~1ms per block apply, migration with drift
  reconciliation for already-drifted chains.

- F3 (alternative): B3b-style epoch-boundary reconciliation system tx.
  Accepts up to 1 epoch (~1 day) of drift between checks. Cheaper but
  band-aid.

- F1 (alternative): gate ClaimRewards/Unjail/AddSelfStake dispatch via
  fork height. Immediate safety but blocks legit users indefinitely.

Recommendation: F2. Architecturally clean. Enables future Merkle proofs
for rewards. Bug A is recurring class — every off-trie value risks drift
forever otherwise.

Coordinated activation with SIP-5 recommended (same fork height) so
operators activate both atomically in one halt-all + simul-start window.

Related: #750 (Bug A), SIP-5 / #751 (Bug B), #752 (defense check).
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 31, 2026

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 44 minutes and 50 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ea6307c2-05f9-4fad-ac7e-7da098334883

📥 Commits

Reviewing files that changed from the base of the PR and between 6dc0609 and 134ba8c.

📒 Files selected for processing (1)
  • sips/sip-6.md
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/sip-6-bug-a-off-trie-state

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.

@satyakwok satyakwok merged commit 505fa95 into main May 31, 2026
4 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