fix(nipopow): pack_interlinks key encoding — use first-occurrence position#866
Open
mwaddip wants to merge 2 commits into
Open
fix(nipopow): pack_interlinks key encoding — use first-occurrence position#866mwaddip wants to merge 2 commits into
mwaddip wants to merge 2 commits into
Conversation
Adds two tests to ergo-nipopow/src/nipopow_algos.rs covering NipopowAlgos::pack_interlinks: - pack_interlinks_keys_are_first_occurrence_positions: asserts that the ExtensionKV key[1] for each duplicate-run encodes the input-vector index of the run's first element (JVM Ergo encoding), not a sequential distinct-group counter. Test currently FAILS against the pre-fix pack_interlinks which emits sequential ix_distinct_block_ids. - pack_interlinks_empty_returns_empty: pins the no-panic behavior on empty input. Verified empirically against mainnet block 1784124 nipopow proof (captured 2026-05-13): the JVM-compat key encoding makes 11/11 leaf hashes in interlinksProof.indices match against an external TS port. The pre-fix sequential encoding matches only 2/11. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ition Replaces the sequential `ix_distinct_block_ids` counter with the input-vector index of each duplicate-run's first element. Matches JVM Ergo's `NipopowAlgos.packInterlinks` (ergoplatform/ergo, `src/main/scala/org/ergoplatform/modifiers/history/popow/NipopowAlgos.scala`) which encodes ExtensionKV keys as `[INTERLINK_VECTOR_PREFIX, position_of_first_occurrence_in_interlinks_vector]`. ## The bug `unpack_interlinks` filters by `key[0] == INTERLINK_VECTOR_PREFIX` only and never reads `key[1]`, so sigma-rust round-trips its own buggy output internally. The divergence is observable only at the Merkle-leaf hash level: a kv-leaf's hash depends on the full kv-bytes including `key[1]`, so a sigma-rust-packed leaf hashes differently from a JVM-packed leaf. Concrete impact: - `PoPowHeader::check_interlinks_proof` FAILS on real mainnet proofs because the expected Merkle root it computes (via the buggy pack) doesn't match the root the proof's walk-up reaches (built from JVM-packed leaves). - `NipopowProof::is_better_than` rejects all real mainnet proofs as "invalid" because it calls `is_valid()` → `has_valid_proofs()` → `check_interlinks_proof`, which fails for any block with at least one duplicate-run starting past position 1 (≈ every mainnet block). ## Validation Verified against mainnet block 1784124 nipopow proof (captured 2026-05-13 via ergo-node-rust): with this fix, all 11 leaf hashes in the proof's interlinksProof.indices match the JVM-generated leaves exactly. Pre-fix matches only 2 (positions 0 and 1 happen to align because distinct_ix=0,1 also = first_pos=0,1 for the first two runs). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
mwaddip
added a commit
to mwaddip/ergots
that referenced
this pull request
May 19, 2026
… landed) Sigma-rust upstream PR ergoplatform/sigma-rust#866 landed 2026-05-19 and was cherry-picked to integration/ergots (worktree HEAD 6ba9d524). Our fixture-gen now uses NipopowAlgos::pack_interlinks / PoPowHeader:: check_interlinks_proof / NipopowProof::is_better_than directly. ### Equivalence test (passed before removal) After reverting all 9 call sites in fixture-gen but BEFORE deleting the JVM-compat module, ran cargo run --release → all regenerated fixture JSON files byte-identical to committed → proves patched sigma-rust output matches our prior JVM-compat workaround exactly. ### Changes - fixture-gen/src/cmds/interlinks_jvm.rs: DELETED - fixture-gen/src/cmds/mod.rs: removed `pub mod interlinks_jvm;` - 9 call sites reverted to sigma-rust APIs across batch_merkle.rs, compare.rs, nipopow_proof.rs, popow_header.rs - packages/nipopow/src/merkle.ts: packInterlinks JSDoc updated (code unchanged — was already JVM-compat; now agrees with patched upstream) - facts/nipopow.md: removed "sigma-rust divergences" subsection; kept only the unrelated extensionRoot-anchoring known limitation - docs/specs/2026-05-19-sigma-rust-pack-interlinks-upstream-prompt.md: marked SUPERSEDED with PR #866 link; kept for historical context 313 nipopow + 140 avltree + 2658 ergoscript = 3111 tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
mwaddip
added a commit
to mwaddip/ergo-node-rust
that referenced
this pull request
May 24, 2026
Picks up PR ergoplatform/sigma-rust#866 cherry-picked onto ergo-node-integration — `pack_interlinks` now encodes each kv-pair's `key[1]` as the input-vector index of each duplicate-run's first element, matching the JVM. Pre-fix sigma-rust used a sequential distinct-group counter, so `check_interlinks_proof` rejected every real-mainnet proof. Effect on this node: light-bootstrap's KMZ17 §4.3 multi-peer comparison via `is_better_than` now actually compares proofs. Pre-fix behavior was silent degradation to "first valid proof wins" because every challenger comparison errored. Full-mode operators unaffected — they never run light bootstrap. Workspace builds clean, tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
pack_interlinks encodes ExtensionKV.key[1] as a sequential distinct-group counter; JVM uses the input-vector index of each duplicate-run's first element. The mismatch is invisible internally (unpack ignores key[1]) but Merkle leaves hash differently from JVM, so check_interlinks_proof and is_better_than reject every real mainnet proof.
Verified against mainnet block 1784124: 11/11 leaf hashes match JVM post-fix (2/11 pre-fix). Also fixes panic on empty input.