Add deterministic RandomX seed schedule
This commit is contained in:
parent
1a927ccb44
commit
7ca340c248
7 changed files with 123 additions and 21 deletions
|
|
@ -184,6 +184,8 @@ public:
|
|||
consensus.asertHalfLife = 2 * 24 * 60 * 60;
|
||||
consensus.fastRiseActivationHeight = 7000;
|
||||
consensus.randomXActivationHeight = std::numeric_limits<int>::max();
|
||||
consensus.randomXSeedEpochLength = 2048;
|
||||
consensus.randomXSeedLag = 64;
|
||||
|
||||
|
||||
|
||||
|
|
@ -227,6 +229,8 @@ public:
|
|||
consensus.asertHalfLife = 2 * 24 * 60 * 60;
|
||||
consensus.fastRiseActivationHeight = 7000;
|
||||
consensus.randomXActivationHeight = std::numeric_limits<int>::max();
|
||||
consensus.randomXSeedEpochLength = 2048;
|
||||
consensus.randomXSeedLag = 64;
|
||||
|
||||
|
||||
|
||||
|
|
@ -374,6 +378,8 @@ public:
|
|||
consensus.fEasyPow = false;
|
||||
consensus.fPowNoRetargeting = false;
|
||||
consensus.randomXActivationHeight = std::numeric_limits<int>::max();
|
||||
consensus.randomXSeedEpochLength = 2048;
|
||||
consensus.randomXSeedLag = 64;
|
||||
consensus.nRuleChangeActivationThreshold = 1815; // 90% of 2016
|
||||
consensus.nMinerConfirmationWindow = 2016; // legacy Bitcoin confirmation window
|
||||
consensus.fRbfEnabled = false;
|
||||
|
|
@ -464,6 +470,8 @@ public:
|
|||
consensus.asertHalfLife = 2 * 24 * 60 * 60;
|
||||
consensus.fastRiseActivationHeight = 7000;
|
||||
consensus.randomXActivationHeight = std::numeric_limits<int>::max();
|
||||
consensus.randomXSeedEpochLength = 64;
|
||||
consensus.randomXSeedLag = 8;
|
||||
|
||||
|
||||
consensus.BIP65Height = 1351;
|
||||
|
|
|
|||
|
|
@ -125,6 +125,8 @@ struct Params {
|
|||
int64_t asertHalfLife;
|
||||
int fastRiseActivationHeight;
|
||||
int randomXActivationHeight;
|
||||
int randomXSeedEpochLength;
|
||||
int randomXSeedLag;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
47
src/pow.cpp
47
src/pow.cpp
|
|
@ -17,6 +17,53 @@ inline unsigned int PowLimit(const Consensus::Params& params)
|
|||
return UintToArith256(params.powLimit).GetCompact();
|
||||
}
|
||||
|
||||
int GetRandomXSeedHeight(int blockHeight, const Consensus::Params& params)
|
||||
{
|
||||
if (blockHeight <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const int epochLength = params.randomXSeedEpochLength;
|
||||
const int seedLag = params.randomXSeedLag;
|
||||
|
||||
if (epochLength <= 0 || seedLag < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const int epochStart = (blockHeight / epochLength) * epochLength;
|
||||
|
||||
if (epochStart <= seedLag) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return epochStart - seedLag;
|
||||
}
|
||||
|
||||
bool GetRandomXSeed(
|
||||
const CBlockIndex* pindexPrev,
|
||||
int blockHeight,
|
||||
const Consensus::Params& params,
|
||||
uint256& seed)
|
||||
{
|
||||
if (pindexPrev == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const int seedHeight = GetRandomXSeedHeight(blockHeight, params);
|
||||
|
||||
if (seedHeight > pindexPrev->nHeight) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const CBlockIndex* pindexSeed = pindexPrev->GetAncestor(seedHeight);
|
||||
if (pindexSeed == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
seed = pindexSeed->GetBlockHash();
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int InitialDifficulty(const Consensus::Params& params)
|
||||
{
|
||||
return PowLimit(params);
|
||||
|
|
|
|||
15
src/pow.h
15
src/pow.h
|
|
@ -22,4 +22,19 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
|
|||
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);
|
||||
const CBlockIndex* GetLastBlockIndexForAlgoFast(const CBlockIndex* pindex, int algo);
|
||||
|
||||
/** Return the block height whose hash is used as the RandomX seed key. */
|
||||
int GetRandomXSeedHeight(int blockHeight, const Consensus::Params& params);
|
||||
|
||||
/**
|
||||
* Resolve the RandomX seed key from the previous block index.
|
||||
*
|
||||
* The seed is always derived from an already-known ancestor block hash.
|
||||
* Returns false if the requested seed ancestor cannot be resolved.
|
||||
*/
|
||||
bool GetRandomXSeed(
|
||||
const CBlockIndex* pindexPrev,
|
||||
int blockHeight,
|
||||
const Consensus::Params& params,
|
||||
uint256& seed);
|
||||
|
||||
#endif // DIGIBYTE_POW_H
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ FUZZ_TARGET_INIT(pow, initialize_pow)
|
|||
{
|
||||
(void)GetBlockProof(current_block);
|
||||
if (current_block.nHeight != std::numeric_limits<int>::max() && current_block.nHeight - (consensus_params.nMinerConfirmationWindow - 1) >= 0) {
|
||||
(void)GetNextWorkRequired(¤t_block, &(*block_header), consensus_params);
|
||||
(void)GetNextWorkRequired(¤t_block, &(*block_header), consensus_params, ALGO_SHA256D);
|
||||
}
|
||||
}
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <pow.h>
|
||||
#include <primitives/block.h>
|
||||
#include <test/util/setup_common.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
|
@ -163,13 +164,13 @@ BOOST_AUTO_TEST_CASE(ASERT_behavior_test)
|
|||
|
||||
// Block 6499 is still governed by the legacy DAA.
|
||||
const unsigned int preActivationBits =
|
||||
GetNextWorkRequired(&blocks[6498], nullptr, consensus);
|
||||
GetNextWorkRequired(&blocks[6498], nullptr, consensus, ALGO_SHA256D);
|
||||
BOOST_CHECK_EQUAL(preActivationBits, anchorBits);
|
||||
|
||||
// Block 6500 is the first ASERT block. Ideal 10-minute spacing
|
||||
// must preserve the anchor target.
|
||||
const unsigned int idealBits =
|
||||
GetNextWorkRequired(&blocks[6499], nullptr, consensus);
|
||||
GetNextWorkRequired(&blocks[6499], nullptr, consensus, ALGO_SHA256D);
|
||||
BOOST_CHECK_EQUAL(idealBits, anchorBits);
|
||||
|
||||
// Block 6501 after a very fast previous block: target must decrease
|
||||
|
|
@ -178,7 +179,7 @@ BOOST_AUTO_TEST_CASE(ASERT_behavior_test)
|
|||
blocks[6499].nTime + consensus.nPowTargetSpacing / 10;
|
||||
|
||||
const unsigned int fastBits =
|
||||
GetNextWorkRequired(&blocks[6500], nullptr, consensus);
|
||||
GetNextWorkRequired(&blocks[6500], nullptr, consensus, ALGO_SHA256D);
|
||||
|
||||
arith_uint256 fastTarget;
|
||||
fastTarget.SetCompact(fastBits);
|
||||
|
|
@ -194,7 +195,7 @@ BOOST_AUTO_TEST_CASE(ASERT_behavior_test)
|
|||
blocks[6499].nTime + consensus.nPowTargetSpacing * 3;
|
||||
|
||||
const unsigned int slowBits =
|
||||
GetNextWorkRequired(&blocks[6500], nullptr, consensus);
|
||||
GetNextWorkRequired(&blocks[6500], nullptr, consensus, ALGO_SHA256D);
|
||||
|
||||
arith_uint256 slowTarget;
|
||||
slowTarget.SetCompact(slowBits);
|
||||
|
|
@ -206,7 +207,7 @@ BOOST_AUTO_TEST_CASE(ASERT_behavior_test)
|
|||
blocks[6499].nTime + consensus.asertHalfLife * 16;
|
||||
|
||||
const unsigned int extremeSlowBits =
|
||||
GetNextWorkRequired(&blocks[6500], nullptr, consensus);
|
||||
GetNextWorkRequired(&blocks[6500], nullptr, consensus, ALGO_SHA256D);
|
||||
|
||||
BOOST_CHECK_EQUAL(
|
||||
extremeSlowBits,
|
||||
|
|
@ -246,7 +247,7 @@ BOOST_AUTO_TEST_CASE(ASERT_reference_vector_run04_test)
|
|||
blocks[2].nBits = 0x01010000;
|
||||
|
||||
const unsigned int result =
|
||||
GetNextWorkRequired(&blocks[2], nullptr, consensus);
|
||||
GetNextWorkRequired(&blocks[2], nullptr, consensus, ALGO_SHA256D);
|
||||
|
||||
BOOST_CHECK_EQUAL(result, 0x01020000U);
|
||||
}
|
||||
|
|
@ -279,7 +280,7 @@ BOOST_AUTO_TEST_CASE(ASERT_reference_vector_run05_test)
|
|||
blocks[2].nBits = 0x1d00ffff;
|
||||
|
||||
BOOST_CHECK_EQUAL(
|
||||
GetNextWorkRequired(&blocks[2], nullptr, consensus),
|
||||
GetNextWorkRequired(&blocks[2], nullptr, consensus, ALGO_SHA256D),
|
||||
0x1d00fec5U);
|
||||
|
||||
// BCHN official ASERT run05 vector, iteration 2:
|
||||
|
|
@ -292,7 +293,7 @@ BOOST_AUTO_TEST_CASE(ASERT_reference_vector_run05_test)
|
|||
}
|
||||
|
||||
BOOST_CHECK_EQUAL(
|
||||
GetNextWorkRequired(&blocks[290], nullptr, consensus),
|
||||
GetNextWorkRequired(&blocks[290], nullptr, consensus, ALGO_SHA256D),
|
||||
0x1c7f62c0U);
|
||||
}
|
||||
|
||||
|
|
@ -346,7 +347,7 @@ BOOST_AUTO_TEST_CASE(ASERT_reference_vector_run06_test)
|
|||
blocks[h].nBits = 0x1802aee8;
|
||||
|
||||
BOOST_CHECK_EQUAL(
|
||||
GetNextWorkRequired(&blocks[h], nullptr, consensus),
|
||||
GetNextWorkRequired(&blocks[h], nullptr, consensus, ALGO_SHA256D),
|
||||
expected[h]);
|
||||
}
|
||||
}
|
||||
|
|
@ -386,9 +387,9 @@ BOOST_AUTO_TEST_CASE(FastRise_activation_and_trigger_test)
|
|||
baselineConsensus.fastRiseActivationHeight = 1000000;
|
||||
|
||||
const unsigned int twoFastBaseline =
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, baselineConsensus);
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, baselineConsensus, ALGO_SHA256D);
|
||||
const unsigned int twoFastResult =
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, consensus);
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, consensus, ALGO_SHA256D);
|
||||
|
||||
BOOST_CHECK_EQUAL(twoFastResult, twoFastBaseline);
|
||||
|
||||
|
|
@ -397,9 +398,9 @@ BOOST_AUTO_TEST_CASE(FastRise_activation_and_trigger_test)
|
|||
blocks[6999].nTime = blocks[6998].nTime + 600;
|
||||
|
||||
const unsigned int threeFastBaseline =
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, baselineConsensus);
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, baselineConsensus, ALGO_SHA256D);
|
||||
const unsigned int threeFastResult =
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, consensus);
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, consensus, ALGO_SHA256D);
|
||||
|
||||
arith_uint256 expectedFastTarget;
|
||||
expectedFastTarget.SetCompact(blocks[6999].nBits);
|
||||
|
|
@ -412,7 +413,7 @@ BOOST_AUTO_TEST_CASE(FastRise_activation_and_trigger_test)
|
|||
consensus.fastRiseActivationHeight = 7001;
|
||||
|
||||
const unsigned int preActivationResult =
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, consensus);
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, consensus, ALGO_SHA256D);
|
||||
|
||||
BOOST_CHECK_EQUAL(preActivationResult, threeFastBaseline);
|
||||
}
|
||||
|
|
@ -449,7 +450,7 @@ BOOST_AUTO_TEST_CASE(FastRise_returns_to_ASERT_test)
|
|||
blocks[6999].nTime = blocks[6998].nTime + 600;
|
||||
|
||||
const unsigned int triggeredBits =
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, consensus);
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, consensus, ALGO_SHA256D);
|
||||
|
||||
arith_uint256 triggeredTarget;
|
||||
triggeredTarget.SetCompact(triggeredBits);
|
||||
|
|
@ -470,10 +471,10 @@ BOOST_AUTO_TEST_CASE(FastRise_returns_to_ASERT_test)
|
|||
baselineConsensus.fastRiseActivationHeight = 1000000;
|
||||
|
||||
const unsigned int expectedASERT =
|
||||
GetNextWorkRequired(&blocks[7000], nullptr, baselineConsensus);
|
||||
GetNextWorkRequired(&blocks[7000], nullptr, baselineConsensus, ALGO_SHA256D);
|
||||
|
||||
const unsigned int actual =
|
||||
GetNextWorkRequired(&blocks[7000], nullptr, consensus);
|
||||
GetNextWorkRequired(&blocks[7000], nullptr, consensus, ALGO_SHA256D);
|
||||
|
||||
BOOST_CHECK_EQUAL(actual, expectedASERT);
|
||||
}
|
||||
|
|
@ -515,10 +516,10 @@ BOOST_AUTO_TEST_CASE(FastRise_zero_and_negative_intervals_test)
|
|||
baselineConsensus.fastRiseActivationHeight = 1000000;
|
||||
|
||||
const unsigned int baseline =
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, baselineConsensus);
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, baselineConsensus, ALGO_SHA256D);
|
||||
|
||||
const unsigned int actual =
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, consensus);
|
||||
GetNextWorkRequired(&blocks[6999], nullptr, consensus, ALGO_SHA256D);
|
||||
|
||||
arith_uint256 expectedFastTarget;
|
||||
expectedFastTarget.SetCompact(blocks[6999].nBits);
|
||||
|
|
@ -529,4 +530,32 @@ BOOST_AUTO_TEST_CASE(FastRise_zero_and_negative_intervals_test)
|
|||
}
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(RandomX_seed_height_test)
|
||||
{
|
||||
auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
|
||||
auto consensus = chainParams->GetConsensus();
|
||||
|
||||
BOOST_CHECK_EQUAL(consensus.randomXSeedEpochLength, 2048);
|
||||
BOOST_CHECK_EQUAL(consensus.randomXSeedLag, 64);
|
||||
|
||||
BOOST_CHECK_EQUAL(GetRandomXSeedHeight(0, consensus), 0);
|
||||
BOOST_CHECK_EQUAL(GetRandomXSeedHeight(1, consensus), 0);
|
||||
BOOST_CHECK_EQUAL(GetRandomXSeedHeight(64, consensus), 0);
|
||||
BOOST_CHECK_EQUAL(GetRandomXSeedHeight(2047, consensus), 0);
|
||||
BOOST_CHECK_EQUAL(GetRandomXSeedHeight(2048, consensus), 1984);
|
||||
BOOST_CHECK_EQUAL(GetRandomXSeedHeight(2049, consensus), 1984);
|
||||
BOOST_CHECK_EQUAL(GetRandomXSeedHeight(4095, consensus), 1984);
|
||||
BOOST_CHECK_EQUAL(GetRandomXSeedHeight(4096, consensus), 4032);
|
||||
BOOST_CHECK_EQUAL(GetRandomXSeedHeight(6144, consensus), 6080);
|
||||
|
||||
consensus.randomXSeedEpochLength = 64;
|
||||
consensus.randomXSeedLag = 8;
|
||||
|
||||
BOOST_CHECK_EQUAL(GetRandomXSeedHeight(63, consensus), 0);
|
||||
BOOST_CHECK_EQUAL(GetRandomXSeedHeight(64, consensus), 56);
|
||||
BOOST_CHECK_EQUAL(GetRandomXSeedHeight(127, consensus), 56);
|
||||
BOOST_CHECK_EQUAL(GetRandomXSeedHeight(128, consensus), 120);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <consensus/validation.h>
|
||||
#include <miner.h>
|
||||
#include <pow.h>
|
||||
#include <primitives/block.h>
|
||||
#include <random.h>
|
||||
#include <script/standard.h>
|
||||
#include <test/util/script.h>
|
||||
|
|
@ -98,7 +99,7 @@ std::shared_ptr<CBlock> MinerTestingSetup::FinalizeBlock(std::shared_ptr<CBlock>
|
|||
|
||||
CBlockHeader header = pblock->GetBlockHeader();
|
||||
auto prevIndex = m_node.chainman->m_blockman.LookupBlockIndex(pblock->hashPrevBlock);
|
||||
pblock->nBits = GetNextWorkRequired(prevIndex, &header, consensus);
|
||||
pblock->nBits = GetNextWorkRequired(prevIndex, &header, consensus, ALGO_SHA256D);
|
||||
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
|
||||
|
||||
while (!CheckProofOfWork(pblock->GetBlockHeader().GetHash(), pblock->nBits, Params().GetConsensus())) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue