From 08625ca2d29d90946fe4f941acd529d8cccc217d Mon Sep 17 00:00:00 2001 From: Mark Friedenbach Date: Wed, 3 Jun 2015 15:01:47 -0700 Subject: [PATCH] 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. --- src/main.cpp | 5 +++-- src/miner.cpp | 2 +- src/test/miner_tests.cpp | 22 +++++++++++----------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a7e4b55e9f..7fffca9030 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -759,7 +759,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; @@ -1053,7 +1054,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa view.SetBackend(dummy); } - int nLockTimeFlags = 0; + int nLockTimeFlags = LOCKTIME_MEDIAN_TIME_PAST; int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST) ? chainActive.Tip()->GetMedianTimePast() : GetAdjustedTime(); diff --git a/src/miner.cpp b/src/miner.cpp index bf23e8298d..41197c9001 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -161,7 +161,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) { const CTransaction& tx = mi->second.GetTx(); - int nLockTimeFlags = 0; + int nLockTimeFlags = LOCKTIME_MEDIAN_TIME_PAST; int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST) ? nMedianTimePast : pblock->GetBlockTime(); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 7a25a329f5..7ad6ea058f 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -227,16 +227,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(); @@ -244,16 +244,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)); @@ -267,7 +267,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) SetMockTime(chainActive.Tip()->GetMedianTimePast() + 2); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); - BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5); + BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 4); delete pblocktemplate; chainActive.Tip()->nHeight--;