@@ -650,10 +650,35 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
650650 return true ;
651651}
652652
653- bool CheckFinalTx (const CTransaction &tx)
653+ bool CheckFinalTx (const CTransaction &tx, int flags )
654654{
655655 AssertLockHeld (cs_main);
656- return IsFinalTx (tx, chainActive.Height () + 1 , GetAdjustedTime ());
656+
657+ // By convention a negative value for flags indicates that the
658+ // current network-enforced consensus rules should be used. In
659+ // a future soft-fork scenario that would mean checking which
660+ // rules would be enforced for the next block and setting the
661+ // appropriate flags. At the present time no soft-forks are
662+ // scheduled, so no flags are set.
663+ flags = std::max (flags, 0 );
664+
665+ // CheckFinalTx() uses chainActive.Height()+1 to evaluate
666+ // nLockTime because when IsFinalTx() is called within
667+ // CBlock::AcceptBlock(), the height of the block *being*
668+ // evaluated is what is used. Thus if we want to know if a
669+ // transaction can be part of the *next* block, we need to call
670+ // IsFinalTx() with one more than chainActive.Height().
671+ const int nBlockHeight = chainActive.Height () + 1 ;
672+
673+ // Timestamps on the other hand don't get any special treatment,
674+ // because we can't know what timestamp the next block will have,
675+ // and there aren't timestamp applications where it matters.
676+ // However this changes once median past time-locks are enforced:
677+ const int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST)
678+ ? chainActive.Tip ()->GetMedianTimePast ()
679+ : GetAdjustedTime ();
680+
681+ return IsFinalTx (tx, nBlockHeight, nBlockTime);
657682}
658683
659684unsigned int GetLegacySigOpCount (const CTransaction& tx)
@@ -797,7 +822,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
797822 // Only accept nLockTime-using transactions that can be mined in the next
798823 // block; we don't want our mempool filled up with transactions that can't
799824 // be mined yet.
800- if (!CheckFinalTx (tx))
825+ if (!CheckFinalTx (tx, STANDARD_LOCKTIME_VERIFY_FLAGS ))
801826 return state.DoS (0 , false , REJECT_NONSTANDARD, " non-final" );
802827
803828 // is it already in the memory pool?
@@ -2723,10 +2748,15 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
27232748 const Consensus::Params& consensusParams = Params ().GetConsensus ();
27242749
27252750 // Check that all transactions are finalized
2726- BOOST_FOREACH (const CTransaction& tx, block.vtx )
2727- if (!IsFinalTx (tx, nHeight, block.GetBlockTime ())) {
2751+ BOOST_FOREACH (const CTransaction& tx, block.vtx ) {
2752+ int nLockTimeFlags = 0 ;
2753+ int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
2754+ ? pindexPrev->GetMedianTimePast ()
2755+ : block.GetBlockTime ();
2756+ if (!IsFinalTx (tx, nHeight, nLockTimeCutoff)) {
27282757 return state.DoS (10 , error (" %s: contains a non-final transaction" , __func__), REJECT_INVALID, " bad-txns-nonfinal" );
27292758 }
2759+ }
27302760
27312761 // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
27322762 // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet):
0 commit comments