Repository navigation
fix(ergo-nipopow): keep max level signed in update_interlinks so negative levels return interlinks unchanged - #959
Open
Kshot3000 wants to merge 1 commit into
Conversation
…tive levels return interlinks unchanged
This was referenced Oct 11, 2026
Open
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.
Fixes #958:
NipopowAlgos::update_interlinkscast the previous header's max level tousizebefore checking whether it is positive.max_level_ofreturns ani32and is negative for a header whose PoW hit exceeds its target (an invalid-PoW header), so the cast turned the level into a huge positive count and the function tried to build an interlinks vector with that many copies of the header id, panicking withcapacity overflow. The reference implementation (NipopowAlgos.updateInterlinksin the Ergo node) keeps the level a signedInt, checksprevLevel > 0on it, and returns the previous interlinks unchanged for a non-positive level.Changes (ergo-nipopow only)
update_interlinksnow keepsprev_levelasi32for the positivity check and casts tousizeonly after the check, mirroring the reference exactly. Behaviour for every positive level is unchanged — including the branch where the level exceeds the interlinks length (dropRightsaturates the same way in the reference).Tests
Five new regression tests in a new integration-test file,
ergo-nipopow/tests/update_interlinks_negative_level.rs(kept out ofnipopow_algos.rsso this diff stays independent of the other open changes to that file). The headers are Autolykos v1, wherepow_hitis thepow_distancefield itself; withn_bits = 0x207fffffthe required target is exactly 2, so each test pins themax_level_ofit exercises before asserting onupdate_interlinks:negative_level_returns_prev_interlinks_unchanged— level -18 (pow_distance = 1_000_000); ondevelopthis panicked withcapacity overflow(verified before the fix, under a 2 GBulimit -v), now the previous interlinks are returned unchanged.level_truncating_to_zero_returns_prev_interlinks_unchanged— level 0 after truncation; unchanged.positive_level_one_replaces_last_interlink— level 1 keeps working: genesis + tail-minus-last + one copy of the previous header id.positive_level_above_interlinks_len_fills_from_genesis— level 8 against 3 interlinks: genesis + 8 copies of the previous header id.genesis_header_starts_interlinks_with_own_id— the genesis path is untouched.Results:
cargo test -p ergo-nipopow --all-features6/6 (5 new + the existing proof roundtrip); downstreamcargo test -p ergo-chain-generation --all-featureslib suite 18/18 (the crate that builds chains throughupdate_interlinks) andcargo test -p ergo-lib --all-features121/121;cargo clippy -p ergo-nipopow --all-features --all-targets -- -D warningsclean;cargo fmt --checkclean for the touched files.File-overlap note: open #957 also touches
nipopow_algos.rs, but inpack_interlinks(a different function, non-overlapping hunks), and its tests live in a unit-test module in that file while these live intests/— the two should rebase cleanly in either order.Built by @Kshot9000 (https://x.com/kshot9000) · Tips (ERG): 9fcM5RWnAjmP4vx5bnW6yohB6H9bLq8sJbaPLHtwZLtQPB32Pvy