github.com/lbryio/lbcd@v0.22.119/claimtrie/node/hashfunc.go (about)

     1  package node
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"encoding/binary"
     6  	"strconv"
     7  
     8  	"github.com/lbryio/lbcd/chaincfg/chainhash"
     9  	"github.com/lbryio/lbcd/wire"
    10  )
    11  
    12  func HashMerkleBranches(left *chainhash.Hash, right *chainhash.Hash) *chainhash.Hash {
    13  	// Concatenate the left and right nodes.
    14  	var hash [chainhash.HashSize * 2]byte
    15  	copy(hash[:chainhash.HashSize], left[:])
    16  	copy(hash[chainhash.HashSize:], right[:])
    17  
    18  	newHash := chainhash.DoubleHashH(hash[:])
    19  	return &newHash
    20  }
    21  
    22  func ComputeMerkleRoot(hashes []*chainhash.Hash) *chainhash.Hash {
    23  	if len(hashes) <= 0 {
    24  		return nil
    25  	}
    26  	for len(hashes) > 1 {
    27  		if (len(hashes) & 1) > 0 { // odd count
    28  			hashes = append(hashes, hashes[len(hashes)-1])
    29  		}
    30  		for i := 0; i < len(hashes); i += 2 { // TODO: parallelize this loop (or use a lib that does it)
    31  			hashes[i>>1] = HashMerkleBranches(hashes[i], hashes[i+1])
    32  		}
    33  		hashes = hashes[:len(hashes)>>1]
    34  	}
    35  	return hashes[0]
    36  }
    37  
    38  func calculateNodeHash(op wire.OutPoint, takeover int32) *chainhash.Hash {
    39  
    40  	txHash := chainhash.DoubleHashH(op.Hash[:])
    41  
    42  	nOut := []byte(strconv.Itoa(int(op.Index)))
    43  	nOutHash := chainhash.DoubleHashH(nOut)
    44  
    45  	buf := make([]byte, 8)
    46  	binary.BigEndian.PutUint64(buf, uint64(takeover))
    47  	heightHash := chainhash.DoubleHashH(buf)
    48  
    49  	h := make([]byte, 0, sha256.Size*3)
    50  	h = append(h, txHash[:]...)
    51  	h = append(h, nOutHash[:]...)
    52  	h = append(h, heightHash[:]...)
    53  
    54  	hh := chainhash.DoubleHashH(h)
    55  
    56  	return &hh
    57  }