diff --git a/src/chainparams.cpp b/src/chainparams.cpp --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -83,6 +83,9 @@ CMainParams() { strNetworkID = "main"; consensus.nSubsidyHalvingInterval = 210000; + // 00000000000000ce80a7e057163a4db1d5ad7b20fb6f598c9597b9665c8fb0d4 - + // April 1, 2012 + consensus.BIP16Height = 173805; consensus.BIP34Height = 227931; consensus.BIP34Hash = uint256S( "000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8"); @@ -249,6 +252,8 @@ CTestNetParams() { strNetworkID = "test"; consensus.nSubsidyHalvingInterval = 210000; + // 00000000040b4e986385315e14bee30ad876d8b47f748025b26683116d21aa65 + consensus.BIP16Height = 514; consensus.BIP34Height = 21111; consensus.BIP34Hash = uint256S( "0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8"); @@ -368,6 +373,8 @@ CRegTestParams() { strNetworkID = "regtest"; consensus.nSubsidyHalvingInterval = 150; + // always enforce P2SH BIP16 on regtest + consensus.BIP16Height = 0; // BIP34 has not activated on regtest (far in the future so block v1 are // not rejected in tests) consensus.BIP34Height = 100000000; diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -32,8 +32,6 @@ static const int COINBASE_MATURITY = 100; /** Coinbase scripts have their own script size limit. */ static const int MAX_COINBASE_SCRIPTSIG_SIZE = 100; -/** Activation time for P2SH (April 1st 2012) */ -static const int64_t P2SH_ACTIVATION_TIME = 1333234914; /** Flags for nSequence and nLockTime locks */ /** Interpret sequence numbers as relative lock-time constraints. */ diff --git a/src/consensus/params.h b/src/consensus/params.h --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -19,6 +19,8 @@ struct Params { uint256 hashGenesisBlock; int nSubsidyHalvingInterval; + /** Block height at which BIP16 becomes active */ + int BIP16Height; /** Block height and hash at which BIP34 becomes active */ int BIP34Height; uint256 BIP34Hash; diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -436,44 +436,6 @@ std::runtime_error); g_mempool.clear(); - // Invalid (pre-p2sh) txn in mempool, template creation fails. - std::array times; - for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++) { - // Trick the MedianTimePast. - times[i] = chainActive.Tip() - ->GetAncestor(chainActive.Tip()->nHeight - i) - ->nTime; - chainActive.Tip()->GetAncestor(chainActive.Tip()->nHeight - i)->nTime = - P2SH_ACTIVATION_TIME; - } - - tx.vin[0].prevout = COutPoint(txFirst[0]->GetId(), 0); - tx.vin[0].scriptSig = CScript() << OP_1; - tx.vout[0].nValue = BLOCKSUBSIDY - LOWFEE; - script = CScript() << OP_0; - tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script)); - hash = tx.GetId(); - g_mempool.addUnchecked( - hash, - entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); - tx.vin[0].prevout = COutPoint(hash, 0); - tx.vin[0].scriptSig = CScript() - << std::vector(script.begin(), script.end()); - tx.vout[0].nValue -= LOWFEE; - hash = tx.GetId(); - g_mempool.addUnchecked( - hash, - entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); - BOOST_CHECK_THROW( - BlockAssembler(config, g_mempool).CreateNewBlock(scriptPubKey), - std::runtime_error); - g_mempool.clear(); - for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++) { - // Restore the MedianTimePast. - chainActive.Tip()->GetAncestor(chainActive.Tip()->nHeight - i)->nTime = - times[i]; - } - // Double spend txn pair in mempool, template creation fails. tx.vin[0].prevout = COutPoint(txFirst[0]->GetId(), 0); tx.vin[0].scriptSig = CScript() << OP_1; @@ -523,6 +485,30 @@ BOOST_CHECK( pblocktemplate = BlockAssembler(config, g_mempool).CreateNewBlock(scriptPubKey)); + + // Invalid p2sh txn in mempool, template creation fails + tx.vin[0].prevout = COutPoint(txFirst[0]->GetId(), 0); + tx.vin[0].scriptSig = CScript() << OP_1; + tx.vout[0].nValue = BLOCKSUBSIDY - LOWFEE; + script = CScript() << OP_0; + tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script)); + hash = tx.GetId(); + g_mempool.addUnchecked( + hash, + entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + tx.vin[0].prevout = COutPoint(hash, 0); + tx.vin[0].scriptSig = CScript() + << std::vector(script.begin(), script.end()); + tx.vout[0].nValue -= LOWFEE; + hash = tx.GetId(); + g_mempool.addUnchecked( + hash, + entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); + BOOST_CHECK_THROW( + BlockAssembler(config, g_mempool).CreateNewBlock(scriptPubKey), + std::runtime_error); + g_mempool.clear(); + // Delete the dummy blocks again. while (chainActive.Tip()->nHeight > nHeight) { CBlockIndex *del = chainActive.Tip(); diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1557,8 +1557,8 @@ uint32_t flags = SCRIPT_VERIFY_NONE; - // P2SH didn't become active until Apr 1 2012 - if (pindex->GetMedianTimePast() >= P2SH_ACTIVATION_TIME) { + // Start enforcing P2SH (BIP16) + if ((pindex->nHeight + 1) >= consensusParams.BIP16Height) { flags |= SCRIPT_VERIFY_P2SH; }