fix(cascade): duplicate last merkle node on odd levels to match LEP-5 - #14
fix(cascade): duplicate last merkle node on odd levels to match LEP-5#14kaleababayneh wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes a Merkle tree root mismatch in the cascade LEP-5 availability commitment. Previously, buildTree promoted an odd node to the next level unchanged, whereas the canonical on-chain Go implementation (merkle.BuildTree) duplicates the last node so it pairs with itself. This caused files with chunk counts producing an odd tree level to commit a wrong availability_commitment root, leading SuperNodes to reject uploads with a "merkle root mismatch". Power-of-two chunk counts were unaffected, which is why prior tests passed.
Changes:
- Duplicate the last node (and store the padded level) when a tree level has an odd node count, matching the Go
merkle.BuildTree. - Update the odd-leaves test to assert the duplicate-pair root.
- Add parity tests with gold vectors generated from the production Go code (1–8 chunk trees and four
buildCommitmentcases including challenge indices).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/cascade/commitment.ts | Duplicates the last node on odd levels so hashing pairs it with itself, matching the canonical on-chain Merkle build. |
| tests/cascade/commitment.test.ts | Rewrites the odd-leaves assertion and adds Go-parity gold-vector tests for buildTree and buildCommitment. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Merkle Tree Commitment Root Mismatch
buildTreeinsrc/cascade/commitment.tspromotes an odd node to the next level unchanged.The canonical implementation instead duplicates the last node so it pairs with itself:
lumera/x/action/v1/merkle/merkle.go, which SuperNodes use for verification viapkg/cascadekit/commitment.go.Because of this, any file whose chunk count produces an odd tree level commits a wrong
availability_commitmentroot on-chain. The SuperNode recomputes the root from the received file, gets a different value, and rejects the upload:Power-of-two chunk counts are not affected, which is why the existing tests passed. Actions already registered with a wrong root cannot complete and only refund at expiry.
The fix duplicates the last node when a tree level has an odd number of nodes, matching
merkle.BuildTree.Tests: the odd-leaves case now asserts the duplicate-pair root, plus gold vectors generated from the Go implementation (1–8 chunk trees and four
buildCommitmentcases including challenge indices). The odd-level cases fail against the old code and pass with the fix. full suite 93/93.