diff --git a/accept.go b/accept.go index 5e66436f..8908aa8f 100644 --- a/accept.go +++ b/accept.go @@ -60,16 +60,10 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { } // Ensure all transactions in the block are finalized. - for i, tx := range block.MsgBlock().Transactions { + for _, tx := range block.Transactions() { if !IsFinalizedTransaction(tx, blockHeight, blockHeader.Timestamp) { - // Use the TxSha function from the block rather - // than the transaction itself since the block version - // is cached. Also, it's safe to ignore the error here - // since the only reason TxSha can fail is if the index - // is out of range which is impossible here. - txSha, _ := block.TxSha(i) str := fmt.Sprintf("block contains unfinalized "+ - "transaction %v", txSha) + "transaction %v", tx.Sha()) return RuleError(str) } } @@ -129,7 +123,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { if prevNode != nil { expectedHeight = prevNode.height + 1 } - coinbaseTx := block.MsgBlock().Transactions[0] + coinbaseTx := block.Transactions()[0] err := checkSerializedHeight(coinbaseTx, expectedHeight) if err != nil { return err diff --git a/checkpoints.go b/checkpoints.go index 4f4c4019..a0b3ff84 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -154,11 +154,11 @@ func (b *BlockChain) findLatestKnownCheckpoint() (*btcutil.Block, error) { // isNonstandardTransaction determines whether a transaction contains any // scripts which are not one of the standard types. -func isNonstandardTransaction(tx *btcwire.MsgTx) bool { +func isNonstandardTransaction(tx *btcutil.Tx) bool { // TODO(davec): Should there be checks for the input signature scripts? // Check all of the output public key scripts for non-standard scripts. - for _, txOut := range tx.TxOut { + for _, txOut := range tx.MsgTx().TxOut { scriptClass := btcscript.GetScriptClass(txOut.PkScript) if scriptClass == btcscript.NonStandardTy { return true @@ -235,7 +235,7 @@ func (b *BlockChain) IsCheckpointCandidate(block *btcutil.Block) (bool, error) { // A checkpoint must have transactions that only contain standard // scripts. - for _, tx := range block.MsgBlock().Transactions { + for _, tx := range block.Transactions() { if isNonstandardTransaction(tx) { return false, nil } diff --git a/internal_test.go b/internal_test.go index b919d543..282804f9 100644 --- a/internal_test.go +++ b/internal_test.go @@ -13,7 +13,6 @@ package btcchain import ( "github.com/conformal/btcutil" - "github.com/conformal/btcwire" "time" ) @@ -37,6 +36,6 @@ func TstTimeSorter(times []time.Time) timeSorter { // TstCheckSerializedHeight makes the internal checkSerializedHeight function // available to the test package. -func TstCheckSerializedHeight(coinbaseTx *btcwire.MsgTx, wantHeight int64) error { +func TstCheckSerializedHeight(coinbaseTx *btcutil.Tx, wantHeight int64) error { return checkSerializedHeight(coinbaseTx, wantHeight) } diff --git a/merkle.go b/merkle.go index e0aa0053..b0e2f1d7 100644 --- a/merkle.go +++ b/merkle.go @@ -69,21 +69,15 @@ func hashMerkleBranches(left *btcwire.ShaHash, right *btcwire.ShaHash) *btcwire. // 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) + nextPoT := nextPowerOfTwo(len(block.Transactions())) 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 + for i, tx := range block.Transactions() { + merkles[i] = tx.Sha() } // Start the array offset after the last transaction and adjusted to the diff --git a/scriptval.go b/scriptval.go index 8426e14f..64e51be4 100644 --- a/scriptval.go +++ b/scriptval.go @@ -19,16 +19,10 @@ type txValidate struct { err error } -// txProcessList -type txProcessList struct { - txsha btcwire.ShaHash - tx *btcwire.MsgTx -} - // validateTxIn validates a the script pair for the passed spending transaction // (along with the specific input index) and origin transaction (with the // specific output index). -func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *btcwire.MsgTx, originTx *btcwire.MsgTx, flags btcscript.ScriptFlags) error { +func validateTxIn(txInIdx int, txin *btcwire.TxIn, tx *btcutil.Tx, originTx *btcutil.Tx, flags btcscript.ScriptFlags) error { // If the input transaction has no previous input, there is nothing // to check. originTxIdx := txin.PreviousOutpoint.Index @@ -36,17 +30,17 @@ func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *b return nil } - if originTxIdx >= uint32(len(originTx.TxOut)) { + if originTxIdx >= uint32(len(originTx.MsgTx().TxOut)) { originTxSha := &txin.PreviousOutpoint.Hash log.Warnf("unable to locate source tx %v spending tx %v", - originTxSha, &txSha) + originTxSha, tx.Sha()) return fmt.Errorf("invalid index %x", originTxIdx) } sigScript := txin.SignatureScript - pkScript := originTx.TxOut[originTxIdx].PkScript - engine, err := btcscript.NewScript(sigScript, pkScript, txInIdx, tx, - flags) + pkScript := originTx.MsgTx().TxOut[originTxIdx].PkScript + engine, err := btcscript.NewScript(sigScript, pkScript, txInIdx, + tx.MsgTx(), flags) if err != nil { return err } @@ -62,9 +56,9 @@ func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *b // ValidateTransactionScripts validates the scripts for the passed transaction // using multiple goroutines. -func ValidateTransactionScripts(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, txStore TxStore, flags btcscript.ScriptFlags) (err error) { +func ValidateTransactionScripts(tx *btcutil.Tx, txStore TxStore, flags btcscript.ScriptFlags) (err error) { c := make(chan txValidate) - job := tx.TxIn + job := tx.MsgTx().TxIn resultErrors := make([]error, len(job)) var currentItem int @@ -72,12 +66,12 @@ func ValidateTransactionScripts(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, txSt processFunc := func(txInIdx int) { log.Tracef("validating tx %v input %v len %v", - txHash, currentItem, len(job)) + tx.Sha(), currentItem, len(job)) txin := job[txInIdx] originTxSha := &txin.PreviousOutpoint.Hash origintxidx := txin.PreviousOutpoint.Index - var originTx *btcwire.MsgTx + var originTx *btcutil.Tx if origintxidx != math.MaxUint32 { txInfo, ok := txStore[*originTxSha] if !ok { @@ -87,8 +81,7 @@ func ValidateTransactionScripts(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, txSt } originTx = txInfo.Tx } - err := validateTxIn(txInIdx, job[txInIdx], txHash, tx, originTx, - flags) + err := validateTxIn(txInIdx, txin, tx, originTx, flags) r := txValidate{txInIdx, err} c <- r } @@ -114,7 +107,8 @@ func ValidateTransactionScripts(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, txSt } for i := 0; i < len(job); i++ { if resultErrors[i] != nil { - log.Warnf("tx %v failed input %v, err %v", txHash, i, resultErrors[i]) + log.Warnf("tx %v failed input %v, err %v", tx.Sha(), i, + resultErrors[i]) } } return @@ -130,17 +124,14 @@ func checkBlockScripts(block *btcutil.Block, txStore TxStore) error { flags |= btcscript.ScriptBip16 } - txList := block.MsgBlock().Transactions + txList := block.Transactions() c := make(chan txValidate) resultErrors := make([]error, len(txList)) var currentItem int var completedItems int processFunc := func(txIdx int) { - tx := txList[txIdx] - txHash, _ := block.TxSha(txIdx) - - err := ValidateTransactionScripts(tx, txHash, txStore, flags) + err := ValidateTransactionScripts(txList[txIdx], txStore, flags) r := txValidate{txIdx, err} c <- r } diff --git a/txlookup.go b/txlookup.go index 193f5331..3d5c1df2 100644 --- a/txlookup.go +++ b/txlookup.go @@ -14,7 +14,7 @@ import ( // TxData contains contextual information about transactions such as which block // they were found in and whether or not the outputs are spent. type TxData struct { - Tx *btcwire.MsgTx + Tx *btcutil.Tx Hash *btcwire.ShaHash BlockHeight int64 Spent []bool @@ -33,23 +33,19 @@ type TxStore map[btcwire.ShaHash]*TxData func connectTransactions(txStore TxStore, block *btcutil.Block) error { // Loop through all of the transactions in the block to see if any of // them are ones we need to update and spend based on the results map. - for i, tx := range block.MsgBlock().Transactions { - txHash, err := block.TxSha(i) - if err != nil { - return err - } - + for _, tx := range block.Transactions() { // Update the transaction store with the transaction information // if it's one of the requested transactions. - if txD, exists := txStore[*txHash]; exists { + msgTx := tx.MsgTx() + if txD, exists := txStore[*tx.Sha()]; exists { txD.Tx = tx txD.BlockHeight = block.Height() - txD.Spent = make([]bool, len(tx.TxOut)) + txD.Spent = make([]bool, len(msgTx.TxOut)) txD.Err = nil } // Spend the origin transaction output. - for _, txIn := range tx.TxIn { + for _, txIn := range msgTx.TxIn { originHash := &txIn.PreviousOutpoint.Hash originIndex := txIn.PreviousOutpoint.Index if originTx, exists := txStore[*originHash]; exists { @@ -67,18 +63,13 @@ func connectTransactions(txStore TxStore, block *btcutil.Block) error { func disconnectTransactions(txStore TxStore, block *btcutil.Block) error { // Loop through all of the transactions in the block to see if any of // them are ones that need to be undone based on the transaction store. - for i, tx := range block.MsgBlock().Transactions { - txHash, err := block.TxSha(i) - if err != nil { - return err - } - + for _, tx := range block.Transactions() { // Clear this transaction from the transaction store if needed. // Only clear it rather than deleting it because the transaction // connect code relies on its presence to decide whether or not // to update the store and any transactions which exist on both // sides of a fork would otherwise not be updated. - if txD, exists := txStore[*txHash]; exists { + if txD, exists := txStore[*tx.Sha()]; exists { txD.Tx = nil txD.BlockHeight = 0 txD.Spent = nil @@ -86,7 +77,7 @@ func disconnectTransactions(txStore TxStore, block *btcutil.Block) error { } // Unspend the origin transaction output. - for _, txIn := range tx.TxIn { + for _, txIn := range tx.MsgTx().TxIn { originHash := &txIn.PreviousOutpoint.Hash originIndex := txIn.PreviousOutpoint.Index originTx, exists := txStore[*originHash] @@ -146,7 +137,7 @@ func fetchTxStoreMain(db btcdb.Db, txSet map[btcwire.ShaHash]bool, includeSpent // cause subtle errors, so avoid the potential altogether. txD.Err = txReply.Err if txReply.Err == nil { - txD.Tx = txReply.Tx + txD.Tx = btcutil.NewTx(txReply.Tx) txD.BlockHeight = txReply.Height txD.Spent = make([]bool, len(txReply.TxSpent)) copy(txD.Spent, txReply.TxSpent) @@ -240,14 +231,9 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc // this block could be referencing other transactions earlier in this // block which are not yet in the chain. txInFlight := map[btcwire.ShaHash]int{} - transactions := block.MsgBlock().Transactions - for i := range transactions { - // Get transaction hash. It's safe to ignore the error since - // it's already cached in the nominal code path and the only - // way it can fail is if the index is out of range which is - // impossible here. - txHash, _ := block.TxSha(i) - txInFlight[*txHash] = i + transactions := block.Transactions() + for i, tx := range transactions { + txInFlight[*tx.Sha()] = i } // Loop through all of the transaction inputs (except for the coinbase @@ -256,7 +242,7 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc txNeededSet := make(map[btcwire.ShaHash]bool) txStore := make(TxStore) for i, tx := range transactions[1:] { - for _, txIn := range tx.TxIn { + for _, txIn := range tx.MsgTx().TxIn { // Add an entry to the transaction store for the needed // transaction with it set to missing by default. originHash := &txIn.PreviousOutpoint.Hash @@ -279,7 +265,7 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc originTx := transactions[inFlightIndex] txD.Tx = originTx txD.BlockHeight = node.height - txD.Spent = make([]bool, len(originTx.TxOut)) + txD.Spent = make([]bool, len(originTx.MsgTx().TxOut)) txD.Err = nil } else { txNeededSet[*originHash] = true @@ -306,18 +292,13 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc // passed transaction from the point of view of the end of the main chain. It // also attempts to fetch the transaction itself so the returned TxStore can be // examined for duplicate transactions. -func (b *BlockChain) FetchTransactionStore(tx *btcwire.MsgTx) (TxStore, error) { - txHash, err := tx.TxSha() - if err != nil { - return nil, err - } - +func (b *BlockChain) FetchTransactionStore(tx *btcutil.Tx) (TxStore, error) { // Create a set of needed transactions from the transactions referenced // by the inputs of the passed transaction. Also, add the passed // transaction itself as a way for the caller to detect duplicates. txNeededSet := make(map[btcwire.ShaHash]bool) - txNeededSet[txHash] = true - for _, txIn := range tx.TxIn { + txNeededSet[*tx.Sha()] = true + for _, txIn := range tx.MsgTx().TxIn { txNeededSet[txIn.PreviousOutpoint.Hash] = true } diff --git a/validate.go b/validate.go index 00ed8ff2..88b677fd 100644 --- a/validate.go +++ b/validate.go @@ -94,7 +94,9 @@ func isNullOutpoint(outpoint *btcwire.OutPoint) bool { // represented in the block chain by a transaction with a single input that has // a previous output transaction index set to the maximum value along with a // zero hash. -func IsCoinBase(msgTx *btcwire.MsgTx) bool { +func IsCoinBase(tx *btcutil.Tx) bool { + msgTx := tx.MsgTx() + // A coin base must only have one transaction input. if len(msgTx.TxIn) != 1 { return false @@ -111,7 +113,9 @@ func IsCoinBase(msgTx *btcwire.MsgTx) bool { } // IsFinalizedTransaction determines whether or not a transaction is finalized. -func IsFinalizedTransaction(msgTx *btcwire.MsgTx, blockHeight int64, blockTime time.Time) bool { +func IsFinalizedTransaction(tx *btcutil.Tx, blockHeight int64, blockTime time.Time) bool { + msgTx := tx.MsgTx() + // Lock time of zero means the transaction is finalized. lockTime := msgTx.LockTime if lockTime == 0 { @@ -175,14 +179,15 @@ func calcBlockSubsidy(height int64) int64 { // CheckTransactionSanity performs some preliminary checks on a transaction to // ensure it is sane. These checks are context free. -func CheckTransactionSanity(tx *btcwire.MsgTx) error { +func CheckTransactionSanity(tx *btcutil.Tx) error { // A transaction must have at least one input. - if len(tx.TxIn) == 0 { + msgTx := tx.MsgTx() + if len(msgTx.TxIn) == 0 { return RuleError("transaction has no inputs") } // A transaction must have at least one output. - if len(tx.TxOut) == 0 { + if len(msgTx.TxOut) == 0 { return RuleError("transaction has no outputs") } @@ -198,7 +203,7 @@ func CheckTransactionSanity(tx *btcwire.MsgTx) error { // as a satoshi. One bitcoin is a quantity of satoshi as defined by the // satoshiPerBitcoin constant. var totalSatoshi int64 - for _, txOut := range tx.TxOut { + for _, txOut := range msgTx.TxOut { satoshi := txOut.Value if satoshi < 0 { str := fmt.Sprintf("transaction output has negative "+ @@ -231,7 +236,7 @@ func CheckTransactionSanity(tx *btcwire.MsgTx) error { // Check for duplicate transaction inputs. existingTxOut := make(map[btcwire.OutPoint]bool) - for _, txIn := range tx.TxIn { + for _, txIn := range msgTx.TxIn { if _, exists := existingTxOut[txIn.PreviousOutpoint]; exists { return RuleError("transaction contains duplicate outpoint") } @@ -240,7 +245,7 @@ func CheckTransactionSanity(tx *btcwire.MsgTx) error { // Coinbase script length must be between min and max length. if IsCoinBase(tx) { - slen := len(tx.TxIn[0].SignatureScript) + slen := len(msgTx.TxIn[0].SignatureScript) if slen < minCoinbaseScriptLen || slen > maxCoinbaseScriptLen { str := fmt.Sprintf("coinbase transaction script length "+ "of %d is out of range (min: %d, max: %d)", @@ -250,7 +255,7 @@ func CheckTransactionSanity(tx *btcwire.MsgTx) error { } else { // Previous transaction outputs referenced by the inputs to this // transaction must not be null. - for _, txIn := range tx.TxIn { + for _, txIn := range msgTx.TxIn { prevOut := &txIn.PreviousOutpoint if isNullOutpoint(prevOut) { return RuleError("transaction input refers to " + @@ -302,7 +307,9 @@ func (b *BlockChain) checkProofOfWork(block *btcutil.Block) error { // input and output scripts in the provided transaction. This uses the // quicker, but imprecise, signature operation counting mechanism from // btcscript. -func countSigOps(msgTx *btcwire.MsgTx) int { +func countSigOps(tx *btcutil.Tx) int { + msgTx := tx.MsgTx() + // Accumulate the number of signature operations in all transaction // inputs. totalSigOps := 0 @@ -325,20 +332,15 @@ func countSigOps(msgTx *btcwire.MsgTx) int { // transactions which are of the pay-to-script-hash type. This uses the // precise, signature operation counting mechanism from btcscript which requires // access to the input transaction scripts. -func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore TxStore) (int, error) { +func countP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, error) { // Coinbase transactions have no interesting inputs. if isCoinBaseTx { return 0, nil } - // TODO(davec): Need to pass the cached version in. - txHash, err := msgTx.TxSha() - if err != nil { - return 0, err - } - // Accumulate the number of signature operations in all transaction // inputs. + msgTx := tx.MsgTx() totalSigOps := 0 for _, txIn := range msgTx.TxIn { // Ensure the referenced input transaction is available. @@ -347,23 +349,24 @@ func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore TxStore) ( if !exists || originTx.Err != nil || originTx.Tx == nil { str := fmt.Sprintf("unable to find input transaction "+ "%v referenced from transaction %v", txInHash, - txHash) + tx.Sha()) return 0, RuleError(str) } + originMsgTx := originTx.Tx.MsgTx() // Ensure the output index in the referenced transaction is // available. originTxIndex := txIn.PreviousOutpoint.Index - if originTxIndex >= uint32(len(originTx.Tx.TxOut)) { + if originTxIndex >= uint32(len(originMsgTx.TxOut)) { str := fmt.Sprintf("out of bounds input index %d in "+ "transaction %v referenced from transaction %v", - originTxIndex, txInHash, txHash) + originTxIndex, txInHash, tx.Sha()) return 0, RuleError(str) } // We're only interested in pay-to-script-hash types, so skip // this input if it's not one. - pkScript := originTx.Tx.TxOut[originTxIndex].PkScript + pkScript := originMsgTx.TxOut[originTxIndex].PkScript if !btcscript.IsPayToScriptHash(pkScript) { continue } @@ -407,8 +410,7 @@ func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { } // Ensure the block time is not more than 2 hours in the future. - msgBlock := block.MsgBlock() - header := &msgBlock.Header + header := &block.MsgBlock().Header if header.Timestamp.After(time.Now().Add(time.Hour * 2)) { str := fmt.Sprintf("block timestamp of %v is too far in the "+ "future", header.Timestamp) @@ -416,7 +418,7 @@ func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { } // A block must have at least one transaction. - transactions := msgBlock.Transactions + transactions := block.Transactions() if len(transactions) == 0 { return RuleError("block does not contain any transactions") } @@ -463,11 +465,8 @@ func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { // since the transaction hashes are already cached due to building the // merkle tree above. existingTxHashes := make(map[btcwire.ShaHash]bool) - txShas, err := block.TxShas() - if err != nil { - return err - } - for _, hash := range txShas { + for _, tx := range transactions { + hash := tx.Sha() if _, exists := existingTxHashes[*hash]; exists { str := fmt.Sprintf("block contains duplicate "+ "transaction %v", hash) @@ -497,8 +496,8 @@ func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { // checkSerializedHeight checks if the signature script in the passed // transaction starts with the serialized block height of wantHeight. -func checkSerializedHeight(coinbaseTx *btcwire.MsgTx, wantHeight int64) error { - sigScript := coinbaseTx.TxIn[0].SignatureScript +func checkSerializedHeight(coinbaseTx *btcutil.Tx, wantHeight int64) error { + sigScript := coinbaseTx.MsgTx().TxIn[0].SignatureScript if len(sigScript) < 1 { str := "the coinbase signature script for blocks of " + "version %d or greater must start with the " + @@ -601,20 +600,15 @@ func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { // amount, and verifying the signatures to prove the spender was the owner of // the bitcoins and therefore allowed to spend them. As it checks the inputs, // it also calculates the total fees for the transaction and returns that value. -func CheckTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore TxStore) (int64, error) { +func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (int64, error) { // Coinbase transactions have no inputs. if IsCoinBase(tx) { return 0, nil } - // TODO(davec): Need to pass the cached version in. - txHash, err := tx.TxSha() - if err != nil { - return 0, err - } - + txHash := tx.Sha() var totalSatoshiIn int64 - for _, txIn := range tx.TxIn { + for _, txIn := range tx.MsgTx().TxIn { // Ensure the input is available. txInHash := &txIn.PreviousOutpoint.Hash originTx, exists := txStore[*txInHash] @@ -659,7 +653,7 @@ func CheckTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore TxStore) // a transaction are in a unit value known as a satoshi. One // bitcoin is a quantity of satoshi as defined by the // satoshiPerBitcoin constant. - originTxSatoshi := originTx.Tx.TxOut[originTxIndex].Value + originTxSatoshi := originTx.Tx.MsgTx().TxOut[originTxIndex].Value if originTxSatoshi < 0 { str := fmt.Sprintf("transaction output has negative "+ "value of %v", originTxSatoshi) @@ -693,7 +687,7 @@ func CheckTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore TxStore) // to ignore overflow and out of range errors here because those error // conditions would have already been caught by checkTransactionSanity. var totalSatoshiOut int64 - for _, txOut := range tx.TxOut { + for _, txOut := range tx.MsgTx().TxOut { totalSatoshiOut += txOut.Value } @@ -771,7 +765,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er // expands the count to include a precise count of pay-to-script-hash // signature operations in each of the input transaction public key // scripts. - transactions := block.MsgBlock().Transactions + transactions := block.Transactions() totalSigOps := 0 for i, tx := range transactions { numsigOps := countSigOps(tx) @@ -832,7 +826,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er // errors here because those error conditions would have already been // caught by checkTransactionSanity. var totalSatoshiOut int64 - for _, txOut := range transactions[0].TxOut { + for _, txOut := range transactions[0].MsgTx().TxOut { totalSatoshiOut += txOut.Value } expectedSatoshiOut := calcBlockSubsidy(node.height) + totalFees diff --git a/validate_test.go b/validate_test.go index 5cde8f1a..004c490b 100644 --- a/validate_test.go +++ b/validate_test.go @@ -66,8 +66,9 @@ func TestCheckSerializedHeight(t *testing.T) { t.Logf("Running %d tests", len(tests)) for i, test := range tests { - tx := coinbaseTx.Copy() - tx.TxIn[0].SignatureScript = test.sigScript + msgTx := coinbaseTx.Copy() + msgTx.TxIn[0].SignatureScript = test.sigScript + tx := btcutil.NewTx(msgTx) err := btcchain.TstCheckSerializedHeight(tx, test.wantHeight) if reflect.TypeOf(err) != reflect.TypeOf(test.err) {