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.
This commit is contained in:
Dave Collins 2015-02-25 14:31:46 -06:00
parent 5a800b9580
commit 65eb8020d2
4 changed files with 31 additions and 32 deletions

View file

@ -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
}
}
}

View file

@ -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
}

View file

@ -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

View file

@ -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
}