openzeppelin-contracts: Multiproof stops working starting with 9 leaves

The following test reverts

it('multiproof', async () => {
  const leaves = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'].map(keccak256).sort(Buffer.compare)
  const merkleTree = new MerkleTree(leaves, keccak256, { sort: true })
  const root = merkleTree.getRoot()
  const proof = merkleTree.getMultiProof(leaves)
  const proofFlags = merkleTree.getProofFlags(leaves, proof)
  await merkleProof.multiProofVerifyCalldata(proof, proofFlags, root, leaves)
})

Versions:

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 20 (6 by maintainers)

Most upvoted comments

The algorithm for multiproofs doesn’t allow the construction of multiproofs for trees with particularly unbalanced shapes. The merkletree.js library can currently easily produce such trees, as in the example above. Unfortunately this is not something we knew of before.

It’s important to note that it is always possible to produce a multiproof for a single leaf.

The problem for multiple leaves is solved by better balancing the merkle tree. The tree should be a complete (not perfect) full binary tree (definitions in Wikipedia). This kind of tree exists for any needed total number of leaves.

Additionally, the array of leaves that will be proven with a multiproof needs to be sorted in a particular way to be able to produce a multiproof. The ordering should be the reverse of the “general indices” defined in this document. The proof array will be sorted in the same way.

The plan I propose is:

  1. Document that in order to use multiproofs there are requirements on the tree shape and the leaves array. (Note: This kind of requirement is not entirely new, because even for single proofs you want the tree to be well balanced as well.)
  2. Add a flag in merkletree.js to build trees of this shape, add a warning if a multiproof is requested for a tree that was built without this flag, and verify that leaves are properly ordered when a multiproof is requested.

Yes we will want to add a test case. At the moment the next step we’re working on is to modify the merkletreejs library to construct the tree as needed.