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 }