feat(state): commit native module state into trie/state_root (fork-gated)#779
Conversation
…ted) Native-module state (SRC-20 ContractRegistry + NFT NftRegistry) was committed only to the STATE-FP fingerprint (#776), not the consensus state_root — so a divergent registry was not rejected by peers. Commit both registries' canonical hashes into the state trie behind a new fork gate, mirroring the proven SIP-6 STATE_IN_TRIE pattern. - new gate NATIVE_STATE_IN_TRIE_HEIGHT, default u64::MAX on BOTH nets. Deliberately NOT reusing STATE_IN_TRIE_HEIGHT (already active on testnet at 6,026,000) — reusing it would retroactively fork testnet's state_root. - two fixed trie keys: sentrix/v1/native_src20_registry + sentrix/v1/native_nft_registry; value = registry canonical_hash (sorted, HashMap-order-independent — from #776). Always-insert post-fork (empty registry has a stable hash), same semantics as total_minted/epoch. - update_trie_for_block captures both hashes before the trie mut-borrow (Phase 2f), independent of the SIP-6 gate. Pre-fork: state_root is bit-identical to today (native state stays off-trie). Post-fork: SRC-20 / NFT state changes move state_root. Commitment model: the trie stores the registry canonical HASH, not the full registry — divergence is detected (peers reject the block); recovery is via peer resync (the blob remains the data source). Activation requires halt-all + state-root-alignment pre-flight + simul-start so every validator commits identical native state at the activation block (STATE_IN_TRIE playbook). NFT_TOKENOP_HEIGHT stays disabled — the NFT registry commits as empty until it is enabled. Tests: pre-fork preserved; post-fork SRC-20 + NFT changes move state_root; replay-deterministic; different supply/owner differ; deploy-order independent; empty commitment stable; fork-gate default-disabled on both nets + activates at pinned height.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
codecov/patch on #779 flagged 10 uncovered lines (0%) in sentrix-trie/src/address.rs: the two new native_*_registry_key builders. They're exercised by sentrix-core's integration tests, but codecov measures sentrix-trie in its own package run where its unit tests didn't call them. Add a unit test asserting both keys are deterministic, mutually distinct, and distinct from total_minted/epoch/account keys.
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThis pull request introduces a new fork-gated feature that commits native-module state (SRC-20 ContractRegistry and NFT NftRegistry) into the account state trie. The implementation establishes fixed registry keys in the trie infrastructure, defines a new fork gate controlled by the Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
PR #779 merged native-module state-root commitment behind a fork gate that is off by default everywhere (NATIVE_STATE_IN_TRIE_HEIGHT = u64::MAX on both nets). Add the operator-side playbook for eventually turning it on, testnet-first, without splitting the chain. Covers: pre-flight (same binary/height/tip/state_root + matching SRC-20 and NFT canonical hashes via the existing SENTRIX_STATE_FINGERPRINT tool + backup), halt-all/simul-start activation with an identical pinned height, post-activation monitoring, rollback/resync on divergence (unset the gate = complete deterministic rollback), and the strict sequence: activate + soak native state-trie first; NFT_TOKENOP_HEIGHT is a separate later decision; never flip both in one window; no mainnet before a clean testnet soak. Docs only — no protocol code, no fork enabled, no tooling added (reuses the existing fingerprint for cross-node hash comparison).
Draft to prevent auto-merge — do not merge; for review only.
Closes the real remaining protocol gap from #776: native-module state (SRC-20
ContractRegistry+ NFTNftRegistry) is now committed into the consensusstate_root, not just the debug fingerprint. A divergent registry is now rejected by peers instead of relying on deterministic re-execution + the uncommitted blob.Design (mirrors the proven SIP-6 STATE_IN_TRIE pattern)
NATIVE_STATE_IN_TRIE_HEIGHT, defaultu64::MAXon BOTH nets. Deliberately not reusingSTATE_IN_TRIE_HEIGHT— it's already active on testnet (6,026,000), so reusing it would retroactively change testnet's state_root and fork the chain.sentrix/v1/native_src20_registry,sentrix/v1/native_nft_registry(same fixed-key style astotal_minted_key/epoch_state_key).canonical_hash()(sorted, HashMap-order-independent — landed in feat(state): canonical fingerprint commitment for native module state (SRC-20 + NFT) #776). Always-insert post-fork; empty registry has a stable hash. Captured before the trie mut-borrow (Phase 2f), independent of the SIP-6 gate.Behaviour
SRC-20 + NFT, same model
Both registries follow the identical commitment path — not NFT-only.
Fork safety / migration
NFT_TOKENOP_HEIGHTstays disabled — the NFT registry commits as empty until it's enabled.Tests (all green)
native_module_state_root.rs(8): pre-fork preserved · post-fork SRC-20 change moves root · post-fork NFT change moves root · replay-deterministic · different supply differ · different owner differ · deploy-order independent · empty commitment stable. Plus fork_heights gate tests (default-disabled both nets; activates at pinned height).Did not weaken: NFT no-reuse, max_supply ever-minted, tx.from_address auth, metadata lock, address validation, sentrix-nft internals.
Commands
cargo test -p sentrix-nft✅ (45+2) ·cargo test --workspace✅ (67 suites, 0 fail)cargo fmt --check✅ ·cargo clippy --workspace --all-targets -D warnings✅No deploy. No RPC/explorer/wallet/marketplace/bridge/image-bytes. NFT fork not enabled.
Summary by CodeRabbit
Release Notes
New Features
Tests