From 65eb8020d29635e4b19b9d8c7833d153efbd08d5 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 25 Feb 2015 14:31:46 -0600 Subject: [PATCH] blockchain: Determine script flags sooner. This commit moves the definition of the flags which are needed to check transaction scripts higher up the call stack to pave the way for adding support for v3 blocks. While here, also spruce up a couple of sections. There are no functional changes in this commit. --- blockchain/accept.go | 38 +++++++++++++++--------------------- blockchain/scriptval.go | 11 +++-------- blockchain/scriptval_test.go | 5 ++++- blockchain/validate.go | 9 ++++++++- 4 files changed, 31 insertions(+), 32 deletions(-) diff --git a/blockchain/accept.go b/blockchain/accept.go index 083d2fe12..f0de24322 100644 --- a/blockchain/accept.go +++ b/blockchain/accept.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2014 Conformal Systems LLC. +// Copyright (c) 2013-2015 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -109,36 +109,30 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags) if !fastAdd { // Reject version 1 blocks once a majority of the network has // upgraded. This is part of BIP0034. - if blockHeader.Version < 2 { - if b.isMajorityVersion(2, prevNode, - b.chainParams.BlockRejectNumRequired) { + if blockHeader.Version < 2 && b.isMajorityVersion(2, prevNode, + b.chainParams.BlockRejectNumRequired) { - str := "new blocks with version %d are no " + - "longer valid" - str = fmt.Sprintf(str, blockHeader.Version) - return ruleError(ErrBlockVersionTooOld, str) - } + str := "new blocks with version %d are no longer valid" + str = fmt.Sprintf(str, blockHeader.Version) + return ruleError(ErrBlockVersionTooOld, str) } // Ensure coinbase starts with serialized block heights for // blocks whose version is the serializedHeightVersion or // newer once a majority of the network has upgraded. This is // part of BIP0034. - if blockHeader.Version >= serializedHeightVersion { - if b.isMajorityVersion(serializedHeightVersion, - prevNode, + if blockHeader.Version >= serializedHeightVersion && + b.isMajorityVersion(serializedHeightVersion, prevNode, b.chainParams.BlockEnforceNumRequired) { - expectedHeight := int64(0) - if prevNode != nil { - expectedHeight = prevNode.height + 1 - } - coinbaseTx := block.Transactions()[0] - err := checkSerializedHeight(coinbaseTx, - expectedHeight) - if err != nil { - return err - } + expectedHeight := int64(0) + if prevNode != nil { + expectedHeight = prevNode.height + 1 + } + coinbaseTx := block.Transactions()[0] + err := checkSerializedHeight(coinbaseTx, expectedHeight) + if err != nil { + return err } } } diff --git a/blockchain/scriptval.go b/blockchain/scriptval.go index 17ca45d88..fea983bbf 100644 --- a/blockchain/scriptval.go +++ b/blockchain/scriptval.go @@ -221,13 +221,8 @@ func ValidateTransactionScripts(tx *btcutil.Tx, txStore TxStore, flags txscript. // checkBlockScripts executes and validates the scripts for all transactions in // the passed block. -func checkBlockScripts(block *btcutil.Block, txStore TxStore) error { - // Setup the script validation flags. Blocks created after the BIP0016 - // activation time need to have the pay-to-script-hash checks enabled. - var flags txscript.ScriptFlags - if block.MsgBlock().Header.Timestamp.After(txscript.Bip16Activation) { - flags |= txscript.ScriptBip16 - } +func checkBlockScripts(block *btcutil.Block, txStore TxStore, + scriptFlags txscript.ScriptFlags) error { // Collect all of the transaction inputs and required information for // validation for all transactions in the block into a single slice. @@ -253,7 +248,7 @@ func checkBlockScripts(block *btcutil.Block, txStore TxStore) error { } // Validate all of the inputs. - validator := newTxValidator(txStore, flags) + validator := newTxValidator(txStore, scriptFlags) if err := validator.Validate(txValItems); err != nil { return err } diff --git a/blockchain/scriptval_test.go b/blockchain/scriptval_test.go index 5b893eb12..e9142d0a5 100644 --- a/blockchain/scriptval_test.go +++ b/blockchain/scriptval_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/btcsuite/btcd/blockchain" + "github.com/btcsuite/btcd/txscript" ) // TestCheckBlockScripts ensures that validating the all of the scripts in a @@ -35,7 +36,9 @@ func TestCheckBlockScripts(t *testing.T) { return } - if err := blockchain.TstCheckBlockScripts(blocks[0], txStore); err != nil { + scriptFlags := txscript.ScriptBip16 + err = blockchain.TstCheckBlockScripts(blocks[0], txStore, scriptFlags) + if err != nil { t.Errorf("Transaction script validation failed: %v\n", err) return diff --git a/blockchain/validate.go b/blockchain/validate.go index 60a68530a..cdace9e8d 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -915,12 +915,19 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er runScripts = false } + // Blocks created after the BIP0016 activation time need to have the + // pay-to-script-hash checks enabled. + var scriptFlags txscript.ScriptFlags + if block.MsgBlock().Header.Timestamp.After(txscript.Bip16Activation) { + scriptFlags |= txscript.ScriptBip16 + } + // Now that the inexpensive checks are done and have passed, verify the // transactions are actually allowed to spend the coins by running the // expensive ECDSA signature check scripts. Doing this last helps // prevent CPU exhaustion attacks. if runScripts { - err := checkBlockScripts(block, txInputStore) + err := checkBlockScripts(block, txInputStore, scriptFlags) if err != nil { return err }