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(2500); | |||||
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 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); | |||||
} | |||||
// 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 | |||||
// expected timestamp. | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); | |||||
BOOST_CHECK_EQUAL( | |||||
GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params), nBits); | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 2 * 600 - 6000, nBits); | |||||
BOOST_CHECK_EQUAL( | |||||
GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params), nBits); | |||||
// The system should continue unaffected by the block with a bogus | |||||
// timestamps. | |||||
for (size_t j = 0; j < 20; i++, j++) { | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 600, nBits); | |||||
BOOST_CHECK_EQUAL( | |||||
GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params), | |||||
nBits); | |||||
} | |||||
// We start emitting blocks faster. Because we use a 6-block MTP | |||||
// difference, and 299s is at the boundary, it takes 11 blocks to | |||||
// have an impact. Then we should see difficulty increase slowly. | |||||
for (size_t j = 0; j < 15; i++, j++) { | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 299, nBits); | |||||
uint32_t nextBits = | |||||
GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | |||||
if (j < 10) { | |||||
BOOST_CHECK_EQUAL(nextBits, nBits); | |||||
} else { | |||||
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 / 250)); | |||||
BOOST_CHECK((currentTarget - nextTarget) > (currentTarget / 260)); | |||||
} | |||||
nBits = nextBits; | |||||
} | |||||
// Back to normal; difficulty stops increasing only after the 600s | |||||
// blocks enter the median | |||||
for (size_t j = 0; j < 15; i++, j++) { | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 600, nBits); | |||||
uint32_t nextBits = | |||||
GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | |||||
if (j < 5) { | |||||
BOOST_CHECK(nextBits < nBits); | |||||
} else { | |||||
BOOST_CHECK_EQUAL(nextBits, nBits); | |||||
} | |||||
nBits = nextBits; | |||||
} | |||||
// Start emitting blocks slowly. Because we use a 6-block MTP | |||||
// difference and gaps are 1 hour, it takes until j is 6 for the MTP | |||||
// diff to go above the window and start to decrease difficulty. | |||||
for (size_t j = 0; j < 9; i++, j++) { | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 3600, nBits); | |||||
uint32_t nextBits = | |||||
GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | |||||
if (j < 6) { | |||||
BOOST_CHECK_EQUAL(nextBits, nBits); | |||||
} else { | |||||
arith_uint256 currentTarget; | |||||
currentTarget.SetCompact(nBits); | |||||
arith_uint256 nextTarget; | |||||
nextTarget.SetCompact(nextBits); | |||||
// Make sure that difficulty decreases as expected | |||||
BOOST_CHECK(nextTarget > currentTarget); | |||||
BOOST_CHECK((nextTarget - currentTarget) < (currentTarget / 60)); | |||||
BOOST_CHECK((nextTarget - currentTarget) > (currentTarget / 70)); | |||||
} | |||||
nBits = nextBits; | |||||
} | |||||
// Back to normal but difficulty continues to decrease until the | |||||
// MTP diff covers 5 10 minute blocks and 1 1 hour block | |||||
for (size_t j = 0; j < 15; i++, j++) { | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 600, nBits); | |||||
uint32_t nextBits = | |||||
GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | |||||
if (j < 9) { | |||||
BOOST_CHECK(nextBits > nBits); | |||||
} else { | |||||
BOOST_CHECK_EQUAL(nextBits, nBits); | |||||
} | |||||
nBits = nextBits; | |||||
} | |||||
// Once the difficulty reached the minimum allowed level, it | |||||
// doesn't get any easier. | |||||
for (size_t j = 0; j < 200; i++, j++) { | |||||
blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); | |||||
uint32_t nextBits = | |||||
GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); | |||||
// Check the difficulty reaches the limit but doesn't fall below it. | |||||
BOOST_CHECK(nextBits <= powLimitBits); | |||||
if (j > 190) BOOST_CHECK(nextBits == powLimitBits); | |||||
nBits = nextBits; | |||||
} | |||||
} | |||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |