From 279308288cf533a3c7c5c0dba643d83677d96fbd Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 10 Mar 2015 00:41:19 -0500 Subject: [PATCH] blockchain: Provide new IsCoinBaseTx function. This commit adds a new function to the blockchain package named IsCoinBaseTx which performs the same function as IsCoinBase except it takes raw wire transactions as opposed to the higher level util transactions. While here, it also adds a file for benchmarks along with a couple of benchmarks for the IsCoinBase and IsCoinBaseTx functions. Finally, the function was very slightly optimized: BenchmarkIsCoinBaseOld 100000000 10.7 ns/op 0 B/op 0 allocs/op BenchmarkIsCoinBaseNew 200000000 6.05 ns/op 0 B/op 0 allocs/op --- blockchain/bench_test.go | 32 ++++++++++++++++++++++++++++++++ blockchain/validate.go | 31 ++++++++++++++++++++++--------- 2 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 blockchain/bench_test.go diff --git a/blockchain/bench_test.go b/blockchain/bench_test.go new file mode 100644 index 00000000..f7872569 --- /dev/null +++ b/blockchain/bench_test.go @@ -0,0 +1,32 @@ +// Copyright (c) 2015 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package blockchain_test + +import ( + "testing" + + "github.com/btcsuite/btcd/blockchain" + "github.com/btcsuite/btcutil" +) + +// BenchmarkIsCoinBase performs a simple benchmark against the IsCoinBase +// function. +func BenchmarkIsCoinBase(b *testing.B) { + tx, _ := btcutil.NewBlock(&Block100000).Tx(1) + b.ResetTimer() + for i := 0; i < b.N; i++ { + blockchain.IsCoinBase(tx) + } +} + +// BenchmarkIsCoinBaseTx performs a simple benchmark against the IsCoinBaseTx +// function. +func BenchmarkIsCoinBaseTx(b *testing.B) { + tx := Block100000.Transactions[1] + b.ResetTimer() + for i := 0; i < b.N; i++ { + blockchain.IsCoinBaseTx(tx) + } +} diff --git a/blockchain/validate.go b/blockchain/validate.go index df6284c4..8604b9ef 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.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. @@ -89,14 +89,15 @@ func isNullOutpoint(outpoint *wire.OutPoint) bool { return false } -// IsCoinBase determines whether or not a transaction is a coinbase. A coinbase -// is a special transaction created by miners that has no inputs. This is -// 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 +// IsCoinBaseTx determines whether or not a transaction is a coinbase. A +// coinbase is a special transaction created by miners that has no inputs. This +// is 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(tx *btcutil.Tx) bool { - msgTx := tx.MsgTx() - +// +// This function only differs from IsCoinBase in that it works with a raw wire +// transaction as opposed to a higher level util transaction. +func IsCoinBaseTx(msgTx *wire.MsgTx) bool { // A coin base must only have one transaction input. if len(msgTx.TxIn) != 1 { return false @@ -104,7 +105,7 @@ func IsCoinBase(tx *btcutil.Tx) bool { // The previous output of a coin base must have a max value index and // a zero hash. - prevOut := msgTx.TxIn[0].PreviousOutPoint + prevOut := &msgTx.TxIn[0].PreviousOutPoint if prevOut.Index != math.MaxUint32 || !prevOut.Hash.IsEqual(zeroHash) { return false } @@ -112,6 +113,18 @@ func IsCoinBase(tx *btcutil.Tx) bool { return true } +// IsCoinBase determines whether or not a transaction is a coinbase. A coinbase +// is a special transaction created by miners that has no inputs. This is +// 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. +// +// This function only differs from IsCoinBaseTx in that it works with a higher +// level util transaction as opposed to a raw wire transaction. +func IsCoinBase(tx *btcutil.Tx) bool { + return IsCoinBaseTx(tx.MsgTx()) +} + // IsFinalizedTransaction determines whether or not a transaction is finalized. func IsFinalizedTransaction(tx *btcutil.Tx, blockHeight int64, blockTime time.Time) bool { msgTx := tx.MsgTx()