From 17da2ba7fa691c666d70948217ffcd5b6ac148f8 Mon Sep 17 00:00:00 2001 From: David Hill Date: Fri, 26 Jun 2015 13:48:10 -0400 Subject: [PATCH] Move IsFinalizedTransaction to txscript. This change moves IsFinalizedTransaction to txscript and also changes the first argument to take a wire.MsgTx instead of btcutil.Tx. This is needed for an upcoming diff in which txscript will require IsFinalizedTransaction and we do not want to import the btcd/blockchain. --- blockchain/validate.go | 37 +------------------------------------ mempool.go | 2 +- mining.go | 2 +- txscript/consensus.go | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 38 deletions(-) diff --git a/blockchain/validate.go b/blockchain/validate.go index 0fc9a949..0ee18deb 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -127,41 +127,6 @@ 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() - - // Lock time of zero means the transaction is finalized. - lockTime := msgTx.LockTime - if lockTime == 0 { - return true - } - - // The lock time field of a transaction is either a block height at - // which the transaction is finalized or a timestamp depending on if the - // value is before the txscript.LockTimeThreshold. When it is under the - // threshold it is a block height. - blockTimeOrHeight := int64(0) - if lockTime < txscript.LockTimeThreshold { - blockTimeOrHeight = blockHeight - } else { - blockTimeOrHeight = blockTime.Unix() - } - if int64(lockTime) < blockTimeOrHeight { - return true - } - - // At this point, the transaction's lock time hasn't occured yet, but - // the transaction might still be finalized if the sequence number - // for all transaction inputs is maxed out. - for _, txIn := range msgTx.TxIn { - if txIn.Sequence != math.MaxUint32 { - return false - } - } - return true -} - // isBIP0030Node returns whether or not the passed node represents one of the // two blocks that violate the BIP0030 rule which prevents transactions from // overwriting old ones. @@ -707,7 +672,7 @@ func (b *BlockChain) checkBlockContext(block *btcutil.Block, prevNode *blockNode // Ensure all transactions in the block are finalized. for _, tx := range block.Transactions() { - if !IsFinalizedTransaction(tx, blockHeight, + if !txscript.IsFinalizedTransaction(tx.MsgTx(), blockHeight, header.Timestamp) { str := fmt.Sprintf("block contains unfinalized "+ diff --git a/mempool.go b/mempool.go index ebcaf5f7..ada0db59 100644 --- a/mempool.go +++ b/mempool.go @@ -237,7 +237,7 @@ func (mp *txMemPool) checkTransactionStandard(tx *btcutil.Tx, height int64) erro // The transaction must be finalized to be standard and therefore // considered for inclusion in a block. adjustedTime := mp.server.timeSource.AdjustedTime() - if !blockchain.IsFinalizedTransaction(tx, height, adjustedTime) { + if !txscript.IsFinalizedTransaction(tx.MsgTx(), height, adjustedTime) { return txRuleError(wire.RejectNonstandard, "transaction is not finalized") } diff --git a/mining.go b/mining.go index 4af91138..0b739111 100644 --- a/mining.go +++ b/mining.go @@ -446,7 +446,7 @@ mempoolLoop: minrLog.Tracef("Skipping coinbase tx %s", tx.Sha()) continue } - if !blockchain.IsFinalizedTransaction(tx, nextBlockHeight, + if !txscript.IsFinalizedTransaction(tx.MsgTx(), nextBlockHeight, timeSource.AdjustedTime()) { minrLog.Tracef("Skipping non-finalized tx %s", tx.Sha()) diff --git a/txscript/consensus.go b/txscript/consensus.go index 1aec5028..de73389c 100644 --- a/txscript/consensus.go +++ b/txscript/consensus.go @@ -4,6 +4,13 @@ package txscript +import ( + "math" + "time" + + "github.com/btcsuite/btcd/wire" +) + const ( // LockTimeThreshold is the number below which a lock time is // interpreted to be a block number. Since an average of one block @@ -12,3 +19,36 @@ const ( // the lock time is a uint32, the max is sometime around 2106. LockTimeThreshold uint32 = 5e8 // Tue Nov 5 00:53:20 1985 UTC ) + +// IsFinalizedTransaction determines whether or not a transaction is finalized. +func IsFinalizedTransaction(msgTx *wire.MsgTx, blockHeight int64, blockTime time.Time) bool { + // Lock time of zero means the transaction is finalized. + lockTime := msgTx.LockTime + if lockTime == 0 { + return true + } + + // The lock time field of a transaction is either a block height at + // which the transaction is finalized or a timestamp depending on if the + // value is before the LockTimeThreshold. When it is under the + // threshold it is a block height. + blockTimeOrHeight := int64(0) + if lockTime < LockTimeThreshold { + blockTimeOrHeight = blockHeight + } else { + blockTimeOrHeight = blockTime.Unix() + } + if int64(lockTime) < blockTimeOrHeight { + return true + } + + // At this point, the transaction's lock time hasn't occured yet, but + // the transaction might still be finalized if the sequence number + // for all transaction inputs is maxed out. + for _, txIn := range msgTx.TxIn { + if txIn.Sequence != math.MaxUint32 { + return false + } + } + return true +}