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 }