Wladimir J. van der Laan 10 years ago
parent
commit
8d132431b4
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 1
      src/Makefile.test.include
  2. 41
      src/chainparams.cpp
  3. 24
      src/chainparams.h
  4. 17
      src/chainparamsbase.cpp
  5. 1
      src/chainparamsbase.h
  6. 2
      src/checkpoints.cpp
  7. 3
      src/main.cpp
  8. 4
      src/pow.cpp
  9. 4
      src/test/base58_tests.cpp
  10. 275
      src/test/blockv2_tests.cpp
  11. 1
      src/test/miner_tests.cpp
  12. 2
      src/test/test_bitcoin.cpp

1
src/Makefile.test.include

@ -51,7 +51,6 @@ BITCOIN_TESTS =\
test/key_tests.cpp \ test/key_tests.cpp \
test/main_tests.cpp \ test/main_tests.cpp \
test/miner_tests.cpp \ test/miner_tests.cpp \
test/blockv2_tests.cpp \
test/mruset_tests.cpp \ test/mruset_tests.cpp \
test/multisig_tests.cpp \ test/multisig_tests.cpp \
test/netbase_tests.cpp \ test/netbase_tests.cpp \

41
src/chainparams.cpp

@ -115,7 +115,6 @@ public:
fAllowMinDifficultyBlocks = false; fAllowMinDifficultyBlocks = false;
fRequireStandard = true; fRequireStandard = true;
fMineBlocksOnDemand = false; fMineBlocksOnDemand = false;
fSkipProofOfWorkCheck = false;
} }
}; };
static CMainParams mainParams; static CMainParams mainParams;
@ -215,46 +214,8 @@ public:
}; };
static CRegTestParams regTestParams; static CRegTestParams regTestParams;
//
// Unit test
//
class CUnitTestParams : public CMainParams, public CModifiableParams {
public:
CUnitTestParams() {
networkID = CBaseChainParams::UNITTEST;
strNetworkID = "unittest";
nDefaultPort = 18445;
vFixedSeeds.clear();
vSeeds.clear(); // Regtest mode doesn't have any DNS seeds.
fRequireRPCPassword = false;
fMiningRequiresPeers = false;
fDefaultCheckMemPool = true;
fAllowMinDifficultyBlocks = false;
fMineBlocksOnDemand = true;
}
public:
// Published setters to allow changing values in unit test cases
virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) { nSubsidyHalvingInterval=anSubsidyHalvingInterval; }
virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority) { nEnforceBlockUpgradeMajority=anEnforceBlockUpgradeMajority; }
virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority) { nRejectBlockOutdatedMajority=anRejectBlockOutdatedMajority; }
virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority) { nToCheckBlockUpgradeMajority=anToCheckBlockUpgradeMajority; }
virtual void setDefaultCheckMemPool(bool afDefaultCheckMemPool) { fDefaultCheckMemPool=afDefaultCheckMemPool; }
virtual void setAllowMinDifficultyBlocks(bool afAllowMinDifficultyBlocks) { fAllowMinDifficultyBlocks=afAllowMinDifficultyBlocks; }
virtual void setSkipProofOfWorkCheck(bool afSkipProofOfWorkCheck) { fSkipProofOfWorkCheck = afSkipProofOfWorkCheck; }
};
static CUnitTestParams unitTestParams;
static CChainParams *pCurrentParams = 0; static CChainParams *pCurrentParams = 0;
CModifiableParams *ModifiableParams()
{
assert(pCurrentParams);
assert(pCurrentParams==&unitTestParams);
return (CModifiableParams*)&unitTestParams;
}
const CChainParams &Params() { const CChainParams &Params() {
assert(pCurrentParams); assert(pCurrentParams);
return *pCurrentParams; return *pCurrentParams;
@ -268,8 +229,6 @@ CChainParams &Params(CBaseChainParams::Network network) {
return testNetParams; return testNetParams;
case CBaseChainParams::REGTEST: case CBaseChainParams::REGTEST:
return regTestParams; return regTestParams;
case CBaseChainParams::UNITTEST:
return unitTestParams;
default: default:
assert(false && "Unimplemented network"); assert(false && "Unimplemented network");
return mainParams; return mainParams;

24
src/chainparams.h

@ -61,8 +61,6 @@ public:
bool DefaultCheckMemPool() const { return fDefaultCheckMemPool; } bool DefaultCheckMemPool() const { return fDefaultCheckMemPool; }
/* Allow mining of a min-difficulty block */ /* Allow mining of a min-difficulty block */
bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; } bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; }
/* Skip proof-of-work check: allow mining of any difficulty block */
bool SkipProofOfWorkCheck() const { return fSkipProofOfWorkCheck; }
/* Make standard checks */ /* Make standard checks */
bool RequireStandard() const { return fRequireStandard; } bool RequireStandard() const { return fRequireStandard; }
int64_t TargetTimespan() const { return nTargetTimespan; } int64_t TargetTimespan() const { return nTargetTimespan; }
@ -105,27 +103,8 @@ protected:
bool fAllowMinDifficultyBlocks; bool fAllowMinDifficultyBlocks;
bool fRequireStandard; bool fRequireStandard;
bool fMineBlocksOnDemand; bool fMineBlocksOnDemand;
bool fSkipProofOfWorkCheck;
}; };
/** Modifiable parameters interface is used by test cases to adapt the parameters in order
*** to test specific features more easily. Test cases should always restore the previous
*** values after finalization.
**/
class CModifiableParams {
public:
// Published setters to allow changing values in unit test cases
virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) =0;
virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority)=0;
virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority)=0;
virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority)=0;
virtual void setDefaultCheckMemPool(bool aDefaultCheckMemPool)=0;
virtual void setAllowMinDifficultyBlocks(bool aAllowMinDifficultyBlocks)=0;
virtual void setSkipProofOfWorkCheck(bool aSkipProofOfWorkCheck)=0;
};
/** /**
* Return the currently selected parameters. This won't change after app startup * Return the currently selected parameters. This won't change after app startup
* outside of the unit tests. * outside of the unit tests.
@ -135,9 +114,6 @@ const CChainParams &Params();
/** Return parameters for the given network. */ /** Return parameters for the given network. */
CChainParams &Params(CBaseChainParams::Network network); CChainParams &Params(CBaseChainParams::Network network);
/** Get modifyable network parameters (UNITTEST only) */
CModifiableParams *ModifiableParams();
/** Sets the params returned by Params() to those for the given network. */ /** Sets the params returned by Params() to those for the given network. */
void SelectParams(CBaseChainParams::Network network); void SelectParams(CBaseChainParams::Network network);

17
src/chainparamsbase.cpp

@ -57,20 +57,6 @@ public:
}; };
static CBaseRegTestParams regTestParams; static CBaseRegTestParams regTestParams;
//
// Unit test
//
class CBaseUnitTestParams : public CBaseMainParams
{
public:
CBaseUnitTestParams()
{
networkID = CBaseChainParams::UNITTEST;
strDataDir = "unittest";
}
};
static CBaseUnitTestParams unitTestParams;
static CBaseChainParams* pCurrentBaseParams = 0; static CBaseChainParams* pCurrentBaseParams = 0;
const CBaseChainParams& BaseParams() const CBaseChainParams& BaseParams()
@ -91,9 +77,6 @@ void SelectBaseParams(CBaseChainParams::Network network)
case CBaseChainParams::REGTEST: case CBaseChainParams::REGTEST:
pCurrentBaseParams = &regTestParams; pCurrentBaseParams = &regTestParams;
break; break;
case CBaseChainParams::UNITTEST:
pCurrentBaseParams = &unitTestParams;
break;
default: default:
assert(false && "Unimplemented network"); assert(false && "Unimplemented network");
return; return;

1
src/chainparamsbase.h

@ -19,7 +19,6 @@ public:
MAIN, MAIN,
TESTNET, TESTNET,
REGTEST, REGTEST,
UNITTEST,
MAX_NETWORK_TYPES MAX_NETWORK_TYPES
}; };

2
src/checkpoints.cpp

@ -88,8 +88,6 @@ namespace Checkpoints {
return dataTestnet; return dataTestnet;
else if (Params().NetworkID() == CBaseChainParams::MAIN) else if (Params().NetworkID() == CBaseChainParams::MAIN)
return data; return data;
else if (Params().NetworkID() == CBaseChainParams::UNITTEST) // UnitTest share the same checkpoints as MAIN
return data;
else else
return dataRegtest; return dataRegtest;
} }

3
src/main.cpp

@ -2305,8 +2305,7 @@ bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex
nHeight = pindexPrev->nHeight+1; nHeight = pindexPrev->nHeight+1;
// Check proof of work // Check proof of work
if ((!Params().SkipProofOfWorkCheck()) && if (block.nBits != GetNextWorkRequired(pindexPrev, &block))
(block.nBits != GetNextWorkRequired(pindexPrev, &block)))
return state.DoS(100, error("AcceptBlock() : incorrect proof of work"), return state.DoS(100, error("AcceptBlock() : incorrect proof of work"),
REJECT_INVALID, "bad-diffbits"); REJECT_INVALID, "bad-diffbits");

4
src/pow.cpp

@ -81,10 +81,6 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits)
bool fNegative; bool fNegative;
bool fOverflow; bool fOverflow;
uint256 bnTarget; uint256 bnTarget;
if (Params().SkipProofOfWorkCheck())
return true;
bnTarget.SetCompact(nBits, &fNegative, &fOverflow); bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
// Check range // Check range

4
src/test/base58_tests.cpp

@ -175,7 +175,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest); BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest);
} }
} }
SelectParams(CBaseChainParams::UNITTEST); SelectParams(CBaseChainParams::MAIN);
} }
// Goal: check that generated keys match test vectors // Goal: check that generated keys match test vectors
@ -243,7 +243,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
CTxDestination nodest = CNoDestination(); CTxDestination nodest = CNoDestination();
BOOST_CHECK(!dummyAddr.Set(nodest)); BOOST_CHECK(!dummyAddr.Set(nodest));
SelectParams(CBaseChainParams::UNITTEST); SelectParams(CBaseChainParams::MAIN);
} }
// Goal: check that base58 parsing code is robust against a variety of corrupted data // Goal: check that base58 parsing code is robust against a variety of corrupted data

275
src/test/blockv2_tests.cpp

@ -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()

1
src/test/miner_tests.cpp

@ -253,7 +253,6 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
chainActive.Tip()->nHeight--; chainActive.Tip()->nHeight--;
SetMockTime(0); SetMockTime(0);
mempool.clear();
BOOST_FOREACH(CTransaction *tx, txFirst) BOOST_FOREACH(CTransaction *tx, txFirst)
delete tx; delete tx;

2
src/test/test_bitcoin.cpp

@ -31,7 +31,7 @@ struct TestingSetup {
TestingSetup() { TestingSetup() {
fPrintToDebugLog = false; // don't want to write to debug.log file fPrintToDebugLog = false; // don't want to write to debug.log file
SelectParams(CBaseChainParams::UNITTEST); SelectParams(CBaseChainParams::MAIN);
noui_connect(); noui_connect();
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
bitdb.MakeMock(); bitdb.MakeMock();

Loading…
Cancel
Save