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.
This commit is contained in:
Dave Collins 2015-02-28 12:17:43 -06:00
parent e0bb106646
commit def0ef6af6
2 changed files with 13 additions and 8 deletions

View file

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

View file

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