Enable policy enforcing GetMedianTimePast as the end point of lock-time constraints

Transactions are not allowed in the memory pool or selected for inclusion in a block until their lock times exceed chainActive.Tip()->GetMedianTimePast(). However blocks including transactions which are only mature under the old rules are still accepted; this is *not* the soft-fork required to actually rely on the new constraint in production.
This commit is contained in:
Mark Friedenbach 2015-06-03 15:01:47 -07:00 committed by Matt Corallo
parent 8bdb2d4d1d
commit bbdccaa987
3 changed files with 15 additions and 14 deletions

View file

@ -795,7 +795,8 @@ int64_t CheckLockTime(const CTransaction &tx, int flags)
// current network-enforced consensus rules should be used. In
// a future soft-fork scenario that would mean an
// IsSuperMajority check against chainActive.Tip().
flags = std::max(flags, 0);
if (flags < 0)
flags = LOCKTIME_MEDIAN_TIME_PAST;
// pcoinsTip contains the UTXO set for chainActive.Tip()
const CCoinsView *pCoinsView = pcoinsTip;
@ -1091,7 +1092,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Enforce sequnce numbers as relative lock-time
// only for tx.nVersion >= 2.
int nLockTimeFlags = 0;
int nLockTimeFlags = LOCKTIME_MEDIAN_TIME_PAST;
if (tx.nVersion >= 2)
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;

View file

@ -160,7 +160,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
// Enforce sequnce numbers as relative lock-time
// only for tx.nVersion >= 2.
int nLockTimeFlags = 0;
int nLockTimeFlags = LOCKTIME_MEDIAN_TIME_PAST;
if (tx.nVersion >= 2)
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;

View file

@ -225,16 +225,16 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.nLockTime = 0;
hash = tx.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
BOOST_CHECK(CheckLockTime(tx, LOCKTIME_VERIFY_SEQUENCE) == chainActive.Tip()->nHeight + 1);
BOOST_CHECK(!LockTime(tx, LOCKTIME_VERIFY_SEQUENCE, pcoinsTip, chainActive.Tip()->nHeight + 2, GetTime()));
BOOST_CHECK(CheckLockTime(tx, LOCKTIME_VERIFY_SEQUENCE|LOCKTIME_MEDIAN_TIME_PAST) == chainActive.Tip()->nHeight + 1);
BOOST_CHECK(!LockTime(tx, LOCKTIME_VERIFY_SEQUENCE|LOCKTIME_MEDIAN_TIME_PAST, pcoinsTip, chainActive.Tip()->nHeight + 2, chainActive.Tip()->GetMedianTimePast()));
// relative time locked
tx.vin[0].prevout.hash = txFirst[1]->GetHash();
tx.vin[0].nSequence = ~(uint32_t)(chainActive.Tip()->GetMedianTimePast()+1-chainActive[1]->GetMedianTimePast()+LOCKTIME_THRESHOLD); // txFirst[1] is the 3rd block
tx.vin[0].nSequence = ~(uint32_t)(chainActive.Tip()->GetMedianTimePast()-chainActive[1]->GetMedianTimePast()+LOCKTIME_THRESHOLD); // txFirst[1] is the 3rd block
hash = tx.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
BOOST_CHECK(CheckLockTime(tx, LOCKTIME_VERIFY_SEQUENCE) == chainActive.Tip()->GetMedianTimePast() + 1);
BOOST_CHECK(!LockTime(tx, LOCKTIME_VERIFY_SEQUENCE, pcoinsTip, chainActive.Tip()->nHeight + 1, GetTime() + 1));
BOOST_CHECK(CheckLockTime(tx, LOCKTIME_VERIFY_SEQUENCE|LOCKTIME_MEDIAN_TIME_PAST) == chainActive.Tip()->GetMedianTimePast());
BOOST_CHECK(!LockTime(tx, LOCKTIME_VERIFY_SEQUENCE|LOCKTIME_MEDIAN_TIME_PAST, pcoinsTip, chainActive.Tip()->nHeight + 1, chainActive.Tip()->GetMedianTimePast() + 1));
// absolute height locked
tx.vin[0].prevout.hash = txFirst[2]->GetHash();
@ -242,16 +242,16 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.nLockTime = chainActive.Tip()->nHeight + 1;
hash = tx.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
BOOST_CHECK(CheckLockTime(tx, 0) == chainActive.Tip()->nHeight + 1);
BOOST_CHECK(!LockTime(tx, 0, pcoinsTip, chainActive.Tip()->nHeight + 2, GetTime()));
BOOST_CHECK(CheckLockTime(tx, LOCKTIME_MEDIAN_TIME_PAST) == chainActive.Tip()->nHeight + 1);
BOOST_CHECK(!LockTime(tx, LOCKTIME_MEDIAN_TIME_PAST, pcoinsTip, chainActive.Tip()->nHeight + 2, chainActive.Tip()->GetMedianTimePast()));
// absolute time locked
tx.vin[0].prevout.hash = txFirst[3]->GetHash();
tx.nLockTime = chainActive.Tip()->GetMedianTimePast() + 1;
tx.nLockTime = chainActive.Tip()->GetMedianTimePast();
hash = tx.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
BOOST_CHECK(CheckLockTime(tx, 0) == chainActive.Tip()->GetMedianTimePast() + 1);
BOOST_CHECK(!LockTime(tx, 0, pcoinsTip, chainActive.Tip()->nHeight + 1, GetTime() + 1));
BOOST_CHECK(CheckLockTime(tx, LOCKTIME_MEDIAN_TIME_PAST) == chainActive.Tip()->GetMedianTimePast());
BOOST_CHECK(!LockTime(tx, LOCKTIME_MEDIAN_TIME_PAST, pcoinsTip, chainActive.Tip()->nHeight + 1, chainActive.Tip()->GetMedianTimePast() + 1));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
@ -266,7 +266,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
SetMockTime(chainActive.Tip()->GetMedianTimePast() + 2);
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
BOOST_CHECK(pblocktemplate->block.vtx.size() >= 4);
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3);
delete pblocktemplate;
chainActive.Tip()->nHeight--;