github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/ledger/common/hash/hash.go (about) 1 package hash 2 3 import ( 4 "encoding/hex" 5 "encoding/json" 6 "fmt" 7 ) 8 9 // HashLen is the ledger default output hash length in bytes 10 const HashLen = 32 11 12 // Hash is the hash type used in all ledger 13 type Hash [HashLen]byte 14 15 func (h Hash) String() string { 16 return hex.EncodeToString(h[:]) 17 } 18 19 func (h Hash) MarshalJSON() ([]byte, error) { 20 return json.Marshal(hex.EncodeToString(h[:])) 21 } 22 23 func (h *Hash) UnmarshalJSON(data []byte) error { 24 var hashHex string 25 if err := json.Unmarshal(data, &hashHex); err != nil { 26 return err 27 } 28 b, err := hex.DecodeString(hashHex) 29 if err != nil { 30 return err 31 } 32 ha, err := ToHash(b) 33 if err != nil { 34 return err 35 } 36 *h = ha 37 return nil 38 } 39 40 // DummyHash is an arbitrary hash value, used in function errors. 41 // DummyHash represents a valid hash value. 42 var DummyHash Hash 43 44 // HashLeaf returns the hash value for leaf nodes. Path is a fixed-length 45 // byte array which should be holding exactly 32 bytes. Note that we don't 46 // include the keys here as they are already included in the path. 47 func HashLeaf(path Hash, value []byte) Hash { 48 hasher := &state{} 49 return hasher.hash256Plus(path, value) // path is 256 bits 50 } 51 52 // HashInterNode returns the hash value for intermediate nodes. hash1 and hash2 53 // are fixed-length byte arrays which should be holding exactly 32 bytes each. 54 func HashInterNode(hash1 Hash, hash2 Hash) Hash { 55 hasher := &state{} 56 return hasher.hash256plus256(hash1, hash2) // hash1 and hash2 are 256 bits 57 } 58 59 // ToHash converts a byte slice to Hash (fixed-length byte array). 60 // It returns an error if the slice has an invalid length. 61 func ToHash(bytes []byte) (Hash, error) { 62 var h Hash 63 if len(bytes) != len(h) { 64 return DummyHash, fmt.Errorf("expecting %d bytes but got %d bytes", len(h), len(bytes)) 65 } 66 copy(h[:], bytes) 67 return h, nil 68 }