fix: consensus determinism, BFT quorum threshold, and digest safety - #44
Open
Alicepoltora wants to merge 1 commit into
Open
fix: consensus determinism, BFT quorum threshold, and digest safety#44Alicepoltora wants to merge 1 commit into
Alicepoltora wants to merge 1 commit into
Conversation
1. Fix non-deterministic global_state_root (consensus/src/merkle_integration.rs)
- HashMap iteration order is non-deterministic; sort entries by subnet_id
before building SubnetAggregationTree so all validators compute the same root
2. Fix non-deterministic Event/Anchor/CF IDs (types/src/event.rs, types/src/consensus.rs)
- Remove SystemTime::now() timestamp from compute_id hash inputs
- Timestamp caused different validators to compute different IDs for the same
logical event, breaking consensus
- VLC logical_time + creator + parent_ids already ensure uniqueness
3. Fix BFT quorum threshold (types/src/consensus.rs)
- Previous formula (n*2)/3 + 1 required unanimity for n=3 (threshold=3)
- Correct BFT quorum is ceil(2n/3): n=3→2, n=4→3, n=6→4
- Changed to (n*2 + 2) / 3
4. Fix Object::compute_digest silently ignoring BCS errors (types/src/object.rs)
- If bcs::to_bytes fails, digest was computed without data bytes
- Two objects with same id/version but different data got the same digest
- Now panics with clear message (indicates a type-level bug)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes 4 consensus-breaking and correctness bugs:
1. Non-deterministic
global_state_root(consensus-breaking)consensus/src/merkle_integration.rs:136compute_global_state_rootiterates aHashMapwhich has non-deterministic order. Different validators compute differentglobal_state_rootfrom identical inputs → consensus fork.Fix: Sort entries by
subnet_idbefore building theSubnetAggregationTree.2. Non-deterministic Event/Anchor/CF IDs (consensus-breaking)
types/src/event.rs:749,types/src/consensus.rs:87,311Event::compute_id,Anchor::compute_id, andConsensusFrame::compute_idincludeSystemTime::now()timestamp in the hash. Two validators creating the same logical event at different wall-clock times get different IDs → never reach consensus.Fix: Exclude timestamp from ID computation. The VLC
logical_time+creator+parent_idsalready provide uniqueness and causal ordering. The timestamp field is preserved for informational purposes.3. BFT quorum threshold wrong for 3 validators
types/src/consensus.rs:334Previous formula
(n * 2) / 3 + 1gives threshold=3 for n=3, requiring unanimity instead of BFT quorum. This means a single offline validator blocks all finalization.Fix:
(n * 2 + 2) / 3= ceil(2n/3).4.
Object::compute_digestsilently ignores BCS errorstypes/src/object.rs:418If
bcs::to_bytesfails, the digest was computed from onlyid + version, without data. Two objects with the same id/version but different (non-serializable) data got the same digest → silent data corruption.Fix:
expect()on BCS failure with a clear message (indicates a type-level bug).Testing
cargo check -p setu-types -p consensus— passescargo test -p consensus— 160/160 passcargo test -p setu-types— 178/179 pass (1 pre-existing golden-file failure unrelated to these changes)Files changed
consensus/src/merkle_integration.rs— sort subnet entriestypes/src/event.rs— exclude timestamp from Event ID, update genesis constanttypes/src/consensus.rs— exclude timestamp from Anchor/CF ID, fix quorum formulatypes/src/object.rs— propagate BCS serialization errors