Changeset View
Changeset View
Standalone View
Standalone View
src/test/pow_tests.cpp
Show First 20 Lines • Show All 181 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(retargeting_test) { | ||||
// 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, params), | ||||
powLimit.GetCompact()); | powLimit.GetCompact()); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(cash_difficulty_test) { | |||||
SelectParams(CBaseChainParams::MAIN); | |||||
const Consensus::Params ¶ms = Params().GetConsensus(); | |||||
std::vector<CBlockIndex> blocks(3000); | |||||
const arith_uint256 powLimit = UintToArith256(params.powLimit); | |||||
uint32_t powLimitBits = powLimit.GetCompact(); | |||||
arith_uint256 currentPow = powLimit >> 4; | |||||
uint32_t initialBits = currentPow.GetCompact(); | |||||
// Genesis block. | |||||
blocks[0] = CBlockIndex(); | |||||
blocks[0].nHeight = 0; | |||||
blocks[0].nTime = 1269211443; | |||||
blocks[0].nBits = initialBits; | |||||
// Block counter. | |||||
size_t i; | |||||
// Pile up some blocks every 10 mins to establish some history. | |||||
for (i = 1; i < 2050; i++) { | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 600, initialBits); | |||||
} | |||||
CBlockHeader blkHeaderDummy; | |||||
uint32_t nextBits; | |||||
uint32_t nBits = | |||||
GetNextCashWorkRequired(&blocks[2049], &blkHeaderDummy, params); | |||||
// Difficulty stays the same as long as we produce a block every 10 mins. | |||||
for (size_t j = 0; j < 10; i++, j++) { | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 600, nBits); | |||||
BOOST_CHECK_EQUAL( | |||||
GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params), | |||||
nBits); | |||||
} | |||||
// Produce a block that is far in the future | |||||
// This will produce a one-time difficulty drop of about 13% | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); | |||||
nextBits = GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params); | |||||
BOOST_CHECK_EQUAL(nextBits, 0x1c11fc76); | |||||
nBits = nextBits; | |||||
// Now produce a block with the expected timestamp. | |||||
// This block counts as +0s, a ~1.5% difficulty raise | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 2 * 600 - 6000, nBits); | |||||
nextBits = GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params); | |||||
BOOST_CHECK_EQUAL(nextBits, 0x1c11c06f); | |||||
nBits = nextBits; | |||||
// The effect of the bogus timestamp is dissipated over the next 8 blocks | |||||
for (size_t j = 0; j < 8; i++, j++) { | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 600, nBits); | |||||
nextBits = GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | |||||
arith_uint256 currentTarget; | |||||
currentTarget.SetCompact(nBits); | |||||
arith_uint256 nextTarget; | |||||
nextTarget.SetCompact(nextBits); | |||||
// Check the difficulty decreases. | |||||
BOOST_CHECK(nextTarget <= powLimit); | |||||
BOOST_CHECK(nextTarget < currentTarget); | |||||
BOOST_CHECK((currentTarget - nextTarget) < (currentTarget >> 6)); | |||||
nBits = nextBits; | |||||
} | |||||
// We start emitting blocks slightly faster. | |||||
// Difficulty should increase slowly. | |||||
for (size_t j = 0; j < 10; i++, j++) { | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 550, nBits); | |||||
nextBits = GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | |||||
arith_uint256 currentTarget; | |||||
currentTarget.SetCompact(nBits); | |||||
arith_uint256 nextTarget; | |||||
nextTarget.SetCompact(nextBits); | |||||
// Make sure that difficulty increases slowly. | |||||
BOOST_CHECK(nextTarget < currentTarget); | |||||
BOOST_CHECK((currentTarget - nextTarget) < (currentTarget >> 8)); | |||||
nBits = nextBits; | |||||
} | |||||
// Check the actual value. | |||||
BOOST_CHECK_EQUAL(nBits, 0x1c0fbbc5); | |||||
// If we dramatically shorten block production, difficulty increases faster. | |||||
for (size_t j = 0; j < 20; i++, j++) { | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 10, nBits); | |||||
nextBits = GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | |||||
arith_uint256 currentTarget; | |||||
currentTarget.SetCompact(nBits); | |||||
arith_uint256 nextTarget; | |||||
nextTarget.SetCompact(nextBits); | |||||
// Make sure that difficulty increases faster. | |||||
BOOST_CHECK(nextTarget < currentTarget); | |||||
BOOST_CHECK((currentTarget - nextTarget) < (currentTarget >> 4)); | |||||
nBits = nextBits; | |||||
} | |||||
// Check the actual value. | |||||
BOOST_CHECK_EQUAL(nBits, 0x1c0bb2b6); | |||||
// If we dramatically slow down block production, difficulty decreases. | |||||
for (size_t j = 0; j < 31; i++, j++) { | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 5000, nBits); | |||||
nextBits = GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | |||||
arith_uint256 currentTarget; | |||||
currentTarget.SetCompact(nBits); | |||||
arith_uint256 nextTarget; | |||||
nextTarget.SetCompact(nextBits); | |||||
// Check the difficulty decreases. | |||||
BOOST_CHECK(nextTarget <= powLimit); | |||||
BOOST_CHECK(nextTarget > currentTarget); | |||||
BOOST_CHECK((nextTarget - currentTarget) < (currentTarget >> 3)); | |||||
nBits = nextBits; | |||||
} | |||||
// Check the actual value. We should have just reached the limit. | |||||
BOOST_CHECK_EQUAL(nBits, 0x1d00ffff); | |||||
// Once the difficulty reached the minimum allowed level, it doesn't get any | |||||
// easier. | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 900, nBits); | |||||
nextBits = GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params); | |||||
BOOST_CHECK_EQUAL(nextBits, powLimitBits); | |||||
nBits = nextBits; | |||||
// Undo the effect of the last block | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 0, nBits); | |||||
nextBits = GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params); | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 0, nBits); | |||||
nextBits = GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params); | |||||
// Raise the difficulty back up above the minimum limit | |||||
// Make a large number of fast blocks | |||||
for (size_t j = 0; j < 31; i++, j++) { | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 0, nBits); | |||||
nextBits = GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | |||||
arith_uint256 currentTarget; | |||||
currentTarget.SetCompact(nBits); | |||||
arith_uint256 nextTarget; | |||||
nextTarget.SetCompact(nextBits); | |||||
// Check the difficulty increases. | |||||
BOOST_CHECK(nextTarget <= powLimit); | |||||
BOOST_CHECK(nextTarget < currentTarget); | |||||
BOOST_CHECK((currentTarget - nextTarget) < (currentTarget >> 6)); | |||||
nBits = nextBits; | |||||
} | |||||
// Check the actual value. | |||||
BOOST_CHECK_EQUAL(nBits, 0x1d00c296); | |||||
// Mine neutral blocks | |||||
// Difficulty continues to change slightly as weights shift | |||||
for (size_t j = 0; j < 10; i++, j++) { | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 600, nBits); | |||||
nextBits = GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | |||||
arith_uint256 currentTarget; | |||||
currentTarget.SetCompact(nBits); | |||||
arith_uint256 nextTarget; | |||||
nextTarget.SetCompact(nextBits); | |||||
BOOST_CHECK(nextTarget <= powLimit); | |||||
BOOST_CHECK(nextTarget > currentTarget); | |||||
BOOST_CHECK((nextTarget - currentTarget) < (currentTarget >> 7)); | |||||
nBits = nextBits; | |||||
} | |||||
} | |||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |