github.com/lbryio/lbcd@v0.22.119/blockchain/merkle.go (about) 1 // Copyright (c) 2013-2016 The btcsuite developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package blockchain 6 7 import ( 8 "bytes" 9 "fmt" 10 "math" 11 12 "github.com/lbryio/lbcd/chaincfg/chainhash" 13 "github.com/lbryio/lbcd/txscript" 14 "github.com/lbryio/lbcd/wire" 15 btcutil "github.com/lbryio/lbcutil" 16 ) 17 18 const ( 19 // CoinbaseWitnessDataLen is the required length of the only element within 20 // the coinbase's witness data if the coinbase transaction contains a 21 // witness commitment. 22 CoinbaseWitnessDataLen = 32 23 24 // CoinbaseWitnessPkScriptLength is the length of the public key script 25 // containing an OP_RETURN, the WitnessMagicBytes, and the witness 26 // commitment itself. In order to be a valid candidate for the output 27 // containing the witness commitment 28 CoinbaseWitnessPkScriptLength = 38 29 ) 30 31 var ( 32 // WitnessMagicBytes is the prefix marker within the public key script 33 // of a coinbase output to indicate that this output holds the witness 34 // commitment for a block. 35 WitnessMagicBytes = []byte{ 36 txscript.OP_RETURN, 37 txscript.OP_DATA_36, 38 0xaa, 39 0x21, 40 0xa9, 41 0xed, 42 } 43 ) 44 45 // nextPowerOfTwo returns the next highest power of two from a given number if 46 // it is not already a power of two. This is a helper function used during the 47 // calculation of a merkle tree. 48 func nextPowerOfTwo(n int) int { 49 // Return the number if it's already a power of 2. 50 if n&(n-1) == 0 { 51 return n 52 } 53 54 // Figure out and return the next power of two. 55 exponent := uint(math.Log2(float64(n))) + 1 56 return 1 << exponent // 2^exponent 57 } 58 59 // HashMerkleBranches takes two hashes, treated as the left and right tree 60 // nodes, and returns the hash of their concatenation. This is a helper 61 // function used to aid in the generation of a merkle tree. 62 func HashMerkleBranches(left *chainhash.Hash, right *chainhash.Hash) *chainhash.Hash { 63 // Concatenate the left and right nodes. 64 var hash [chainhash.HashSize * 2]byte 65 copy(hash[:chainhash.HashSize], left[:]) 66 copy(hash[chainhash.HashSize:], right[:]) 67 68 newHash := chainhash.DoubleHashH(hash[:]) 69 return &newHash 70 } 71 72 // BuildMerkleTreeStore creates a merkle tree from a slice of transactions, 73 // stores it using a linear array, and returns a slice of the backing array. A 74 // linear array was chosen as opposed to an actual tree structure since it uses 75 // about half as much memory. The following describes a merkle tree and how it 76 // is stored in a linear array. 77 // 78 // A merkle tree is a tree in which every non-leaf node is the hash of its 79 // children nodes. A diagram depicting how this works for bitcoin transactions 80 // where h(x) is a double sha256 follows: 81 // 82 // root = h1234 = h(h12 + h34) 83 // / \ 84 // h12 = h(h1 + h2) h34 = h(h3 + h4) 85 // / \ / \ 86 // h1 = h(tx1) h2 = h(tx2) h3 = h(tx3) h4 = h(tx4) 87 // 88 // The above stored as a linear array is as follows: 89 // 90 // [h1 h2 h3 h4 h12 h34 root] 91 // 92 // As the above shows, the merkle root is always the last element in the array. 93 // 94 // The number of inputs is not always a power of two which results in a 95 // balanced tree structure as above. In that case, parent nodes with no 96 // children are also zero and parent nodes with only a single left node 97 // are calculated by concatenating the left node with itself before hashing. 98 // Since this function uses nodes that are pointers to the hashes, empty nodes 99 // will be nil. 100 // 101 // The additional bool parameter indicates if we are generating the merkle tree 102 // using witness transaction id's rather than regular transaction id's. This 103 // also presents an additional case wherein the wtxid of the coinbase transaction 104 // is the zeroHash. 105 func BuildMerkleTreeStore(transactions []*btcutil.Tx, witness bool) []*chainhash.Hash { 106 // Calculate how many entries are required to hold the binary merkle 107 // tree as a linear array and create an array of that size. 108 nextPoT := nextPowerOfTwo(len(transactions)) 109 arraySize := nextPoT*2 - 1 110 merkles := make([]*chainhash.Hash, arraySize) 111 112 // Create the base transaction hashes and populate the array with them. 113 for i, tx := range transactions { 114 // If we're computing a witness merkle root, instead of the 115 // regular txid, we use the modified wtxid which includes a 116 // transaction's witness data within the digest. Additionally, 117 // the coinbase's wtxid is all zeroes. 118 switch { 119 case witness && i == 0: 120 var zeroHash chainhash.Hash 121 merkles[i] = &zeroHash 122 case witness: 123 wSha := tx.MsgTx().WitnessHash() 124 merkles[i] = &wSha 125 default: 126 merkles[i] = tx.Hash() 127 } 128 129 } 130 131 // Start the array offset after the last transaction and adjusted to the 132 // next power of two. 133 offset := nextPoT 134 for i := 0; i < arraySize-1; i += 2 { 135 switch { 136 // When there is no left child node, the parent is nil too. 137 case merkles[i] == nil: 138 merkles[offset] = nil 139 140 // When there is no right child, the parent is generated by 141 // hashing the concatenation of the left child with itself. 142 case merkles[i+1] == nil: 143 newHash := HashMerkleBranches(merkles[i], merkles[i]) 144 merkles[offset] = newHash 145 146 // The normal case sets the parent node to the double sha256 147 // of the concatentation of the left and right children. 148 default: 149 newHash := HashMerkleBranches(merkles[i], merkles[i+1]) 150 merkles[offset] = newHash 151 } 152 offset++ 153 } 154 155 return merkles 156 } 157 158 // ExtractWitnessCommitment attempts to locate, and return the witness 159 // commitment for a block. The witness commitment is of the form: 160 // SHA256(witness root || witness nonce). The function additionally returns a 161 // boolean indicating if the witness root was located within any of the txOut's 162 // in the passed transaction. The witness commitment is stored as the data push 163 // for an OP_RETURN with special magic bytes to aide in location. 164 func ExtractWitnessCommitment(tx *btcutil.Tx) ([]byte, bool) { 165 // The witness commitment *must* be located within one of the coinbase 166 // transaction's outputs. 167 if !IsCoinBase(tx) { 168 return nil, false 169 } 170 171 msgTx := tx.MsgTx() 172 for i := len(msgTx.TxOut) - 1; i >= 0; i-- { 173 // The public key script that contains the witness commitment 174 // must shared a prefix with the WitnessMagicBytes, and be at 175 // least 38 bytes. 176 pkScript := msgTx.TxOut[i].PkScript 177 if len(pkScript) >= CoinbaseWitnessPkScriptLength && 178 bytes.HasPrefix(pkScript, WitnessMagicBytes) { 179 180 // The witness commitment itself is a 32-byte hash 181 // directly after the WitnessMagicBytes. The remaining 182 // bytes beyond the 38th byte currently have no consensus 183 // meaning. 184 start := len(WitnessMagicBytes) 185 end := CoinbaseWitnessPkScriptLength 186 return msgTx.TxOut[i].PkScript[start:end], true 187 } 188 } 189 190 return nil, false 191 } 192 193 // ValidateWitnessCommitment validates the witness commitment (if any) found 194 // within the coinbase transaction of the passed block. 195 func ValidateWitnessCommitment(blk *btcutil.Block) error { 196 // If the block doesn't have any transactions at all, then we won't be 197 // able to extract a commitment from the non-existent coinbase 198 // transaction. So we exit early here. 199 if len(blk.Transactions()) == 0 { 200 str := "cannot validate witness commitment of block without " + 201 "transactions" 202 return ruleError(ErrNoTransactions, str) 203 } 204 205 coinbaseTx := blk.Transactions()[0] 206 if len(coinbaseTx.MsgTx().TxIn) == 0 { 207 return ruleError(ErrNoTxInputs, "transaction has no inputs") 208 } 209 210 witnessCommitment, witnessFound := ExtractWitnessCommitment(coinbaseTx) 211 212 // If we can't find a witness commitment in any of the coinbase's 213 // outputs, then the block MUST NOT contain any transactions with 214 // witness data. 215 if !witnessFound { 216 for _, tx := range blk.Transactions() { 217 msgTx := tx.MsgTx() 218 if msgTx.HasWitness() { 219 str := fmt.Sprintf("block contains transaction with witness" + 220 " data, yet no witness commitment present") 221 return ruleError(ErrUnexpectedWitness, str) 222 } 223 } 224 return nil 225 } 226 227 // At this point the block contains a witness commitment, so the 228 // coinbase transaction MUST have exactly one witness element within 229 // its witness data and that element must be exactly 230 // CoinbaseWitnessDataLen bytes. 231 // 232 // Some popular pool software, for example yiimp, uses pre-BIP0141 233 // coinbase struture. In this case, we don't just accept it, but also 234 // turn it into post-BIP0141 format. 235 if len(coinbaseTx.MsgTx().TxIn[0].Witness) == 0 { 236 log.Infof("pre-BIP0141 coinbase transaction detected. Height: %d", blk.Height()) 237 238 var witnessNonce [CoinbaseWitnessDataLen]byte 239 coinbaseTx.MsgTx().TxIn[0].Witness = wire.TxWitness{witnessNonce[:]} 240 blk.MsgBlock().Transactions[0].TxIn[0].Witness = wire.TxWitness{witnessNonce[:]} 241 242 // Clear cached serialized block. 243 blk.SetBytes(nil) 244 } 245 coinbaseWitness := coinbaseTx.MsgTx().TxIn[0].Witness 246 if len(coinbaseWitness) != 1 { 247 str := fmt.Sprintf("the coinbase transaction has %d items in "+ 248 "its witness stack when only one is allowed. Height: %d", 249 len(coinbaseWitness), blk.Height()) 250 return ruleError(ErrInvalidWitnessCommitment, str) 251 } 252 witnessNonce := coinbaseWitness[0] 253 if len(witnessNonce) != CoinbaseWitnessDataLen { 254 str := fmt.Sprintf("the coinbase transaction witness nonce "+ 255 "has %d bytes when it must be %d bytes", 256 len(witnessNonce), CoinbaseWitnessDataLen) 257 return ruleError(ErrInvalidWitnessCommitment, str) 258 } 259 260 // Finally, with the preliminary checks out of the way, we can check if 261 // the extracted witnessCommitment is equal to: 262 // SHA256(witnessMerkleRoot || witnessNonce). Where witnessNonce is the 263 // coinbase transaction's only witness item. 264 witnessMerkleTree := BuildMerkleTreeStore(blk.Transactions(), true) 265 witnessMerkleRoot := witnessMerkleTree[len(witnessMerkleTree)-1] 266 267 var witnessPreimage [chainhash.HashSize * 2]byte 268 copy(witnessPreimage[:], witnessMerkleRoot[:]) 269 copy(witnessPreimage[chainhash.HashSize:], witnessNonce) 270 271 computedCommitment := chainhash.DoubleHashB(witnessPreimage[:]) 272 if !bytes.Equal(computedCommitment, witnessCommitment) { 273 str := fmt.Sprintf("witness commitment does not match: "+ 274 "computed %v, coinbase includes %v", computedCommitment, 275 witnessCommitment) 276 return ruleError(ErrWitnessCommitmentMismatch, str) 277 } 278 279 return nil 280 }