Skip to content

fix(cascade): duplicate last merkle node on odd levels to match LEP-5 - #14

Open
kaleababayneh wants to merge 1 commit into
LumeraProtocol:masterfrom
kaleababayneh:master
Open

fix(cascade): duplicate last merkle node on odd levels to match LEP-5#14
kaleababayneh wants to merge 1 commit into
LumeraProtocol:masterfrom
kaleababayneh:master

Conversation

@kaleababayneh

Copy link
Copy Markdown
Contributor

Merkle Tree Commitment Root Mismatch

buildTree in src/cascade/commitment.ts promotes 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 via pkg/cascadekit/commitment.go.

Because of this, any file whose chunk count produces an odd tree level commits a wrong availability_commitment root on-chain. The SuperNode recomputes the root from the received file, gets a different value, and rejects the upload:

LEP-5 commitment root verification failed: merkle root mismatch

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 buildCommitment cases including challenge indices). The odd-level cases fail against the old code and pass with the fix. full suite 93/93.

@a-ok123
a-ok123 requested review from mateeullahmalik and a balanced review from Copilot August 21, 2026 15:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 buildCommitment cases 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.

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.

2 participants