feat(storagechallenge): add LEP-6 deterministic primitives#287
Merged
j-rafique merged 1 commit intoMay 4, 2026
Conversation
fba3844 to
6d3160b
Compare
941967b to
0dc9475
Compare
All previously flagged issues have been addressed. No new issues found.
Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues. |
38849ea to
fd7466f
Compare
Introduces pkg/storagechallenge/deterministic/lep6.go, the off-chain
computation library shared by the storage_challenge runtime, recheck
service, and self-healing dispatcher. Every function is pure (no I/O,
no clock, no goroutines) so independent reporters challenging the same
(target, ticket) pair produce byte-identical StorageProofResult fields.
Functions land in two categories:
CHAIN-MIRRORED (must match lumera/x/audit/v1/keeper/audit_peer_assignment.go
byte-for-byte; the chain re-runs them to validate MsgSubmitEpochReport):
- SelectLEP6Targets — 1/3 deterministic target subset
(SHA-256(seed||0x00||account||0x00||"challenge_target"),
targetCount = ceil(N/divisor) clamped to [1, N])
- PairChallengerToTarget / AssignChallengerTargets — challenger->target
pairing (label "pair"), with no-self and lex tie-break
SUPERNODE-CANONICAL (chain stores outputs as opaque strings; this file
defines the canonical encoding all reporters must use to stay in lockstep):
- ClassifyTicketBucket — RECENT/OLD bucket classification using
Action.BlockHeight (Action.UpdatedHeight does not exist; see
docs/plans/LEP6_SUPERNODE_IMPLEMENTATION_PLAN.md "Resolved Decision 3")
- SelectTicketForBucket — deterministic per-(target,bucket) ticket pick
with excluded-set support for active heal ops
- SelectArtifactClass — LEP-6 §10 weighted roll (20% INDEX / 80% SYMBOL)
with deterministic fallback when a class has no artifacts
- SelectArtifactOrdinal — uniform ordinal mod artifactCount
- ComputeMultiRangeOffsets — k=4 range offsets in [0, size-rangeLen)
- ComputeCompoundChallengeHash — BLAKE3 over concat of slices in offset
order (lukechampine.com/blake3 to match the chain's library)
- DerivationInputHash — canonical hex of derivation inputs
- TranscriptHash — full canonical transcript identifier with sorted
observer ids; struct-input form prevents field-order mistakes
Domain separators ("challenge_target", "pair", "ticket_rank",
"artifact_class", "artifact_ordinal", "range_offset",
"derivation_input", "transcript") and enum string forms ("INDEX"/
"SYMBOL", "RECENT"/"OLD"/"PROBATION"/"RECHECK") are package
constants; freezing them prevents accidental drift between callers and
tests. Any change is a protocol-level break that requires versioning.
Tests:
- TestStorageTruthAssignmentHash_KnownVector locks the byte-level SHA-256
composition against an independent computation, guaranteeing the
chain-mirrored helper has not drifted.
- TestSelectLEP6Targets_OneThirdCoverage_AssignmentMatchesChain uses the
chain's own audit_peer_assignment_test.go fixture
(seed="01234567890123456789012345678901", active={sn-a..sn-f},
divisor=3) — output {sn-f, sn-e}.
- TestAssignChallengerTargets_KnownAssignment locks the full pairing
{sn-a -> sn-f, sn-b -> sn-e}.
- TestSelectArtifactClass_WeightedDistribution validates ~20% INDEX
over 5000 draws (±2% tolerance).
- Determinism, sensitivity, error-path, and out-of-bounds tests for
every primitive.
Verified: `go test ./pkg/storagechallenge/deterministic/...` passes; the
existing deterministic_test.go pre-LEP-6 tests continue to pass.
0dc9475 to
af43dd8
Compare
3024949
into
supernode/LEP-6-chain-client-extensions
6 checks passed
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.
Introduces pkg/storagechallenge/deterministic/lep6.go, the off-chain computation library shared by the storage_challenge runtime, recheck service, and self-healing dispatcher. Every function is pure (no I/O, no clock, no goroutines) so independent reporters challenging the same (target, ticket) pair produce byte-identical StorageProofResult fields.
Functions land in two categories:
CHAIN-MIRRORED (must match lumera/x/audit/v1/keeper/audit_peer_assignment.go byte-for-byte; the chain re-runs them to validate MsgSubmitEpochReport):
SUPERNODE-CANONICAL (chain stores outputs as opaque strings; this file defines the canonical encoding all reporters must use to stay in lockstep):
Domain separators ("challenge_target", "pair", "ticket_rank", "artifact_class", "artifact_ordinal", "range_offset", "derivation_input", "transcript") and enum string forms ("INDEX"/ "SYMBOL", "RECENT"/"OLD"/"PROBATION"/"RECHECK") are package constants; freezing them prevents accidental drift between callers and tests. Any change is a protocol-level break that requires versioning.
Tests:
Verified:
go test ./pkg/storagechallenge/deterministic/...passes; the existing deterministic_test.go pre-LEP-6 tests continue to pass.