From def0ef6af676990a3113734271136fc757f28cc5 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 28 Feb 2015 12:17:43 -0600 Subject: [PATCH] Use network adjusted time for finalized tx check. This commit modifies finalized transaction check used by the memory pool and block templates to use the network adjusted time instead of the unadjusted local time. This helps keep the transactions accepted to the memory pool, and hence allowed to relay, more consistent across nodes. --- mempool.go | 7 ++++--- mining.go | 14 +++++++++----- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/mempool.go b/mempool.go index 69497ef5..6ed79df4 100644 --- a/mempool.go +++ b/mempool.go @@ -225,7 +225,7 @@ func checkPkScriptStandard(pkScript []byte, scriptClass txscript.ScriptClass) er // finalized, conforming to more stringent size constraints, having scripts // of recognized forms, and not containing "dust" outputs (those that are // so small it costs more to process them than they are worth). -func checkTransactionStandard(tx *btcutil.Tx, height int64) error { +func (mp *txMemPool) checkTransactionStandard(tx *btcutil.Tx, height int64) error { msgTx := tx.MsgTx() // The transaction must be a currently supported version. @@ -238,7 +238,8 @@ func checkTransactionStandard(tx *btcutil.Tx, height int64) error { // The transaction must be finalized to be standard and therefore // considered for inclusion in a block. - if !blockchain.IsFinalizedTransaction(tx, height, time.Now()) { + adjustedTime := mp.server.timeSource.AdjustedTime() + if !blockchain.IsFinalizedTransaction(tx, height, adjustedTime) { return txRuleError(wire.RejectNonstandard, "transaction is not finalized") } @@ -1030,7 +1031,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo // Don't allow non-standard transactions if the network parameters // forbid their relaying. if !activeNetParams.RelayNonStdTxs { - err := checkTransactionStandard(tx, nextBlockHeight) + err := mp.checkTransactionStandard(tx, nextBlockHeight) if err != nil { // Attempt to extract a reject code from the error so // it can be retained. When not possible, fall back to diff --git a/mining.go b/mining.go index f327a49d..13edafe6 100644 --- a/mining.go +++ b/mining.go @@ -282,7 +282,7 @@ func minimumMedianTime(chainState *chainState) (time.Time, error) { // medianAdjustedTime returns the current time adjusted to ensure it is at least // one second after the median timestamp of the last several blocks per the // chain consensus rules. -func medianAdjustedTime(chainState *chainState) (time.Time, error) { +func medianAdjustedTime(chainState *chainState, timeSource blockchain.MedianTimeSource) (time.Time, error) { chainState.Lock() defer chainState.Unlock() if chainState.pastMedianTimeErr != nil { @@ -295,7 +295,7 @@ func medianAdjustedTime(chainState *chainState) (time.Time, error) { // timestamp is truncated to a second boundary before comparison since a // block timestamp does not supported a precision greater than one // second. - newTimestamp := time.Unix(time.Now().Unix(), 0) + newTimestamp := timeSource.AdjustedTime() minTimestamp := chainState.pastMedianTime.Add(time.Second) if newTimestamp.Before(minTimestamp) { newTimestamp = minTimestamp @@ -367,6 +367,7 @@ func medianAdjustedTime(chainState *chainState) (time.Time, error) { // ----------------------------------- -- func NewBlockTemplate(mempool *txMemPool, payToAddress btcutil.Address) (*BlockTemplate, error) { blockManager := mempool.server.blockManager + timeSource := mempool.server.timeSource chainState := &blockManager.chainState chain := blockManager.blockChain @@ -445,7 +446,9 @@ mempoolLoop: minrLog.Tracef("Skipping coinbase tx %s", tx.Sha()) continue } - if !blockchain.IsFinalizedTransaction(tx, nextBlockHeight, time.Now()) { + if !blockchain.IsFinalizedTransaction(tx, nextBlockHeight, + timeSource.AdjustedTime()) { + minrLog.Tracef("Skipping non-finalized tx %s", tx.Sha()) continue } @@ -708,7 +711,7 @@ mempoolLoop: // Calculate the required difficulty for the block. The timestamp // is potentially adjusted to ensure it comes after the median time of // the last several blocks per the chain consensus rules. - ts, err := medianAdjustedTime(chainState) + ts, err := medianAdjustedTime(chainState, timeSource) if err != nil { return nil, err } @@ -766,7 +769,8 @@ func UpdateBlockTime(msgBlock *wire.MsgBlock, bManager *blockManager) error { // The new timestamp is potentially adjusted to ensure it comes after // the median time of the last several blocks per the chain consensus // rules. - newTimestamp, err := medianAdjustedTime(&bManager.chainState) + newTimestamp, err := medianAdjustedTime(&bManager.chainState, + bManager.server.timeSource) if err != nil { return err }