Repository navigation
4.1: domain-separate sortition and null miner samples in Epoch 4.1 - #7830
aaronb-stacks wants to merge 3 commits into
Conversation
From Epoch 4.1, the winning block-commit and the null miner's challenge are sampled from separate digests of the sortition hash and VRF seed, using the SORTITION and NULL_MINER scopes. Earlier epochs keep the unscoped digest for both samples
There was a problem hiding this comment.
🟡 Changes recommended
The tests do not cover epoch-gated winner selection through select_winning_block or make_snapshot, leaving a consensus-critical scope error undetected without a regression test distinguishing Epoch 4.0 and 4.1 winners.
1 open issue
What changed in this PR
This PR separates the winning block-commit and null-miner draws starting in Epoch 4.1, using distinct hash scopes with the existing entropy.
Changes:
- Gates domain-separated sampling on Epoch 4.1 while preserving legacy sampling and final sortition-hash mixing.
- Adds tests for scoped digests, distribution sampling, and epoch-dependent null-miner behavior.
- Documents the consensus behavior change in a changelog fragment.
| File | Description |
|---|---|
stackslib/src/chainstate/burn/sortition.rs |
Applies distinct sampling scopes and adds regression tests. |
stackslib/src/chainstate/burn/mod.rs |
Adds an optional scope prefix to VRF-seed hashing. |
stackslib/src/burnchains/tests/burnchain.rs |
Explicitly preserves unscoped hashing in the existing test. |
stacks-common/src/types/mod.rs |
Adds the Epoch 4.1 activation predicate. |
changelog.d/sortition-sample-scopes.changed |
Records the domain-separated sampling change. |
Review effort: Balanced
hstove-stacks
left a comment
There was a problem hiding this comment.
Overall LGTM, I mainly think we should do this copilot comment's suggestion about an integration test using fixes inputs to verify the difference in 4.1
There was a problem hiding this comment.
🟡 Changes recommended
The fixture uses the initial seed and preserves the sentinel sortition hash, so it cannot detect incorrect fallback to the initial seed instead of retrieving the stored winner’s seed.
1 open issue
1 resolved since last review
Review effort: Balanced
The fixture appended the prior winner with the sentinel's initial sortition hash and sampled at that same height, so get_last_vrf_seed returned VRFSeed::initial(). Give the winning snapshot a non-initial sortition hash, sample in its child block, assert the stored winner's seed is used, and pick inputs where the initial seed would choose a different winner, so a fallback to the initial seed fails the test.
There was a problem hiding this comment.
🔵 Needs a closer look
Consensus-critical Epoch 4.1 winner selection and null-miner rejection require full burnchain replay and epoch-transition validation that was unavailable in this environment.
No open issues 🎉
1 resolved since last review
Review effort: Balanced
|
/valid |
|
🚀 Validation started for this PR.
Stop it with Progress will appear in the Block Validation check. |


From Epoch 4.1, sortition samples the winning block-commit and the null miner's challenge from two separate, domain-separated digests instead of reusing one.
The fix keeps the same entropy (no new randomness source) and just domain-separates the two samples. I scoped the winner draw as well as the null miner draw so the two are symmetric.