Browse Source
It breaks the new mingw tests! See - https://travis-ci.org/bitcoin/bitcoin/jobs/36845581 - https://travis-ci.org/bitcoin/bitcoin/jobs/36845582 This reverts commit0.104705902777
,5e2e7fcb99
,a25fd6be13
.
Wladimir J. van der Laan
10 years ago
12 changed files with 4 additions and 371 deletions
@ -1,275 +0,0 @@
@@ -1,275 +0,0 @@
|
||||
// Copyright (c) 2011-2014 The Bitcoin Core developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "main.h" |
||||
#include "miner.h" |
||||
#include "uint256.h" |
||||
#include "util.h" |
||||
|
||||
#include <boost/test/unit_test.hpp> |
||||
|
||||
// This test cheecks the majority rule which states that after 1000 v2 blocks no new v1 block can be part of that branch.
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(blockv2_tests) |
||||
|
||||
static CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; |
||||
|
||||
static void SetEmptyBlock(CBlock * pblock) |
||||
{ |
||||
pblock->nVersion = 2; |
||||
pblock->nTime = chainActive.Tip()->GetMedianTimePast()+1; |
||||
pblock->nNonce = 0; |
||||
} |
||||
|
||||
static void SetBlockDefaultAttributesAndHeight(CBlock * pblock,bool addHeight,int heightDifference) |
||||
{ |
||||
SetEmptyBlock(pblock); |
||||
|
||||
// Add the coinbase
|
||||
CMutableTransaction txCoinbase(pblock->vtx[0]); |
||||
|
||||
if (addHeight) |
||||
txCoinbase.vin[0].scriptSig = (CScript() << (chainActive.Height()+1+heightDifference) << 0); |
||||
else |
||||
txCoinbase.vin[0].scriptSig = (CScript() << heightDifference << 0); // At least size 2, this is a protocol spec
|
||||
|
||||
txCoinbase.vout[0].scriptPubKey = CScript(); |
||||
pblock->vtx[0] = CTransaction(txCoinbase); |
||||
pblock->hashMerkleRoot = pblock->BuildMerkleTree(); |
||||
} |
||||
|
||||
void CheckSubsidyHalving(CBlockTemplate * &pblocktemplate, CBlock * &pblock) |
||||
{ |
||||
if ((chainActive.Height()+1) % Params().SubsidyHalvingInterval() == 0) |
||||
{ |
||||
// The RegTest network has a low subsidy halving interval (150) so
|
||||
// we must recompute the coinbase subsidy if we reach the boundary.
|
||||
// The unittest network allows modifying this interval. We check it so this
|
||||
// test can work in any network.
|
||||
|
||||
// preserve parent hash
|
||||
uint256 prevParent = pblock->hashPrevBlock; |
||||
delete pblocktemplate; |
||||
pblocktemplate = CreateNewBlock(scriptPubKey); |
||||
pblock = &pblocktemplate->block; // pointer for convenience
|
||||
pblock->hashPrevBlock = prevParent; |
||||
} |
||||
} |
||||
|
||||
void CheckBlockAddedToBestChainSuccessfully(CBlock *pblock) |
||||
{ |
||||
int PreviousHeight; |
||||
CValidationState state; |
||||
|
||||
PreviousHeight = chainActive.Height(); |
||||
BOOST_CHECK(ProcessBlock(state, NULL, pblock)); |
||||
BOOST_CHECK(state.IsValid()); |
||||
BOOST_CHECK((PreviousHeight+1) == chainActive.Height()); // to differentiate from orphan blocks, which also get accepted in ProcessBlock()
|
||||
|
||||
// Previous checks do not assure the current best chain has pblock as tip. It could be the case that a because
|
||||
// of a malfunction in the chain reorganization code, a reorganization causes an increase of the chain length, but with another tip.
|
||||
// So we also check that.
|
||||
BOOST_CHECK(chainActive.Tip()->GetBlockHash()==pblock->GetHash()); |
||||
} |
||||
|
||||
void Blockv2test() |
||||
{ |
||||
assert(Params().NetworkID() == CBaseChainParams::UNITTEST); |
||||
ModifiableParams()->setSkipProofOfWorkCheck(true); |
||||
|
||||
// We don't know the state of the block-chain here: it depends on which other tests are run before this test.
|
||||
// See https://github.com/bitcoin/bitcoin/pull/4688 for a patch that allows the re-creation of the block-chain
|
||||
// for each testcase that requires it.
|
||||
|
||||
// If miner_tests.cpp is run before, the chain will be 100 blocks long, and all of them will be v1
|
||||
|
||||
|
||||
LogPrintf("Blockv2test testcase starts\n"); |
||||
|
||||
CBlockTemplate *pblocktemplate; |
||||
CScript script; |
||||
uint256 hash; |
||||
int PreviousHeight; |
||||
|
||||
LOCK(cs_main); |
||||
|
||||
// Simple block creation, nothing special yet.
|
||||
pblocktemplate = CreateNewBlock(scriptPubKey); |
||||
CBlock *pblock = &pblocktemplate->block; // pointer for convenience
|
||||
|
||||
LogPrintf("Blockv2test block v1 add begin\n"); |
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// First create a block v1, check that it is accepted. The block has an invalid height.
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
SetBlockDefaultAttributesAndHeight(pblock,false,5000); |
||||
pblock->nVersion = 1; |
||||
CValidationState state1; |
||||
PreviousHeight = chainActive.Height(); |
||||
BOOST_CHECK(ProcessBlock(state1, NULL, pblock)); |
||||
BOOST_CHECK(state1.IsValid()); |
||||
BOOST_CHECK((PreviousHeight+1) == chainActive.Height()); // to differentiate from orphan blocks, which also get accepted in ProcessBlock()
|
||||
pblock->hashPrevBlock = pblock->GetHash(); // update parent
|
||||
|
||||
|
||||
|
||||
// First check that the supermajority threshold is exactly 1000 blocks
|
||||
BOOST_CHECK(Params().ToCheckBlockUpgradeMajority()==1000); //
|
||||
BOOST_CHECK(Params().EnforceBlockUpgradeMajority()==750); |
||||
BOOST_CHECK(Params().RejectBlockOutdatedMajority()==950); |
||||
|
||||
// Over the last 1000 blocks, 750 blocks must be v2 to switch to v2-only mode.
|
||||
// Here we're testing only the last 750, not any subset.
|
||||
|
||||
LogPrintf("Blockv2test BIP30 repetition begin\n"); |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// First, if we try to add a block v2 with the same coinbase tx, we should get
|
||||
// "bad-txns-BIP30" because the coinbase tx has the same hash as the previous.
|
||||
// Even if ConnectBlock returns a "bad-txns-BIP30", ActivateBestChainStep clears
|
||||
// the state, so we get true here and the "bad-txns-BIP30" reason is lost. But this
|
||||
// is the intended behaviour: Receiving a single block can cause zero or multiple blocks to be
|
||||
// connected, and ActivateBestChain's responsibility is just switching the best block whatsoever.
|
||||
// Feedback about failures causes a reject message to be sent to the peer from which we received
|
||||
// the actual block (not necessarily the same as from whom we got the block that caused the reorg),
|
||||
// for which we remember the peerid.
|
||||
// Because we cannot access the failure reason here, we just verify instead that the chain
|
||||
// height has not been incremented.
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CValidationState state7; |
||||
PreviousHeight = chainActive.Height(); |
||||
CheckSubsidyHalving(pblocktemplate,pblock); |
||||
SetBlockDefaultAttributesAndHeight(pblock,false,5000); //
|
||||
pblock->nVersion = 2; |
||||
BOOST_CHECK(ProcessBlock(state7, NULL, pblock)); // should we care about the return value?
|
||||
BOOST_CHECK(state7.IsValid()); |
||||
BOOST_CHECK(PreviousHeight == chainActive.Height()); // we check the block has not been added.
|
||||
|
||||
LogPrintf("Blockv2test 750 v2 blocks begin\n"); |
||||
|
||||
////////////////////////////
|
||||
// Now create 750 v2 blocks
|
||||
////////////////////////////
|
||||
|
||||
for (int i=0;i<750;i++) |
||||
{ |
||||
|
||||
LogPrintf("Blockv2test block %d begin\n",i); |
||||
|
||||
CheckSubsidyHalving(pblocktemplate,pblock); |
||||
|
||||
// We add a value to the height to make is NOT equal to the actual height.
|
||||
SetBlockDefaultAttributesAndHeight(pblock,true,1000); // blocks version 2 without height are allowed! for only 750 blocks
|
||||
pblock->nVersion = 2; |
||||
|
||||
CheckBlockAddedToBestChainSuccessfully(pblock); |
||||
pblock->hashPrevBlock = pblock->GetHash(); // update parent
|
||||
} |
||||
|
||||
LogPrintf("Blockv2test v2 without height rejected begin\n"); |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Now we try to add a block v2, with an invalid height and it should be rejected.
|
||||
// We use 2000 as argument heightDifference because is not in the range [1000..1750].
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
CheckSubsidyHalving(pblocktemplate,pblock); |
||||
SetBlockDefaultAttributesAndHeight(pblock,true,2000); //
|
||||
pblock->nVersion = 2; |
||||
CValidationState state0; |
||||
BOOST_CHECK(ProcessBlock(state0, NULL, pblock)==false); |
||||
BOOST_CHECK(!state0.IsValid()); |
||||
BOOST_CHECK(state0.GetRejectReason()=="bad-cb-height"); |
||||
// Do not update parent since block has failed
|
||||
|
||||
LogPrintf("Blockv2test v2 with height accepted begin\n"); |
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Now we add 200 additional blocks, until we get 950
|
||||
// (the threshold where v1 blocks are not accepted anymore)
|
||||
/////////////////////////////////////////////////////////////
|
||||
for (int i=0;i<200;i++) |
||||
{ |
||||
|
||||
LogPrintf("Blockv2test v2block %d begin\n",i); |
||||
CheckSubsidyHalving(pblocktemplate,pblock); |
||||
SetBlockDefaultAttributesAndHeight(pblock,true,0); |
||||
pblock->nVersion = 2; |
||||
CheckBlockAddedToBestChainSuccessfully(pblock); |
||||
pblock->hashPrevBlock = pblock->GetHash(); // update parent
|
||||
} |
||||
|
||||
|
||||
LogPrintf("Blockv2test block v1 rejected\n"); |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Now we try to add a block v1, it should be rejected, even if it hash the height field
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
CheckSubsidyHalving(pblocktemplate,pblock); |
||||
SetBlockDefaultAttributesAndHeight(pblock,true,0); |
||||
pblock->nVersion = 1; |
||||
CValidationState state2; |
||||
BOOST_CHECK(ProcessBlock(state2, NULL, pblock)==false); |
||||
BOOST_CHECK(!state2.IsValid()); |
||||
BOOST_CHECK(state2.GetRejectReason()=="bad-version"); |
||||
// Do not update parent since block has failed
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// Block time too old check
|
||||
////////////////////////////////////////////////////////
|
||||
CheckSubsidyHalving(pblocktemplate,pblock); |
||||
SetBlockDefaultAttributesAndHeight(pblock,true,0); |
||||
pblock->nVersion = 2; |
||||
pblock->nTime = chainActive.Tip()->GetMedianTimePast()-1; |
||||
CValidationState state4; |
||||
BOOST_CHECK(ProcessBlock(state4, NULL, pblock)==false); |
||||
BOOST_CHECK(!state4.IsValid()); |
||||
BOOST_CHECK(state4.GetRejectReason()=="time-too-old"); |
||||
// Do not update parent since block has failed
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// Adding a non-final coinbase, must modify coinbase
|
||||
////////////////////////////////////////////////////////
|
||||
CheckSubsidyHalving(pblocktemplate,pblock); |
||||
SetEmptyBlock(pblock); |
||||
// Use a mutable coinbase to change nLockTime and nSequence
|
||||
CMutableTransaction txCoinbase(pblock->vtx[0]); |
||||
txCoinbase.vin[0].scriptSig = (CScript() << chainActive.Height() << 0); |
||||
txCoinbase.nLockTime = LOCKTIME_THRESHOLD-1; // refers to height
|
||||
txCoinbase.vin[0].nSequence = 1; // non-zero sequence
|
||||
pblock->vtx[0] = CTransaction(txCoinbase); |
||||
pblock->nVersion = 2; |
||||
pblock->hashMerkleRoot = pblock->BuildMerkleTree(); |
||||
CValidationState state5; |
||||
BOOST_CHECK(ProcessBlock(state5, NULL, pblock)==false); |
||||
BOOST_CHECK(!state5.IsValid()); |
||||
BOOST_CHECK(state5.GetRejectReason()=="bad-txns-nonfinal"); |
||||
// Do not update parent since block has failed
|
||||
|
||||
ModifiableParams()->setSkipProofOfWorkCheck(false); |
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Just to be sure that proof-of-work skipping is working ok, we submit a block
|
||||
// without enought proof of work and it must be rejected.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CheckSubsidyHalving(pblocktemplate,pblock); |
||||
SetBlockDefaultAttributesAndHeight(pblock,true,0); |
||||
pblock->nVersion = 2; |
||||
CValidationState state6; |
||||
BOOST_CHECK(ProcessBlock(state6, NULL, pblock)==false); |
||||
BOOST_CHECK(!state6.IsValid()); |
||||
BOOST_CHECK(state6.GetRejectReason()=="high-hash"); |
||||
|
||||
delete pblocktemplate; |
||||
|
||||
|
||||
LogPrintf("Blockv2test testcase ends\n"); |
||||
} |
||||
|
||||
BOOST_AUTO_TEST_CASE(Blockv2testcase) |
||||
{ |
||||
Blockv2test(); |
||||
} |
||||
|
||||
BOOST_AUTO_TEST_SUITE_END() |
Loading…
Reference in new issue