Skip to content

Commit

Permalink
Fix single node tree bug
Browse files Browse the repository at this point in the history
  • Loading branch information
litt3 committed Dec 18, 2024
1 parent 89cfdd7 commit 5ff5bb3
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
9 changes: 7 additions & 2 deletions verify/merkle.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ import (
"github.com/ethereum/go-ethereum/crypto"
)

// ProcessInclusionProof processes the Merkle root proof
// ProcessInclusionProof computes the merkle root hash based on the provided leaf and proof, returning the result.
// An error is returned if the proof param is malformed.
//
// NOTE: this method returning a nil error does NOT indicate that the proof is valid. Rather, it merely indicates that
// the proof was well-formed. The hash returned by this method must be compared to the claimed root hash, to
// determine if the proof is valid.
func ProcessInclusionProof(proof []byte, leaf common.Hash, index uint64) (common.Hash, error) {
if len(proof) == 0 || len(proof)%32 != 0 {
if len(proof)%32 != 0 {
return common.Hash{}, errors.New("proof length should be a multiple of 32 bytes or 256 bits")
}

Expand Down
44 changes: 44 additions & 0 deletions verify/merkle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package verify
import (
"testing"

"github.com/wealdtech/go-merkletree/v2"
"github.com/wealdtech/go-merkletree/v2/keccak256"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -39,3 +42,44 @@ func TestProcessInclusionProofFail(t *testing.T) {

require.NotEqual(t, expectedRoot, actualRoot.Bytes())
}

// TestProcessInclusionProofSingleNode confirms that a merkle tree containing a single node is successfully confirmed
func TestProcessInclusionProofSingleNode(t *testing.T) {
leaf, err := hexutil.Decode("0x616C6C206861696C20746865206772656174207361746F736869")
require.NotNil(t, leaf)
require.NoError(t, err)

tree, err := merkletree.NewTree(merkletree.WithData([][]byte{leaf}), merkletree.WithHashType(keccak256.New()))
require.NotNil(t, tree)
require.NoError(t, err)

merkleProof, err := tree.GenerateProofWithIndex(0, 0)
require.NotNil(t, merkleProof)
require.NoError(t, err)

// sanity check: there shouldn't be any sibling hashes for this tree
require.Equal(t, 0, len(merkleProof.Hashes))

emptyProof := make([]byte, 0)

computedRoot, err := ProcessInclusionProof(
emptyProof,
common.BytesToHash(keccak256.New().Hash(leaf)),
0)
require.NotNil(t, computedRoot)
require.NoError(t, err)
require.Equal(t, computedRoot.Bytes(), tree.Root())

// create an alternate leaf, and make sure that the inclusion proof fails the comparison check
badLeaf, err := hexutil.Decode("0xab")
require.NotNil(t, badLeaf)
require.NoError(t, err)

computedRoot, err = ProcessInclusionProof(
emptyProof,
common.BytesToHash(keccak256.New().Hash(badLeaf)),
0)
require.NotNil(t, computedRoot)
require.NoError(t, err)
require.NotEqual(t, computedRoot.Bytes(), tree.Root())
}

0 comments on commit 5ff5bb3

Please sign in to comment.