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
This commit is contained in:
Dave Collins 2015-03-10 00:41:19 -05:00
parent 54d7951084
commit 279308288c
2 changed files with 54 additions and 9 deletions

32
blockchain/bench_test.go Normal file
View file

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

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 // Use of this source code is governed by an ISC
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
@ -89,14 +89,15 @@ func isNullOutpoint(outpoint *wire.OutPoint) bool {
return false return false
} }
// IsCoinBase determines whether or not a transaction is a coinbase. A coinbase // IsCoinBaseTx determines whether or not a transaction is a coinbase. A
// is a special transaction created by miners that has no inputs. This is // coinbase is a special transaction created by miners that has no inputs. This
// represented in the block chain by a transaction with a single input that has // is represented in the block chain by a transaction with a single input that
// a previous output transaction index set to the maximum value along with a // has a previous output transaction index set to the maximum value along with a
// zero hash. // 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. // A coin base must only have one transaction input.
if len(msgTx.TxIn) != 1 { if len(msgTx.TxIn) != 1 {
return false 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 // The previous output of a coin base must have a max value index and
// a zero hash. // a zero hash.
prevOut := msgTx.TxIn[0].PreviousOutPoint prevOut := &msgTx.TxIn[0].PreviousOutPoint
if prevOut.Index != math.MaxUint32 || !prevOut.Hash.IsEqual(zeroHash) { if prevOut.Index != math.MaxUint32 || !prevOut.Hash.IsEqual(zeroHash) {
return false return false
} }
@ -112,6 +113,18 @@ func IsCoinBase(tx *btcutil.Tx) bool {
return true 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. // IsFinalizedTransaction determines whether or not a transaction is finalized.
func IsFinalizedTransaction(tx *btcutil.Tx, blockHeight int64, blockTime time.Time) bool { func IsFinalizedTransaction(tx *btcutil.Tx, blockHeight int64, blockTime time.Time) bool {
msgTx := tx.MsgTx() msgTx := tx.MsgTx()