Changeset View
Changeset View
Standalone View
Standalone View
src/test/pow_tests.cpp
// Copyright (c) 2015 The Bitcoin Core developers | // Copyright (c) 2015 The Bitcoin Core developers | ||||
// Distributed under the MIT/X11 software license, see the accompanying | // Distributed under the MIT/X11 software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include "pow.h" | #include "pow.h" | ||||
#include "chain.h" | #include "chain.h" | ||||
#include "chainparams.h" | #include "chainparams.h" | ||||
#include "config.h" | |||||
#include "random.h" | #include "random.h" | ||||
#include "test/test_bitcoin.h" | #include "test/test_bitcoin.h" | ||||
#include "util.h" | #include "util.h" | ||||
#include <boost/test/unit_test.hpp> | #include <boost/test/unit_test.hpp> | ||||
BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup) | BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup) | ||||
/* Test calculation of next difficulty target with no constraints applying */ | /* Test calculation of next difficulty target with no constraints applying */ | ||||
BOOST_AUTO_TEST_CASE(get_next_work) { | BOOST_AUTO_TEST_CASE(get_next_work) { | ||||
SelectParams(CBaseChainParams::MAIN); | SelectParams(CBaseChainParams::MAIN); | ||||
const Consensus::Params ¶ms = Params().GetConsensus(); | GlobalConfig config; | ||||
int64_t nLastRetargetTime = 1261130161; // Block #30240 | int64_t nLastRetargetTime = 1261130161; // Block #30240 | ||||
CBlockIndex pindexLast; | CBlockIndex pindexLast; | ||||
pindexLast.nHeight = 32255; | pindexLast.nHeight = 32255; | ||||
pindexLast.nTime = 1262152739; // Block #32255 | pindexLast.nTime = 1262152739; // Block #32255 | ||||
pindexLast.nBits = 0x1d00ffff; | pindexLast.nBits = 0x1d00ffff; | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), | CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, config), | ||||
0x1d00d86a); | 0x1d00d86a); | ||||
} | } | ||||
/* Test the constraint on the upper bound for next work */ | /* Test the constraint on the upper bound for next work */ | ||||
BOOST_AUTO_TEST_CASE(get_next_work_pow_limit) { | BOOST_AUTO_TEST_CASE(get_next_work_pow_limit) { | ||||
SelectParams(CBaseChainParams::MAIN); | SelectParams(CBaseChainParams::MAIN); | ||||
const Consensus::Params ¶ms = Params().GetConsensus(); | GlobalConfig config; | ||||
int64_t nLastRetargetTime = 1231006505; // Block #0 | int64_t nLastRetargetTime = 1231006505; // Block #0 | ||||
CBlockIndex pindexLast; | CBlockIndex pindexLast; | ||||
pindexLast.nHeight = 2015; | pindexLast.nHeight = 2015; | ||||
pindexLast.nTime = 1233061996; // Block #2015 | pindexLast.nTime = 1233061996; // Block #2015 | ||||
pindexLast.nBits = 0x1d00ffff; | pindexLast.nBits = 0x1d00ffff; | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), | CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, config), | ||||
0x1d00ffff); | 0x1d00ffff); | ||||
} | } | ||||
/* Test the constraint on the lower bound for actual time taken */ | /* Test the constraint on the lower bound for actual time taken */ | ||||
BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual) { | BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual) { | ||||
SelectParams(CBaseChainParams::MAIN); | SelectParams(CBaseChainParams::MAIN); | ||||
const Consensus::Params ¶ms = Params().GetConsensus(); | GlobalConfig config; | ||||
int64_t nLastRetargetTime = 1279008237; // Block #66528 | int64_t nLastRetargetTime = 1279008237; // Block #66528 | ||||
CBlockIndex pindexLast; | CBlockIndex pindexLast; | ||||
pindexLast.nHeight = 68543; | pindexLast.nHeight = 68543; | ||||
pindexLast.nTime = 1279297671; // Block #68543 | pindexLast.nTime = 1279297671; // Block #68543 | ||||
pindexLast.nBits = 0x1c05a3f4; | pindexLast.nBits = 0x1c05a3f4; | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), | CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, config), | ||||
0x1c0168fd); | 0x1c0168fd); | ||||
} | } | ||||
/* Test the constraint on the upper bound for actual time taken */ | /* Test the constraint on the upper bound for actual time taken */ | ||||
BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual) { | BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual) { | ||||
SelectParams(CBaseChainParams::MAIN); | SelectParams(CBaseChainParams::MAIN); | ||||
const Consensus::Params ¶ms = Params().GetConsensus(); | GlobalConfig config; | ||||
int64_t nLastRetargetTime = 1263163443; // NOTE: Not an actual block time | int64_t nLastRetargetTime = 1263163443; // NOTE: Not an actual block time | ||||
CBlockIndex pindexLast; | CBlockIndex pindexLast; | ||||
pindexLast.nHeight = 46367; | pindexLast.nHeight = 46367; | ||||
pindexLast.nTime = 1269211443; // Block #46367 | pindexLast.nTime = 1269211443; // Block #46367 | ||||
pindexLast.nBits = 0x1c387f6f; | pindexLast.nBits = 0x1c387f6f; | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), | CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, config), | ||||
0x1d00e1fd); | 0x1d00e1fd); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test) { | BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test) { | ||||
SelectParams(CBaseChainParams::MAIN); | SelectParams(CBaseChainParams::MAIN); | ||||
const Consensus::Params ¶ms = Params().GetConsensus(); | const Consensus::Params ¶ms = Params().GetConsensus(); | ||||
std::vector<CBlockIndex> blocks(10000); | std::vector<CBlockIndex> blocks(10000); | ||||
Show All 26 Lines | static CBlockIndex GetBlockIndex(CBlockIndex *pindexPrev, int64_t nTimeInterval, | ||||
block.nBits = nBits; | block.nBits = nBits; | ||||
block.nChainWork = pindexPrev->nChainWork + GetBlockProof(block); | block.nChainWork = pindexPrev->nChainWork + GetBlockProof(block); | ||||
return block; | return block; | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(retargeting_test) { | BOOST_AUTO_TEST_CASE(retargeting_test) { | ||||
SelectParams(CBaseChainParams::MAIN); | SelectParams(CBaseChainParams::MAIN); | ||||
const Consensus::Params ¶ms = Params().GetConsensus(); | GlobalConfig config; | ||||
std::vector<CBlockIndex> blocks(115); | std::vector<CBlockIndex> blocks(115); | ||||
const Consensus::Params ¶ms = config.GetChainParams().GetConsensus(); | |||||
const arith_uint256 powLimit = UintToArith256(params.powLimit); | const arith_uint256 powLimit = UintToArith256(params.powLimit); | ||||
arith_uint256 currentPow = powLimit >> 1; | arith_uint256 currentPow = powLimit >> 1; | ||||
uint32_t initialBits = currentPow.GetCompact(); | uint32_t initialBits = currentPow.GetCompact(); | ||||
// Genesis block. | // Genesis block. | ||||
blocks[0] = CBlockIndex(); | blocks[0] = CBlockIndex(); | ||||
blocks[0].nHeight = 0; | blocks[0].nHeight = 0; | ||||
blocks[0].nTime = 1269211443; | blocks[0].nTime = 1269211443; | ||||
Show All 10 Lines | BOOST_AUTO_TEST_CASE(retargeting_test) { | ||||
CBlockHeader blkHeaderDummy; | CBlockHeader blkHeaderDummy; | ||||
// We start getting 2h blocks time. For the first 5 blocks, it doesn't | // We start getting 2h blocks time. For the first 5 blocks, it doesn't | ||||
// matter as the MTP is not affected. For the next 5 block, MTP difference | // matter as the MTP is not affected. For the next 5 block, MTP difference | ||||
// increases but stays below 12h. | // increases but stays below 12h. | ||||
for (size_t i = 100; i < 110; i++) { | for (size_t i = 100; i < 110; i++) { | ||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 2 * 3600, initialBits); | blocks[i] = GetBlockIndex(&blocks[i - 1], 2 * 3600, initialBits); | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
GetNextWorkRequired(&blocks[i], &blkHeaderDummy, params), | GetNextWorkRequired(&blocks[i], &blkHeaderDummy, config), | ||||
initialBits); | initialBits); | ||||
} | } | ||||
// Now we expect the difficulty to decrease. | // Now we expect the difficulty to decrease. | ||||
blocks[110] = GetBlockIndex(&blocks[109], 2 * 3600, initialBits); | blocks[110] = GetBlockIndex(&blocks[109], 2 * 3600, initialBits); | ||||
currentPow.SetCompact(currentPow.GetCompact()); | currentPow.SetCompact(currentPow.GetCompact()); | ||||
currentPow += (currentPow >> 2); | currentPow += (currentPow >> 2); | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
GetNextWorkRequired(&blocks[110], &blkHeaderDummy, params), | GetNextWorkRequired(&blocks[110], &blkHeaderDummy, config), | ||||
currentPow.GetCompact()); | currentPow.GetCompact()); | ||||
// As we continue with 2h blocks, difficulty continue to decrease. | // As we continue with 2h blocks, difficulty continue to decrease. | ||||
blocks[111] = | blocks[111] = | ||||
GetBlockIndex(&blocks[110], 2 * 3600, currentPow.GetCompact()); | GetBlockIndex(&blocks[110], 2 * 3600, currentPow.GetCompact()); | ||||
currentPow.SetCompact(currentPow.GetCompact()); | currentPow.SetCompact(currentPow.GetCompact()); | ||||
currentPow += (currentPow >> 2); | currentPow += (currentPow >> 2); | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
GetNextWorkRequired(&blocks[111], &blkHeaderDummy, params), | GetNextWorkRequired(&blocks[111], &blkHeaderDummy, config), | ||||
currentPow.GetCompact()); | currentPow.GetCompact()); | ||||
// We decrease again. | // We decrease again. | ||||
blocks[112] = | blocks[112] = | ||||
GetBlockIndex(&blocks[111], 2 * 3600, currentPow.GetCompact()); | GetBlockIndex(&blocks[111], 2 * 3600, currentPow.GetCompact()); | ||||
currentPow.SetCompact(currentPow.GetCompact()); | currentPow.SetCompact(currentPow.GetCompact()); | ||||
currentPow += (currentPow >> 2); | currentPow += (currentPow >> 2); | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
GetNextWorkRequired(&blocks[112], &blkHeaderDummy, params), | GetNextWorkRequired(&blocks[112], &blkHeaderDummy, config), | ||||
currentPow.GetCompact()); | currentPow.GetCompact()); | ||||
// We check that we do not go below the minimal difficulty. | // We check that we do not go below the minimal difficulty. | ||||
blocks[113] = | blocks[113] = | ||||
GetBlockIndex(&blocks[112], 2 * 3600, currentPow.GetCompact()); | GetBlockIndex(&blocks[112], 2 * 3600, currentPow.GetCompact()); | ||||
currentPow.SetCompact(currentPow.GetCompact()); | currentPow.SetCompact(currentPow.GetCompact()); | ||||
currentPow += (currentPow >> 2); | currentPow += (currentPow >> 2); | ||||
BOOST_CHECK(powLimit.GetCompact() != currentPow.GetCompact()); | BOOST_CHECK(powLimit.GetCompact() != currentPow.GetCompact()); | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
GetNextWorkRequired(&blocks[113], &blkHeaderDummy, params), | GetNextWorkRequired(&blocks[113], &blkHeaderDummy, config), | ||||
powLimit.GetCompact()); | powLimit.GetCompact()); | ||||
// Once we reached the minimal difficulty, we stick with it. | // Once we reached the minimal difficulty, we stick with it. | ||||
blocks[114] = GetBlockIndex(&blocks[113], 2 * 3600, powLimit.GetCompact()); | blocks[114] = GetBlockIndex(&blocks[113], 2 * 3600, powLimit.GetCompact()); | ||||
BOOST_CHECK(powLimit.GetCompact() != currentPow.GetCompact()); | BOOST_CHECK(powLimit.GetCompact() != currentPow.GetCompact()); | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
GetNextWorkRequired(&blocks[114], &blkHeaderDummy, params), | GetNextWorkRequired(&blocks[114], &blkHeaderDummy, config), | ||||
powLimit.GetCompact()); | powLimit.GetCompact()); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(cash_difficulty_test) { | BOOST_AUTO_TEST_CASE(cash_difficulty_test) { | ||||
SelectParams(CBaseChainParams::MAIN); | SelectParams(CBaseChainParams::MAIN); | ||||
const Consensus::Params ¶ms = Params().GetConsensus(); | GlobalConfig config; | ||||
std::vector<CBlockIndex> blocks(3000); | std::vector<CBlockIndex> blocks(3000); | ||||
const Consensus::Params ¶ms = config.GetChainParams().GetConsensus(); | |||||
const arith_uint256 powLimit = UintToArith256(params.powLimit); | const arith_uint256 powLimit = UintToArith256(params.powLimit); | ||||
uint32_t powLimitBits = powLimit.GetCompact(); | uint32_t powLimitBits = powLimit.GetCompact(); | ||||
arith_uint256 currentPow = powLimit >> 4; | arith_uint256 currentPow = powLimit >> 4; | ||||
uint32_t initialBits = currentPow.GetCompact(); | uint32_t initialBits = currentPow.GetCompact(); | ||||
// Genesis block. | // Genesis block. | ||||
blocks[0] = CBlockIndex(); | blocks[0] = CBlockIndex(); | ||||
blocks[0].nHeight = 0; | blocks[0].nHeight = 0; | ||||
blocks[0].nTime = 1269211443; | blocks[0].nTime = 1269211443; | ||||
blocks[0].nBits = initialBits; | blocks[0].nBits = initialBits; | ||||
blocks[0].nChainWork = GetBlockProof(blocks[0]); | blocks[0].nChainWork = GetBlockProof(blocks[0]); | ||||
// Block counter. | // Block counter. | ||||
size_t i; | size_t i; | ||||
// Pile up some blocks every 10 mins to establish some history. | // Pile up some blocks every 10 mins to establish some history. | ||||
for (i = 1; i < 2050; i++) { | for (i = 1; i < 2050; i++) { | ||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 600, initialBits); | blocks[i] = GetBlockIndex(&blocks[i - 1], 600, initialBits); | ||||
} | } | ||||
CBlockHeader blkHeaderDummy; | CBlockHeader blkHeaderDummy; | ||||
uint32_t nBits = | uint32_t nBits = | ||||
GetNextCashWorkRequired(&blocks[2049], &blkHeaderDummy, params); | GetNextCashWorkRequired(&blocks[2049], &blkHeaderDummy, config); | ||||
// Difficulty stays the same as long as we produce a block every 10 mins. | // Difficulty stays the same as long as we produce a block every 10 mins. | ||||
for (size_t j = 0; j < 10; i++, j++) { | for (size_t j = 0; j < 10; i++, j++) { | ||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 600, nBits); | blocks[i] = GetBlockIndex(&blocks[i - 1], 600, nBits); | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params), | GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, config), | ||||
nBits); | nBits); | ||||
} | } | ||||
// Make sure we skip over blocks that are out of wack. To do so, we produce | // Make sure we skip over blocks that are out of wack. To do so, we produce | ||||
// a block that is far in the future, and then produce a block with the | // a block that is far in the future, and then produce a block with the | ||||
// expected timestamp. | // expected timestamp. | ||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); | blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params), nBits); | GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, config), nBits); | ||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 2 * 600 - 6000, nBits); | blocks[i] = GetBlockIndex(&blocks[i - 1], 2 * 600 - 6000, nBits); | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params), nBits); | GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, config), nBits); | ||||
// The system should continue unaffected by the block with a bogous | // The system should continue unaffected by the block with a bogous | ||||
// timestamps. | // timestamps. | ||||
for (size_t j = 0; j < 20; i++, j++) { | for (size_t j = 0; j < 20; i++, j++) { | ||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 600, nBits); | blocks[i] = GetBlockIndex(&blocks[i - 1], 600, nBits); | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params), | GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, config), | ||||
nBits); | nBits); | ||||
} | } | ||||
// We start emitting blocks slightly faster. The first block has no impact. | // We start emitting blocks slightly faster. The first block has no impact. | ||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 550, nBits); | blocks[i] = GetBlockIndex(&blocks[i - 1], 550, nBits); | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params), nBits); | GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, config), nBits); | ||||
// Now we should see difficulty increase slowly. | // Now we should see difficulty increase slowly. | ||||
for (size_t j = 0; j < 10; i++, j++) { | for (size_t j = 0; j < 10; i++, j++) { | ||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 550, nBits); | blocks[i] = GetBlockIndex(&blocks[i - 1], 550, nBits); | ||||
const uint32_t nextBits = | const uint32_t nextBits = | ||||
GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, config); | ||||
arith_uint256 currentTarget; | arith_uint256 currentTarget; | ||||
currentTarget.SetCompact(nBits); | currentTarget.SetCompact(nBits); | ||||
arith_uint256 nextTarget; | arith_uint256 nextTarget; | ||||
nextTarget.SetCompact(nextBits); | nextTarget.SetCompact(nextBits); | ||||
// Make sure that difficulty increases very slowly. | // Make sure that difficulty increases very slowly. | ||||
BOOST_CHECK(nextTarget < currentTarget); | BOOST_CHECK(nextTarget < currentTarget); | ||||
BOOST_CHECK((currentTarget - nextTarget) < (currentTarget >> 10)); | BOOST_CHECK((currentTarget - nextTarget) < (currentTarget >> 10)); | ||||
nBits = nextBits; | nBits = nextBits; | ||||
} | } | ||||
// Check the actual value. | // Check the actual value. | ||||
BOOST_CHECK_EQUAL(nBits, 0x1c0fe7b1); | BOOST_CHECK_EQUAL(nBits, 0x1c0fe7b1); | ||||
// If we dramatically shorten block production, difficulty increases faster. | // If we dramatically shorten block production, difficulty increases faster. | ||||
for (size_t j = 0; j < 20; i++, j++) { | for (size_t j = 0; j < 20; i++, j++) { | ||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 10, nBits); | blocks[i] = GetBlockIndex(&blocks[i - 1], 10, nBits); | ||||
const uint32_t nextBits = | const uint32_t nextBits = | ||||
GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, config); | ||||
arith_uint256 currentTarget; | arith_uint256 currentTarget; | ||||
currentTarget.SetCompact(nBits); | currentTarget.SetCompact(nBits); | ||||
arith_uint256 nextTarget; | arith_uint256 nextTarget; | ||||
nextTarget.SetCompact(nextBits); | nextTarget.SetCompact(nextBits); | ||||
// Make sure that difficulty increases faster. | // Make sure that difficulty increases faster. | ||||
BOOST_CHECK(nextTarget < currentTarget); | BOOST_CHECK(nextTarget < currentTarget); | ||||
BOOST_CHECK((currentTarget - nextTarget) < (currentTarget >> 4)); | BOOST_CHECK((currentTarget - nextTarget) < (currentTarget >> 4)); | ||||
nBits = nextBits; | nBits = nextBits; | ||||
} | } | ||||
// Check the actual value. | // Check the actual value. | ||||
BOOST_CHECK_EQUAL(nBits, 0x1c0db19f); | BOOST_CHECK_EQUAL(nBits, 0x1c0db19f); | ||||
// We start to emit blocks significantly slower. The first block has no | // We start to emit blocks significantly slower. The first block has no | ||||
// impact. | // impact. | ||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); | blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); | ||||
nBits = GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params); | nBits = GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, config); | ||||
// Check the actual value. | // Check the actual value. | ||||
BOOST_CHECK_EQUAL(nBits, 0x1c0d9222); | BOOST_CHECK_EQUAL(nBits, 0x1c0d9222); | ||||
// If we dramatically slow down block production, difficulty decreases. | // If we dramatically slow down block production, difficulty decreases. | ||||
for (size_t j = 0; j < 93; i++, j++) { | for (size_t j = 0; j < 93; i++, j++) { | ||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); | blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); | ||||
const uint32_t nextBits = | const uint32_t nextBits = | ||||
GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, config); | ||||
arith_uint256 currentTarget; | arith_uint256 currentTarget; | ||||
currentTarget.SetCompact(nBits); | currentTarget.SetCompact(nBits); | ||||
arith_uint256 nextTarget; | arith_uint256 nextTarget; | ||||
nextTarget.SetCompact(nextBits); | nextTarget.SetCompact(nextBits); | ||||
// Check the difficulty decreases. | // Check the difficulty decreases. | ||||
BOOST_CHECK(nextTarget <= powLimit); | BOOST_CHECK(nextTarget <= powLimit); | ||||
BOOST_CHECK(nextTarget > currentTarget); | BOOST_CHECK(nextTarget > currentTarget); | ||||
BOOST_CHECK((nextTarget - currentTarget) < (currentTarget >> 3)); | BOOST_CHECK((nextTarget - currentTarget) < (currentTarget >> 3)); | ||||
nBits = nextBits; | nBits = nextBits; | ||||
} | } | ||||
// Check the actual value. | // Check the actual value. | ||||
BOOST_CHECK_EQUAL(nBits, 0x1c2f13b9); | BOOST_CHECK_EQUAL(nBits, 0x1c2f13b9); | ||||
// Due to the window of time being bounded, next block's difficulty actually | // Due to the window of time being bounded, next block's difficulty actually | ||||
// gets harder. | // gets harder. | ||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); | blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); | ||||
nBits = GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params); | nBits = GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, config); | ||||
BOOST_CHECK_EQUAL(nBits, 0x1c2ee9bf); | BOOST_CHECK_EQUAL(nBits, 0x1c2ee9bf); | ||||
// And goes down again. It takes a while due to the window being bounded and | // And goes down again. It takes a while due to the window being bounded and | ||||
// the skewed block causes 2 blocks to get out of the window. | // the skewed block causes 2 blocks to get out of the window. | ||||
for (size_t j = 0; j < 192; i++, j++) { | for (size_t j = 0; j < 192; i++, j++) { | ||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); | blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); | ||||
const uint32_t nextBits = | const uint32_t nextBits = | ||||
GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, config); | ||||
arith_uint256 currentTarget; | arith_uint256 currentTarget; | ||||
currentTarget.SetCompact(nBits); | currentTarget.SetCompact(nBits); | ||||
arith_uint256 nextTarget; | arith_uint256 nextTarget; | ||||
nextTarget.SetCompact(nextBits); | nextTarget.SetCompact(nextBits); | ||||
// Check the difficulty decreases. | // Check the difficulty decreases. | ||||
BOOST_CHECK(nextTarget <= powLimit); | BOOST_CHECK(nextTarget <= powLimit); | ||||
BOOST_CHECK(nextTarget > currentTarget); | BOOST_CHECK(nextTarget > currentTarget); | ||||
BOOST_CHECK((nextTarget - currentTarget) < (currentTarget >> 3)); | BOOST_CHECK((nextTarget - currentTarget) < (currentTarget >> 3)); | ||||
nBits = nextBits; | nBits = nextBits; | ||||
} | } | ||||
// Check the actual value. | // Check the actual value. | ||||
BOOST_CHECK_EQUAL(nBits, 0x1d00ffff); | BOOST_CHECK_EQUAL(nBits, 0x1d00ffff); | ||||
// Once the difficulty reached the minimum allowed level, it doesn't get any | // Once the difficulty reached the minimum allowed level, it doesn't get any | ||||
// easier. | // easier. | ||||
for (size_t j = 0; j < 5; i++, j++) { | for (size_t j = 0; j < 5; i++, j++) { | ||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); | blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); | ||||
const uint32_t nextBits = | const uint32_t nextBits = | ||||
GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, config); | ||||
// Check the difficulty stays constant. | // Check the difficulty stays constant. | ||||
BOOST_CHECK_EQUAL(nextBits, powLimitBits); | BOOST_CHECK_EQUAL(nextBits, powLimitBits); | ||||
nBits = nextBits; | nBits = nextBits; | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |