github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/ledger/common/hash/hash_test.go (about)

     1  package hash_test
     2  
     3  import (
     4  	"crypto/rand"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  	"golang.org/x/crypto/sha3"
    10  
    11  	cryhash "github.com/onflow/crypto/hash"
    12  
    13  	"github.com/onflow/flow-go/ledger"
    14  	"github.com/onflow/flow-go/ledger/common/hash"
    15  )
    16  
    17  func TestHash(t *testing.T) {
    18  	t.Run("lengthSanity", func(t *testing.T) {
    19  		assert.Equal(t, 32, hash.HashLen)
    20  	})
    21  
    22  	t.Run("HashLeaf", func(t *testing.T) {
    23  		var path hash.Hash
    24  
    25  		for i := 0; i < 5000; i++ {
    26  			value := make([]byte, i)
    27  			_, err := rand.Read(path[:])
    28  			require.NoError(t, err)
    29  			_, err = rand.Read(value)
    30  			require.NoError(t, err)
    31  			h := hash.HashLeaf(path, value)
    32  
    33  			hasher := sha3.New256()
    34  			_, _ = hasher.Write(path[:])
    35  			_, _ = hasher.Write(value)
    36  			expected := hasher.Sum(nil)
    37  			assert.Equal(t, expected, h[:])
    38  		}
    39  	})
    40  
    41  	t.Run("HashInterNode", func(t *testing.T) {
    42  		var h1, h2 hash.Hash
    43  
    44  		for i := 0; i < 5000; i++ {
    45  			_, err := rand.Read(h1[:])
    46  			require.NoError(t, err)
    47  			_, err = rand.Read(h2[:])
    48  			require.NoError(t, err)
    49  			h := hash.HashInterNode(h1, h2)
    50  
    51  			hasher := sha3.New256()
    52  			_, _ = hasher.Write(h1[:])
    53  			_, _ = hasher.Write(h2[:])
    54  			expected := hasher.Sum(nil)
    55  			assert.Equal(t, expected, h[:])
    56  		}
    57  	})
    58  }
    59  
    60  // Test_GetDefaultHashForHeight tests getting default hash for given heights
    61  func Test_GetDefaultHashForHeight(t *testing.T) {
    62  	var defaultLeafHash [cryhash.HashLenSHA3_256]byte
    63  	cryhash.ComputeSHA3_256(&defaultLeafHash, []byte("default:"))
    64  	expected := ledger.GetDefaultHashForHeight(0)
    65  	assert.Equal(t, expected[:], defaultLeafHash[:])
    66  
    67  	l1 := hash.HashInterNode(ledger.GetDefaultHashForHeight(0), ledger.GetDefaultHashForHeight(0))
    68  	assert.Equal(t, l1, ledger.GetDefaultHashForHeight(1))
    69  
    70  	l2 := hash.HashInterNode(l1, l1)
    71  	assert.Equal(t, l2, ledger.GetDefaultHashForHeight(2))
    72  }
    73  
    74  func Test_ComputeCompactValue(t *testing.T) {
    75  	v := []byte{'A'}
    76  
    77  	// 00000101...00000000
    78  	var path hash.Hash
    79  	path[0] = 5
    80  	nodeHeight := 251
    81  	h := hash.HashLeaf(path, v)
    82  	l := 0
    83  	// exclude last 3 level
    84  	for ; l < nodeHeight-3; l++ {
    85  		h = hash.HashInterNode(h, ledger.GetDefaultHashForHeight(l))
    86  	}
    87  	l1 := hash.HashInterNode(ledger.GetDefaultHashForHeight(l), h)
    88  	l2 := hash.HashInterNode(l1, ledger.GetDefaultHashForHeight(l+1))
    89  	l3 := hash.HashInterNode(ledger.GetDefaultHashForHeight(l+2), l2)
    90  	result := ledger.ComputeCompactValue(path, v, nodeHeight)
    91  	assert.Equal(t, l3, result)
    92  }
    93  
    94  func BenchmarkHash(b *testing.B) {
    95  
    96  	var h1, h2 hash.Hash
    97  	_, _ = rand.Read(h1[:])
    98  	_, _ = rand.Read(h2[:])
    99  
   100  	// customized sha3 for ledger
   101  	b.Run("LedgerSha3", func(b *testing.B) {
   102  		b.ResetTimer()
   103  		for i := 0; i < b.N; i++ {
   104  			_ = hash.HashInterNode(h1, h2)
   105  		}
   106  		b.StopTimer()
   107  	})
   108  
   109  	// flow crypto generic sha3
   110  	b.Run("GenericSha3", func(b *testing.B) {
   111  		b.ResetTimer()
   112  		for i := 0; i < b.N; i++ {
   113  			hasher := cryhash.NewSHA3_256()
   114  			_, _ = hasher.Write(h1[:])
   115  			_, _ = hasher.Write(h2[:])
   116  			_ = hasher.SumHash()
   117  		}
   118  		b.StopTimer()
   119  	})
   120  }