// Copyright (c) 2013 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. package btcchain import ( "github.com/conformal/btcutil" "github.com/conformal/btcwire" "math" ) // nextPowerOfTwo returns the next highest power of two from a given number if // it is not already a power of two. This is a helper function used during the // calculation of a merkle tree. func nextPowerOfTwo(n int) int { // Return the number if it's already a power of 2. if n&(n-1) == 0 { return n } // Figure out and return the next power of two. exponent := uint(math.Log2(float64(n))) + 1 return 1 << exponent // 2^exponent } // hashMerkleBranches takes two hashes, treated as the left and right tree // nodes, and returns the hash of their concatenation. This is a helper // function used to during generatation of a merkle tree. func hashMerkleBranches(left *btcwire.ShaHash, right *btcwire.ShaHash) *btcwire.ShaHash { // Concatenate the left and right nodes. var sha [btcwire.HashSize * 2]byte copy(sha[:btcwire.HashSize], left.Bytes()) copy(sha[btcwire.HashSize:], right.Bytes()) // Create a new sha hash from the double sha 256. Ignore the error // here since SetBytes can't fail here due to the fact DoubleSha256 // always returns a []byte of the right size regardless of input. newSha, _ := btcwire.NewShaHash(btcwire.DoubleSha256(sha[:])) return newSha } // BuildMerkleTreeStore creates a merkle tree from block, stores it using a // linear array, and returns a slice of the backing array. A linear array was // chosen as opposed to an actual tree structure since it uses about half as // much memory. The following describes a merkle tree and how it is stored in // a linear array. // // A merkle tree is a tree in which every non-leaf node is the hash of its // children nodes. A diagram depicting how this works for bitcoin transactions // where h(x) is a double sha256 follows: // // root = h1234 = h(h12 + h34) // / \ // h12 = h(h1 + h2) h34 = h(h3 + h4) // / \ / \ // h1 = h(tx1) h2 = h(tx2) h3 = h(tx3) h4 = h(tx4) // // The above stored as a linear array is as follows: // // [h1 h2 h3 h4 h12 h34 root] // // As the above shows, the merkle root is always the last element in the array. // // The number of inputs is not always a power of two which results in a // balanced tree structure as above. In that case, parent nodes with no // children are also zero and parent nodes with only a single left node // are calculated by concatenating the left node with itself before hashing. // Since this function uses nodes that are pointers to the hashes, empty nodes // will be nil. func BuildMerkleTreeStore(block *btcutil.Block) []*btcwire.ShaHash { numTransactions := len(block.MsgBlock().Transactions) // Calculate how many entries are required to hold the binary merkle // tree as a linear array and create an array of that size. nextPoT := nextPowerOfTwo(numTransactions) arraySize := nextPoT*2 - 1 merkles := make([]*btcwire.ShaHash, arraySize) // Create the base transaction shas and populate the array with them. for i := 0; i < numTransactions; i++ { // Ignore the error since the only reason TxSha can fail is // if the index is out of range which is impossible here due // to using a loop over the existing transactions. sha, _ := block.TxSha(i) merkles[i] = sha } // Start the array offset after the last transaction and adjusted to the // next power of two. offset := nextPoT for i := 0; i < arraySize-1; i += 2 { switch { // When there is no left child node, the parent is nil too. case merkles[i] == nil: merkles[offset] = nil // When there is no right child, the parent is generated by // hashing the concatenation of the left child with itself. case merkles[i+1] == nil: newSha := hashMerkleBranches(merkles[i], merkles[i]) merkles[offset] = newSha // The normal case sets the parent node to the double sha256 // of the concatentation of the left and right children. default: newSha := hashMerkleBranches(merkles[i], merkles[i+1]) merkles[offset] = newSha } offset++ } return merkles }