github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/tendermint/crypto/merkle/simple_tree_test.go (about)

     1  package merkle
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/require"
     7  
     8  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/tmhash"
     9  	tmrand "github.com/fibonacci-chain/fbc/libs/tendermint/libs/rand"
    10  )
    11  
    12  type testItem []byte
    13  
    14  func (tI testItem) Hash() []byte {
    15  	return []byte(tI)
    16  }
    17  
    18  func TestSimpleProof(t *testing.T) {
    19  
    20  	total := 100
    21  
    22  	items := make([][]byte, total)
    23  	for i := 0; i < total; i++ {
    24  		items[i] = testItem(tmrand.Bytes(tmhash.Size))
    25  	}
    26  
    27  	rootHash := SimpleHashFromByteSlices(items)
    28  
    29  	rootHash2, proofs := SimpleProofsFromByteSlices(items)
    30  
    31  	require.Equal(t, rootHash, rootHash2, "Unmatched root hashes: %X vs %X", rootHash, rootHash2)
    32  
    33  	// For each item, check the trail.
    34  	for i, item := range items {
    35  		proof := proofs[i]
    36  
    37  		// Check total/index
    38  		require.Equal(t, proof.Index, i, "Unmatched indicies: %d vs %d", proof.Index, i)
    39  
    40  		require.Equal(t, proof.Total, total, "Unmatched totals: %d vs %d", proof.Total, total)
    41  
    42  		// Verify success
    43  		err := proof.Verify(rootHash, item)
    44  		require.NoError(t, err, "Verification failed: %v.", err)
    45  
    46  		// Trail too long should make it fail
    47  		origAunts := proof.Aunts
    48  		proof.Aunts = append(proof.Aunts, tmrand.Bytes(32))
    49  		err = proof.Verify(rootHash, item)
    50  		require.Error(t, err, "Expected verification to fail for wrong trail length")
    51  
    52  		proof.Aunts = origAunts
    53  
    54  		// Trail too short should make it fail
    55  		proof.Aunts = proof.Aunts[0 : len(proof.Aunts)-1]
    56  		err = proof.Verify(rootHash, item)
    57  		require.Error(t, err, "Expected verification to fail for wrong trail length")
    58  
    59  		proof.Aunts = origAunts
    60  
    61  		// Mutating the itemHash should make it fail.
    62  		err = proof.Verify(rootHash, MutateByteSlice(item))
    63  		require.Error(t, err, "Expected verification to fail for mutated leaf hash")
    64  
    65  		// Mutating the rootHash should make it fail.
    66  		err = proof.Verify(MutateByteSlice(rootHash), item)
    67  		require.Error(t, err, "Expected verification to fail for mutated root hash")
    68  	}
    69  }
    70  
    71  func TestSimpleHashAlternatives(t *testing.T) {
    72  
    73  	total := 100
    74  
    75  	items := make([][]byte, total)
    76  	for i := 0; i < total; i++ {
    77  		items[i] = testItem(tmrand.Bytes(tmhash.Size))
    78  	}
    79  
    80  	rootHash1 := SimpleHashFromByteSlicesIterative(items)
    81  	rootHash2 := SimpleHashFromByteSlices(items)
    82  	require.Equal(t, rootHash1, rootHash2, "Unmatched root hashes: %X vs %X", rootHash1, rootHash2)
    83  }
    84  
    85  func BenchmarkSimpleHashAlternatives(b *testing.B) {
    86  	total := 100
    87  
    88  	items := make([][]byte, total)
    89  	for i := 0; i < total; i++ {
    90  		items[i] = testItem(tmrand.Bytes(tmhash.Size))
    91  	}
    92  
    93  	b.ResetTimer()
    94  	b.Run("recursive", func(b *testing.B) {
    95  		for i := 0; i < b.N; i++ {
    96  			_ = SimpleHashFromByteSlices(items)
    97  		}
    98  	})
    99  
   100  	b.Run("iterative", func(b *testing.B) {
   101  		for i := 0; i < b.N; i++ {
   102  			_ = SimpleHashFromByteSlicesIterative(items)
   103  		}
   104  	})
   105  }
   106  
   107  func Test_getSplitPoint(t *testing.T) {
   108  	tests := []struct {
   109  		length int
   110  		want   int
   111  	}{
   112  		{1, 0},
   113  		{2, 1},
   114  		{3, 2},
   115  		{4, 2},
   116  		{5, 4},
   117  		{10, 8},
   118  		{20, 16},
   119  		{100, 64},
   120  		{255, 128},
   121  		{256, 128},
   122  		{257, 256},
   123  	}
   124  	for _, tt := range tests {
   125  		got := getSplitPoint(tt.length)
   126  		require.Equal(t, tt.want, got, "getSplitPoint(%d) = %v, want %v", tt.length, got, tt.want)
   127  	}
   128  }