Skip to content

Preserve duplicate leaves in Merkle proofs - #4

Closed
a-shannon wants to merge 1 commit into
ergoplatform:masterfrom
a-shannon:fix/duplicate-merkle-leaves
Closed

Preserve duplicate leaves in Merkle proofs#4
a-shannon wants to merge 1 commit into
ergoplatform:masterfrom
a-shannon:fix/duplicate-merkle-leaves

Conversation

@a-shannon

Copy link
Copy Markdown

Summary

  • derive Merkle tree length and batch leaf order from the actual ordered leaves in topNode
  • preserve elementsHashIndex for element lookup while verifying that the returned proof matches the requested hash
  • cover duplicate positions, padding boundaries, batch normalization, and inconsistent manual index maps

Root cause

MerkleTree.apply keeps duplicate leaves in topNode, but elementsHashIndex is a
map from leaf hash to one index. Equal hashes therefore collapse in the map while
remaining separate positions in the tree.

length, proofByIndex, and proofByIndices used that deduplicated map as if it
were the ordered leaf sequence. With duplicate leaves, traversal could return a
proof for another leaf that still validated against the root, while batch proofs
could reject valid indices or use the wrong leaf hashes.

This change traverses topNode once to retain every leaf hash in order. Element
lookup continues to use the existing map and now fails closed if a manually
constructed map points at a leaf with a different hash.

Compatibility

  • tree construction and rootHash are unchanged
  • the MerkleTree case-class parameters and callable public JVM signature are unchanged
  • MerkleProof and BatchMerkleProof formats and serializers are unchanged
  • proofs for unique-leaf trees remain byte-for-byte unchanged

Tests

  • sbt "+scryptoJVM/Test/testOnly scorex.crypto.authds.merkle.MerkleTreeSpecification" — 17 passed on each of Scala 2.11, 2.12, 2.13, and 3
  • sbt "+scryptoJS/Test/testOnly scorex.crypto.authds.merkle.MerkleTreeSpecification" — 17 passed on each of Scala 2.13 and 3
  • sbt "scryptoJVM/test" "scryptoJS/test" — JVM 171 passed; JS 128 passed
  • git diff --check

Related work

Follow-up to ergoplatform/ergo#2463 and the node-local hotfix
ergoplatform/ergo#2469.

@a-shannon

Copy link
Copy Markdown
Author

Superseded by #5, which implements the same duplicate-leaf invariant using the selected single-structure design and is now merged. Closing this alternative.

@a-shannon a-shannon closed this Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant