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  }