Make RandomX block templates activation-aware
This commit is contained in:
parent
3b26ac9397
commit
00158bc780
7 changed files with 104 additions and 12 deletions
|
|
@ -592,6 +592,8 @@ static void MaybeUpdateHeights(const ArgsManager& args, Consensus::Params& conse
|
|||
consensus.BIP65Height = int{height};
|
||||
} else if (name == "csv") {
|
||||
consensus.CSVHeight = int{height};
|
||||
} else if (name == "randomx") {
|
||||
consensus.randomXActivationHeight = int{height};
|
||||
} else {
|
||||
throw std::runtime_error(strprintf("Invalid name (%s) for -testactivationheight=name@height.", arg));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
|
||||
int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev, int algo)
|
||||
{
|
||||
int64_t nOldTime = pblock->nTime;
|
||||
int64_t nNewTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
|
||||
|
|
@ -36,7 +36,7 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam
|
|||
|
||||
// Updating time can change work required on testnet:
|
||||
if (consensusParams.fPowAllowMinDifficultyBlocks)
|
||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams, ALGO_SHA256D);
|
||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams, algo);
|
||||
|
||||
return nNewTime - nOldTime;
|
||||
}
|
||||
|
|
@ -172,7 +172,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
|||
// Fill in header
|
||||
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
|
||||
pblock->SetAlgo(algo);
|
||||
UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
|
||||
UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev, algo);
|
||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus(), algo);
|
||||
pblock->nNonce = 0;
|
||||
pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(*pblock->vtx[0]);
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ void RegenerateCommitments(CBlock& block, const CBlockIndex* pindexPrev, const C
|
|||
|
||||
/** Modify the extranonce in a block */
|
||||
void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
|
||||
int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
|
||||
int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev, int algo);
|
||||
|
||||
/** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */
|
||||
void RegenerateCommitments(CBlock& block, ChainstateManager& chainman);
|
||||
|
|
|
|||
|
|
@ -639,7 +639,12 @@ static RPCHelpMan getblocktemplate()
|
|||
if (strAlgo == "sha256d") {
|
||||
algo = ALGO_SHA256D;
|
||||
} else if (strAlgo == "randomx") {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "RandomX is not active yet");
|
||||
const CBlockIndex* tip = chainman.ActiveChain().Tip();
|
||||
if (tip == nullptr ||
|
||||
tip->nHeight + 1 < Params().GetConsensus().randomXActivationHeight) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "RandomX is not active yet");
|
||||
}
|
||||
algo = ALGO_RANDOMX;
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unknown proof-of-work algorithm");
|
||||
}
|
||||
|
|
@ -809,7 +814,7 @@ static RPCHelpMan getblocktemplate()
|
|||
CBlock* pblock = &pblocktemplate->block; // pointer for convenience
|
||||
|
||||
// Update nTime
|
||||
UpdateTime(pblock, consensusParams, pindexPrev);
|
||||
UpdateTime(pblock, consensusParams, pindexPrev, algo);
|
||||
pblock->nNonce = 0;
|
||||
|
||||
// NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration
|
||||
|
|
|
|||
|
|
@ -1751,7 +1751,8 @@ static bool CheckContextualRandomXProofOfWork(
|
|||
const CBlockHeader& block,
|
||||
BlockValidationState& state,
|
||||
const Consensus::Params& consensusParams,
|
||||
const CBlockIndex* pindexPrev);
|
||||
const CBlockIndex* pindexPrev,
|
||||
bool fCheckPOW);
|
||||
|
||||
/** Apply the effects of this block (with given index) on the UTXO set represented by coins.
|
||||
* Validity checks that depend on the UTXO set are also done; ConnectBlock()
|
||||
|
|
@ -1793,7 +1794,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
|||
if (!fJustCheck &&
|
||||
block.GetHash() != m_params.GetConsensus().hashGenesisBlock &&
|
||||
block.GetAlgo() == ALGO_RANDOMX &&
|
||||
!CheckContextualRandomXProofOfWork(block, state, m_params.GetConsensus(), pindex->pprev)) {
|
||||
!CheckContextualRandomXProofOfWork(block, state, m_params.GetConsensus(), pindex->pprev, true)) {
|
||||
return error("%s: contextual RandomX proof of work check failed: %s", __func__, state.ToString());
|
||||
}
|
||||
|
||||
|
|
@ -3160,7 +3161,8 @@ static bool CheckContextualRandomXProofOfWork(
|
|||
const CBlockHeader& block,
|
||||
BlockValidationState& state,
|
||||
const Consensus::Params& consensusParams,
|
||||
const CBlockIndex* pindexPrev)
|
||||
const CBlockIndex* pindexPrev,
|
||||
bool fCheckPOW)
|
||||
{
|
||||
assert(pindexPrev != nullptr);
|
||||
assert(block.GetAlgo() == ALGO_RANDOMX);
|
||||
|
|
@ -3185,6 +3187,9 @@ static bool CheckContextualRandomXProofOfWork(
|
|||
"incorrect RandomX proof of work difficulty");
|
||||
}
|
||||
|
||||
if (!fCheckPOW)
|
||||
return true;
|
||||
|
||||
return CheckRandomXProofOfWork(
|
||||
block,
|
||||
state,
|
||||
|
|
@ -3197,6 +3202,16 @@ static bool CheckBlockHeader(const CBlockHeader& block, BlockValidationState& st
|
|||
if (!fCheckPOW)
|
||||
return true;
|
||||
|
||||
// Genesis predates the multi-algo version-bit encoding. Preserve its
|
||||
// historical SHA256D proof-of-work validation without treating unknown
|
||||
// algorithm version bits as valid for any other block.
|
||||
if (block.GetHash() == consensusParams.hashGenesisBlock) {
|
||||
if (!CheckProofOfWork(block.GetHash(), block.nBits, consensusParams))
|
||||
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "high-hash", "proof of work failed");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const int algo = block.GetAlgo();
|
||||
|
||||
// SHA256D proof of work is context-free.
|
||||
|
|
@ -3357,7 +3372,7 @@ CBlockIndex* BlockManager::GetLastCheckpoint(const CCheckpointData& data)
|
|||
* in ConnectBlock().
|
||||
* Note that -reindex-chainstate skips the validation that happens here!
|
||||
*/
|
||||
static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, BlockManager& blockman, const CChainParams& params, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, BlockManager& blockman, const CChainParams& params, const CBlockIndex* pindexPrev, int64_t nAdjustedTime, bool fCheckPOW = true) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
{
|
||||
assert(pindexPrev != nullptr);
|
||||
const int nHeight = pindexPrev->nHeight + 1;
|
||||
|
|
@ -3367,7 +3382,7 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
|
|||
const int algo = block.GetAlgo();
|
||||
|
||||
if (algo == ALGO_RANDOMX) {
|
||||
if (!CheckContextualRandomXProofOfWork(block, state, consensusParams, pindexPrev))
|
||||
if (!CheckContextualRandomXProofOfWork(block, state, consensusParams, pindexPrev, fCheckPOW))
|
||||
return false;
|
||||
} else if (algo == ALGO_SHA256D) {
|
||||
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams, ALGO_SHA256D))
|
||||
|
|
@ -3751,7 +3766,7 @@ bool TestBlockValidity(BlockValidationState& state,
|
|||
indexDummy.phashBlock = &block_hash;
|
||||
|
||||
// NOTE: CheckBlockHeader is called by CheckBlock
|
||||
if (!ContextualCheckBlockHeader(block, state, chainstate.m_blockman, chainparams, pindexPrev, GetAdjustedTime()))
|
||||
if (!ContextualCheckBlockHeader(block, state, chainstate.m_blockman, chainparams, pindexPrev, GetAdjustedTime(), fCheckPOW))
|
||||
return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.ToString());
|
||||
if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot))
|
||||
return error("%s: Consensus::CheckBlock: %s", __func__, state.ToString());
|
||||
|
|
|
|||
Loading…
Reference in a new issue