Add multi-algo chainwork branch regression test
This commit is contained in:
parent
287a84a533
commit
3b26ac9397
1 changed files with 162 additions and 0 deletions
|
|
@ -152,6 +152,168 @@ BOOST_AUTO_TEST_CASE(MultiAlgo_chainwork_normalization_test)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(MultiAlgo_chainwork_branch_accumulation_test)
|
||||||
|
{
|
||||||
|
auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
|
||||||
|
auto consensus = chainParams->GetConsensus();
|
||||||
|
|
||||||
|
// Test-only activation. Mainnet RandomX remains disabled.
|
||||||
|
consensus.randomXActivationHeight = 40;
|
||||||
|
|
||||||
|
std::vector<CBlockIndex> history(40);
|
||||||
|
|
||||||
|
arith_uint256 shaTarget = UintToArith256(consensus.powLimit);
|
||||||
|
shaTarget >>= 8;
|
||||||
|
const unsigned int shaBits = shaTarget.GetCompact();
|
||||||
|
|
||||||
|
const int64_t startTime = 1800000000;
|
||||||
|
|
||||||
|
CBlockIndex* latest[NUM_ALGOS_IMPL]{};
|
||||||
|
|
||||||
|
for (int i = 0; i < 40; ++i) {
|
||||||
|
CBlockIndex& block = history[i];
|
||||||
|
|
||||||
|
block.pprev = i ? &history[i - 1] : nullptr;
|
||||||
|
block.nHeight = i;
|
||||||
|
block.nTime = startTime + i * consensus.nPowTargetSpacing;
|
||||||
|
block.nBits = shaBits;
|
||||||
|
block.nVersion =
|
||||||
|
BLOCK_VERSION_DEFAULT | BLOCK_VERSION_SHA256D;
|
||||||
|
|
||||||
|
for (int algo = 0; algo < NUM_ALGOS_IMPL; ++algo) {
|
||||||
|
block.lastAlgoBlocks[algo] = latest[algo];
|
||||||
|
}
|
||||||
|
|
||||||
|
latest[ALGO_SHA256D] = █
|
||||||
|
|
||||||
|
block.nChainWork =
|
||||||
|
(block.pprev ? block.pprev->nChainWork : arith_uint256{0}) +
|
||||||
|
GetBlockProof(block, consensus);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto buildChild =
|
||||||
|
[&](CBlockIndex& child,
|
||||||
|
CBlockIndex& parent,
|
||||||
|
int algo,
|
||||||
|
uint32_t time) {
|
||||||
|
child.pprev = &parent;
|
||||||
|
child.nHeight = parent.nHeight + 1;
|
||||||
|
child.nTime = time;
|
||||||
|
child.nVersion =
|
||||||
|
BLOCK_VERSION_DEFAULT |
|
||||||
|
(algo == ALGO_RANDOMX
|
||||||
|
? BLOCK_VERSION_RANDOMX
|
||||||
|
: BLOCK_VERSION_SHA256D);
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_ALGOS_IMPL; ++i) {
|
||||||
|
child.lastAlgoBlocks[i] = parent.lastAlgoBlocks[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
child.nBits =
|
||||||
|
GetNextWorkRequired(
|
||||||
|
&parent,
|
||||||
|
nullptr,
|
||||||
|
consensus,
|
||||||
|
algo);
|
||||||
|
|
||||||
|
child.lastAlgoBlocks[algo] = &child;
|
||||||
|
|
||||||
|
child.nChainWork =
|
||||||
|
parent.nChainWork +
|
||||||
|
GetBlockProof(child, consensus);
|
||||||
|
};
|
||||||
|
|
||||||
|
CBlockIndex shaBranch1;
|
||||||
|
CBlockIndex randomXBranch1;
|
||||||
|
|
||||||
|
const uint32_t firstTime =
|
||||||
|
history[39].nTime + consensus.nPowTargetSpacing;
|
||||||
|
|
||||||
|
buildChild(
|
||||||
|
shaBranch1,
|
||||||
|
history[39],
|
||||||
|
ALGO_SHA256D,
|
||||||
|
firstTime);
|
||||||
|
|
||||||
|
buildChild(
|
||||||
|
randomXBranch1,
|
||||||
|
history[39],
|
||||||
|
ALGO_RANDOMX,
|
||||||
|
firstTime);
|
||||||
|
|
||||||
|
// Native SHA256D and RandomX targets differ, but siblings over the same
|
||||||
|
// parent must receive exactly the same normalized chainwork increment.
|
||||||
|
BOOST_REQUIRE(
|
||||||
|
GetBlockProof(shaBranch1) !=
|
||||||
|
GetBlockProof(randomXBranch1));
|
||||||
|
|
||||||
|
BOOST_CHECK(
|
||||||
|
GetBlockProof(shaBranch1, consensus) ==
|
||||||
|
GetBlockProof(randomXBranch1, consensus));
|
||||||
|
|
||||||
|
BOOST_CHECK(
|
||||||
|
shaBranch1.nChainWork ==
|
||||||
|
randomXBranch1.nChainWork);
|
||||||
|
|
||||||
|
// Extend both competing branches with the opposite algorithm.
|
||||||
|
CBlockIndex shaThenRandomX;
|
||||||
|
CBlockIndex randomXThenSha;
|
||||||
|
|
||||||
|
const uint32_t secondTime =
|
||||||
|
firstTime + consensus.nPowTargetSpacing;
|
||||||
|
|
||||||
|
buildChild(
|
||||||
|
shaThenRandomX,
|
||||||
|
shaBranch1,
|
||||||
|
ALGO_RANDOMX,
|
||||||
|
secondTime);
|
||||||
|
|
||||||
|
buildChild(
|
||||||
|
randomXThenSha,
|
||||||
|
randomXBranch1,
|
||||||
|
ALGO_SHA256D,
|
||||||
|
secondTime);
|
||||||
|
|
||||||
|
// Each branch must accumulate exactly the normalized proof selected by
|
||||||
|
// consensus, never the algorithm's raw native proof.
|
||||||
|
BOOST_CHECK(
|
||||||
|
shaThenRandomX.nChainWork ==
|
||||||
|
shaBranch1.nChainWork +
|
||||||
|
GetBlockProof(shaThenRandomX, consensus));
|
||||||
|
|
||||||
|
BOOST_CHECK(
|
||||||
|
randomXThenSha.nChainWork ==
|
||||||
|
randomXBranch1.nChainWork +
|
||||||
|
GetBlockProof(randomXThenSha, consensus));
|
||||||
|
|
||||||
|
BOOST_CHECK(
|
||||||
|
shaThenRandomX.nChainWork >
|
||||||
|
shaBranch1.nChainWork);
|
||||||
|
|
||||||
|
BOOST_CHECK(
|
||||||
|
randomXThenSha.nChainWork >
|
||||||
|
randomXBranch1.nChainWork);
|
||||||
|
|
||||||
|
// Verify the per-algo links were propagated exactly like AddToBlockIndex.
|
||||||
|
BOOST_CHECK(
|
||||||
|
shaThenRandomX.lastAlgoBlocks[ALGO_RANDOMX] ==
|
||||||
|
&shaThenRandomX);
|
||||||
|
|
||||||
|
BOOST_CHECK(
|
||||||
|
shaThenRandomX.lastAlgoBlocks[ALGO_SHA256D] ==
|
||||||
|
&shaBranch1);
|
||||||
|
|
||||||
|
BOOST_CHECK(
|
||||||
|
randomXThenSha.lastAlgoBlocks[ALGO_SHA256D] ==
|
||||||
|
&randomXThenSha);
|
||||||
|
|
||||||
|
BOOST_CHECK(
|
||||||
|
randomXThenSha.lastAlgoBlocks[ALGO_RANDOMX] ==
|
||||||
|
&randomXBranch1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test)
|
BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test)
|
||||||
{
|
{
|
||||||
const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
|
const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue