refactor: use chainman instead of chainParams for DeploymentActive*

This commit is contained in:
Anthony Towns
2022-04-15 05:50:53 +10:00
parent deffe0df6c
commit 78adef1753
4 changed files with 60 additions and 63 deletions

View File

@@ -1110,7 +1110,6 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
if (state->pindexLastCommonBlock == state->pindexBestKnownBlock) if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
return; return;
const Consensus::Params& consensusParams = m_chainparams.GetConsensus();
std::vector<const CBlockIndex*> vToFetch; std::vector<const CBlockIndex*> vToFetch;
const CBlockIndex *pindexWalk = state->pindexLastCommonBlock; const CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
// Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
@@ -1140,7 +1139,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
// We consider the chain that this peer is on invalid. // We consider the chain that this peer is on invalid.
return; return;
} }
if (!State(nodeid)->fHaveWitness && DeploymentActiveAt(*pindex, consensusParams, Consensus::DEPLOYMENT_SEGWIT)) { if (!State(nodeid)->fHaveWitness && DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) {
// We wouldn't download this block or its descendants from this peer. // We wouldn't download this block or its descendants from this peer.
return; return;
} }
@@ -1641,7 +1640,7 @@ void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::sha
return; return;
m_highest_fast_announce = pindex->nHeight; m_highest_fast_announce = pindex->nHeight;
bool fWitnessEnabled = DeploymentActiveAt(*pindex, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT); bool fWitnessEnabled = DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_SEGWIT);
uint256 hashBlock(pblock->GetHash()); uint256 hashBlock(pblock->GetHash());
const std::shared_future<CSerializedNetMsg> lazy_ser{ const std::shared_future<CSerializedNetMsg> lazy_ser{
std::async(std::launch::deferred, [&] { return msgMaker.Make(NetMsgType::CMPCTBLOCK, *pcmpctblock); })}; std::async(std::launch::deferred, [&] { return msgMaker.Make(NetMsgType::CMPCTBLOCK, *pcmpctblock); })};
@@ -2258,7 +2257,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
while (pindexWalk && !m_chainman.ActiveChain().Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) { while (pindexWalk && !m_chainman.ActiveChain().Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) && if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) &&
!IsBlockRequested(pindexWalk->GetBlockHash()) && !IsBlockRequested(pindexWalk->GetBlockHash()) &&
(!DeploymentActiveAt(*pindexWalk, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT) || State(pfrom.GetId())->fHaveWitness)) { (!DeploymentActiveAt(*pindexWalk, m_chainman, Consensus::DEPLOYMENT_SEGWIT) || State(pfrom.GetId())->fHaveWitness)) {
// We don't have this block, and it's not yet in flight. // We don't have this block, and it's not yet in flight.
vToFetch.push_back(pindexWalk); vToFetch.push_back(pindexWalk);
} }
@@ -3629,7 +3628,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
return; return;
} }
if (DeploymentActiveAt(*pindex, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT) && !nodestate->fSupportsDesiredCmpctVersion) { if (DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_SEGWIT) && !nodestate->fSupportsDesiredCmpctVersion) {
// Don't bother trying to process compact blocks from v1 peers // Don't bother trying to process compact blocks from v1 peers
// after segwit activates. // after segwit activates.
return; return;

View File

@@ -1064,26 +1064,26 @@ static RPCHelpMan verifychain()
}; };
} }
static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softforks, const Consensus::Params& params, Consensus::BuriedDeployment dep) static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softforks, const ChainstateManager& chainman, Consensus::BuriedDeployment dep)
{ {
// For buried deployments. // For buried deployments.
if (!DeploymentEnabled(params, dep)) return; if (!DeploymentEnabled(chainman, dep)) return;
UniValue rv(UniValue::VOBJ); UniValue rv(UniValue::VOBJ);
rv.pushKV("type", "buried"); rv.pushKV("type", "buried");
// getdeploymentinfo reports the softfork as active from when the chain height is // getdeploymentinfo reports the softfork as active from when the chain height is
// one below the activation height // one below the activation height
rv.pushKV("active", DeploymentActiveAfter(blockindex, params, dep)); rv.pushKV("active", DeploymentActiveAfter(blockindex, chainman, dep));
rv.pushKV("height", params.DeploymentHeight(dep)); rv.pushKV("height", chainman.GetConsensus().DeploymentHeight(dep));
softforks.pushKV(DeploymentName(dep), rv); softforks.pushKV(DeploymentName(dep), rv);
} }
static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softforks, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softforks, const ChainstateManager& chainman, Consensus::DeploymentPos id)
{ {
// For BIP9 deployments. // For BIP9 deployments.
if (!DeploymentEnabled(consensusParams, id)) return; if (!DeploymentEnabled(chainman, id)) return;
if (blockindex == nullptr) return; if (blockindex == nullptr) return;
auto get_state_name = [](const ThresholdState state) -> std::string { auto get_state_name = [](const ThresholdState state) -> std::string {
@@ -1099,29 +1099,29 @@ static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softfo
UniValue bip9(UniValue::VOBJ); UniValue bip9(UniValue::VOBJ);
const ThresholdState next_state = g_versionbitscache.State(blockindex, consensusParams, id); const ThresholdState next_state = g_versionbitscache.State(blockindex, chainman.GetConsensus(), id);
const ThresholdState current_state = g_versionbitscache.State(blockindex->pprev, consensusParams, id); const ThresholdState current_state = g_versionbitscache.State(blockindex->pprev, chainman.GetConsensus(), id);
const bool has_signal = (ThresholdState::STARTED == current_state || ThresholdState::LOCKED_IN == current_state); const bool has_signal = (ThresholdState::STARTED == current_state || ThresholdState::LOCKED_IN == current_state);
// BIP9 parameters // BIP9 parameters
if (has_signal) { if (has_signal) {
bip9.pushKV("bit", consensusParams.vDeployments[id].bit); bip9.pushKV("bit", chainman.GetConsensus().vDeployments[id].bit);
} }
bip9.pushKV("start_time", consensusParams.vDeployments[id].nStartTime); bip9.pushKV("start_time", chainman.GetConsensus().vDeployments[id].nStartTime);
bip9.pushKV("timeout", consensusParams.vDeployments[id].nTimeout); bip9.pushKV("timeout", chainman.GetConsensus().vDeployments[id].nTimeout);
bip9.pushKV("min_activation_height", consensusParams.vDeployments[id].min_activation_height); bip9.pushKV("min_activation_height", chainman.GetConsensus().vDeployments[id].min_activation_height);
// BIP9 status // BIP9 status
bip9.pushKV("status", get_state_name(current_state)); bip9.pushKV("status", get_state_name(current_state));
bip9.pushKV("since", g_versionbitscache.StateSinceHeight(blockindex->pprev, consensusParams, id)); bip9.pushKV("since", g_versionbitscache.StateSinceHeight(blockindex->pprev, chainman.GetConsensus(), id));
bip9.pushKV("status_next", get_state_name(next_state)); bip9.pushKV("status_next", get_state_name(next_state));
// BIP9 signalling status, if applicable // BIP9 signalling status, if applicable
if (has_signal) { if (has_signal) {
UniValue statsUV(UniValue::VOBJ); UniValue statsUV(UniValue::VOBJ);
std::vector<bool> signals; std::vector<bool> signals;
BIP9Stats statsStruct = g_versionbitscache.Statistics(blockindex, consensusParams, id, &signals); BIP9Stats statsStruct = g_versionbitscache.Statistics(blockindex, chainman.GetConsensus(), id, &signals);
statsUV.pushKV("period", statsStruct.period); statsUV.pushKV("period", statsStruct.period);
statsUV.pushKV("elapsed", statsStruct.elapsed); statsUV.pushKV("elapsed", statsStruct.elapsed);
statsUV.pushKV("count", statsStruct.count); statsUV.pushKV("count", statsStruct.count);
@@ -1142,7 +1142,7 @@ static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softfo
UniValue rv(UniValue::VOBJ); UniValue rv(UniValue::VOBJ);
rv.pushKV("type", "bip9"); rv.pushKV("type", "bip9");
if (ThresholdState::ACTIVE == next_state) { if (ThresholdState::ACTIVE == next_state) {
rv.pushKV("height", g_versionbitscache.StateSinceHeight(blockindex, consensusParams, id)); rv.pushKV("height", g_versionbitscache.StateSinceHeight(blockindex, chainman.GetConsensus(), id));
} }
rv.pushKV("active", ThresholdState::ACTIVE == next_state); rv.pushKV("active", ThresholdState::ACTIVE == next_state);
rv.pushKV("bip9", bip9); rv.pushKV("bip9", bip9);
@@ -1152,7 +1152,7 @@ static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softfo
namespace { namespace {
/* TODO: when -deprecatedrpc=softforks is removed, drop these */ /* TODO: when -deprecatedrpc=softforks is removed, drop these */
UniValue DeploymentInfo(const CBlockIndex* tip, const Consensus::Params& consensusParams); UniValue DeploymentInfo(const CBlockIndex* tip, const ChainstateManager& chainman);
extern const std::vector<RPCResult> RPCHelpForDeployment; extern const std::vector<RPCResult> RPCHelpForDeployment;
} }
@@ -1227,8 +1227,7 @@ RPCHelpMan getblockchaininfo()
} }
if (IsDeprecatedRPCEnabled("softforks")) { if (IsDeprecatedRPCEnabled("softforks")) {
const Consensus::Params& consensusParams = Params().GetConsensus(); obj.pushKV("softforks", DeploymentInfo(&tip, chainman));
obj.pushKV("softforks", DeploymentInfo(&tip, consensusParams));
} }
obj.pushKV("warnings", GetWarnings(false).original); obj.pushKV("warnings", GetWarnings(false).original);
@@ -1263,16 +1262,16 @@ const std::vector<RPCResult> RPCHelpForDeployment{
}}, }},
}; };
UniValue DeploymentInfo(const CBlockIndex* blockindex, const Consensus::Params& consensusParams) UniValue DeploymentInfo(const CBlockIndex* blockindex, const ChainstateManager& chainman)
{ {
UniValue softforks(UniValue::VOBJ); UniValue softforks(UniValue::VOBJ);
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB); SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_HEIGHTINCB);
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_DERSIG); SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_DERSIG);
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_CLTV); SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_CLTV);
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_CSV); SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_CSV);
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_SEGWIT); SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_SEGWIT);
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_TESTDUMMY); SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_TESTDUMMY);
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_TAPROOT); SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_TAPROOT);
return softforks; return softforks;
} }
} // anon namespace } // anon namespace
@@ -1311,12 +1310,10 @@ static RPCHelpMan getdeploymentinfo()
} }
} }
const Consensus::Params& consensusParams = Params().GetConsensus();
UniValue deploymentinfo(UniValue::VOBJ); UniValue deploymentinfo(UniValue::VOBJ);
deploymentinfo.pushKV("hash", blockindex->GetBlockHash().ToString()); deploymentinfo.pushKV("hash", blockindex->GetBlockHash().ToString());
deploymentinfo.pushKV("height", blockindex->nHeight); deploymentinfo.pushKV("height", blockindex->nHeight);
deploymentinfo.pushKV("deployments", DeploymentInfo(blockindex, consensusParams)); deploymentinfo.pushKV("deployments", DeploymentInfo(blockindex, chainman));
return deploymentinfo; return deploymentinfo;
}, },
}; };

View File

@@ -770,7 +770,7 @@ static RPCHelpMan getblocktemplate()
pblock->nNonce = 0; pblock->nNonce = 0;
// NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration // NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration
const bool fPreSegWit = !DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT); const bool fPreSegWit = !DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_SEGWIT);
UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal"); UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");

View File

@@ -261,7 +261,7 @@ bool CheckSequenceLocksAtTip(CBlockIndex* tip,
} }
// Returns the script flags which should be checked for a given block // Returns the script flags which should be checked for a given block
static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Consensus::Params& chainparams); static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const ChainstateManager& chainman);
static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, size_t limit, std::chrono::seconds age) static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, size_t limit, std::chrono::seconds age)
EXCLUSIVE_LOCKS_REQUIRED(::cs_main, pool.cs) EXCLUSIVE_LOCKS_REQUIRED(::cs_main, pool.cs)
@@ -1026,7 +1026,6 @@ bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws)
const CTransaction& tx = *ws.m_ptx; const CTransaction& tx = *ws.m_ptx;
const uint256& hash = ws.m_hash; const uint256& hash = ws.m_hash;
TxValidationState& state = ws.m_state; TxValidationState& state = ws.m_state;
const CChainParams& chainparams = args.m_chainparams;
// Check again against the current block tip's script verification // Check again against the current block tip's script verification
// flags to cache our script execution flags. This is, of course, // flags to cache our script execution flags. This is, of course,
@@ -1043,7 +1042,7 @@ bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws)
// There is a similar check in CreateNewBlock() to prevent creating // There is a similar check in CreateNewBlock() to prevent creating
// invalid blocks (using TestBlockValidity), however allowing such // invalid blocks (using TestBlockValidity), however allowing such
// transactions into the mempool can be exploited as a DoS attack. // transactions into the mempool can be exploited as a DoS attack.
unsigned int currentBlockScriptVerifyFlags{GetBlockScriptFlags(*m_active_chainstate.m_chain.Tip(), chainparams.GetConsensus())}; unsigned int currentBlockScriptVerifyFlags{GetBlockScriptFlags(*m_active_chainstate.m_chain.Tip(), m_active_chainstate.m_chainman)};
if (!CheckInputsFromMempoolAndCache(tx, state, m_view, m_pool, currentBlockScriptVerifyFlags, if (!CheckInputsFromMempoolAndCache(tx, state, m_view, m_pool, currentBlockScriptVerifyFlags,
ws.m_precomputed_txdata, m_active_chainstate.CoinsTip())) { ws.m_precomputed_txdata, m_active_chainstate.CoinsTip())) {
LogPrintf("BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s\n", hash.ToString(), state.ToString()); LogPrintf("BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s\n", hash.ToString(), state.ToString());
@@ -1929,8 +1928,10 @@ public:
static std::array<ThresholdConditionCache, VERSIONBITS_NUM_BITS> warningcache GUARDED_BY(cs_main); static std::array<ThresholdConditionCache, VERSIONBITS_NUM_BITS> warningcache GUARDED_BY(cs_main);
static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Consensus::Params& consensusparams) static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const ChainstateManager& chainman)
{ {
const Consensus::Params& consensusparams = chainman.GetConsensus();
// BIP16 didn't become active until Apr 1 2012 (on mainnet, and // BIP16 didn't become active until Apr 1 2012 (on mainnet, and
// retroactively applied to testnet) // retroactively applied to testnet)
// However, only one historical block violated the P2SH rules (on both // However, only one historical block violated the P2SH rules (on both
@@ -1946,22 +1947,22 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Co
} }
// Enforce the DERSIG (BIP66) rule // Enforce the DERSIG (BIP66) rule
if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_DERSIG)) { if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_DERSIG)) {
flags |= SCRIPT_VERIFY_DERSIG; flags |= SCRIPT_VERIFY_DERSIG;
} }
// Enforce CHECKLOCKTIMEVERIFY (BIP65) // Enforce CHECKLOCKTIMEVERIFY (BIP65)
if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_CLTV)) { if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_CLTV)) {
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
} }
// Enforce CHECKSEQUENCEVERIFY (BIP112) // Enforce CHECKSEQUENCEVERIFY (BIP112)
if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_CSV)) { if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_CSV)) {
flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
} }
// Enforce BIP147 NULLDUMMY (activated simultaneously with segwit) // Enforce BIP147 NULLDUMMY (activated simultaneously with segwit)
if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_SEGWIT)) { if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_SEGWIT)) {
flags |= SCRIPT_VERIFY_NULLDUMMY; flags |= SCRIPT_VERIFY_NULLDUMMY;
} }
@@ -2152,12 +2153,12 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// Enforce BIP68 (sequence locks) // Enforce BIP68 (sequence locks)
int nLockTimeFlags = 0; int nLockTimeFlags = 0;
if (DeploymentActiveAt(*pindex, m_params.GetConsensus(), Consensus::DEPLOYMENT_CSV)) { if (DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_CSV)) {
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE; nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
} }
// Get the script flags for this block // Get the script flags for this block
unsigned int flags{GetBlockScriptFlags(*pindex, m_params.GetConsensus())}; unsigned int flags{GetBlockScriptFlags(*pindex, m_chainman)};
int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1; int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
LogPrint(BCLog::BENCH, " - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks * MILLI / nBlocksTotal); LogPrint(BCLog::BENCH, " - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks * MILLI / nBlocksTotal);
@@ -3279,7 +3280,7 @@ void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pi
pindexNew->nDataPos = pos.nPos; pindexNew->nDataPos = pos.nPos;
pindexNew->nUndoPos = 0; pindexNew->nUndoPos = 0;
pindexNew->nStatus |= BLOCK_HAVE_DATA; pindexNew->nStatus |= BLOCK_HAVE_DATA;
if (DeploymentActiveAt(*pindexNew, m_params.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) { if (DeploymentActiveAt(*pindexNew, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) {
pindexNew->nStatus |= BLOCK_OPT_WITNESS; pindexNew->nStatus |= BLOCK_OPT_WITNESS;
} }
pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS); pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
@@ -3401,7 +3402,7 @@ void ChainstateManager::UpdateUncommittedBlockStructures(CBlock& block, const CB
{ {
int commitpos = GetWitnessCommitmentIndex(block); int commitpos = GetWitnessCommitmentIndex(block);
static const std::vector<unsigned char> nonce(32, 0x00); static const std::vector<unsigned char> nonce(32, 0x00);
if (commitpos != NO_WITNESS_COMMITMENT && DeploymentActiveAfter(pindexPrev, GetConsensus(), Consensus::DEPLOYMENT_SEGWIT) && !block.vtx[0]->HasWitness()) { if (commitpos != NO_WITNESS_COMMITMENT && DeploymentActiveAfter(pindexPrev, *this, Consensus::DEPLOYMENT_SEGWIT) && !block.vtx[0]->HasWitness()) {
CMutableTransaction tx(*block.vtx[0]); CMutableTransaction tx(*block.vtx[0]);
tx.vin[0].scriptWitness.stack.resize(1); tx.vin[0].scriptWitness.stack.resize(1);
tx.vin[0].scriptWitness.stack[0] = nonce; tx.vin[0].scriptWitness.stack[0] = nonce;
@@ -3445,14 +3446,14 @@ std::vector<unsigned char> ChainstateManager::GenerateCoinbaseCommitment(CBlock&
* in ConnectBlock(). * in ConnectBlock().
* Note that -reindex-chainstate skips the validation that happens here! * 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 ChainstateManager& chainman, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
{ {
AssertLockHeld(::cs_main); AssertLockHeld(::cs_main);
assert(pindexPrev != nullptr); assert(pindexPrev != nullptr);
const int nHeight = pindexPrev->nHeight + 1; const int nHeight = pindexPrev->nHeight + 1;
// Check proof of work // Check proof of work
const Consensus::Params& consensusParams = params.GetConsensus(); const Consensus::Params& consensusParams = chainman.GetConsensus();
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-diffbits", "incorrect proof of work"); return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-diffbits", "incorrect proof of work");
@@ -3461,7 +3462,7 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
// Don't accept any forks from the main chain prior to last checkpoint. // Don't accept any forks from the main chain prior to last checkpoint.
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our // GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
// BlockIndex(). // BlockIndex().
const CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(params.Checkpoints()); const CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(chainman.GetParams().Checkpoints());
if (pcheckpoint && nHeight < pcheckpoint->nHeight) { if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
LogPrintf("ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__, nHeight); LogPrintf("ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__, nHeight);
return state.Invalid(BlockValidationResult::BLOCK_CHECKPOINT, "bad-fork-prior-to-checkpoint"); return state.Invalid(BlockValidationResult::BLOCK_CHECKPOINT, "bad-fork-prior-to-checkpoint");
@@ -3477,9 +3478,9 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", "block timestamp too far in the future"); return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", "block timestamp too far in the future");
// Reject blocks with outdated version // Reject blocks with outdated version
if ((block.nVersion < 2 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB)) || if ((block.nVersion < 2 && DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_HEIGHTINCB)) ||
(block.nVersion < 3 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_DERSIG)) || (block.nVersion < 3 && DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_DERSIG)) ||
(block.nVersion < 4 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CLTV))) { (block.nVersion < 4 && DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_CLTV))) {
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, strprintf("bad-version(0x%08x)", block.nVersion), return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, strprintf("bad-version(0x%08x)", block.nVersion),
strprintf("rejected nVersion=0x%08x block", block.nVersion)); strprintf("rejected nVersion=0x%08x block", block.nVersion));
} }
@@ -3493,13 +3494,13 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
* in ConnectBlock(). * in ConnectBlock().
* Note that -reindex-chainstate skips the validation that happens here! * Note that -reindex-chainstate skips the validation that happens here!
*/ */
static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& state, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev) static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& state, const ChainstateManager& chainman, const CBlockIndex* pindexPrev)
{ {
const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1; const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
// Enforce BIP113 (Median Time Past). // Enforce BIP113 (Median Time Past).
int nLockTimeFlags = 0; int nLockTimeFlags = 0;
if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CSV)) { if (DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_CSV)) {
assert(pindexPrev != nullptr); assert(pindexPrev != nullptr);
nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST; nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST;
} }
@@ -3516,7 +3517,7 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
} }
// Enforce rule that the coinbase starts with serialized block height // Enforce rule that the coinbase starts with serialized block height
if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB)) if (DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_HEIGHTINCB))
{ {
CScript expect = CScript() << nHeight; CScript expect = CScript() << nHeight;
if (block.vtx[0]->vin[0].scriptSig.size() < expect.size() || if (block.vtx[0]->vin[0].scriptSig.size() < expect.size() ||
@@ -3534,7 +3535,7 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
// {0xaa, 0x21, 0xa9, 0xed}, and the following 32 bytes are SHA256^2(witness root, witness reserved value). In case there are // {0xaa, 0x21, 0xa9, 0xed}, and the following 32 bytes are SHA256^2(witness root, witness reserved value). In case there are
// multiple, the last one is used. // multiple, the last one is used.
bool fHaveWitness = false; bool fHaveWitness = false;
if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT)) { if (DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_SEGWIT)) {
int commitpos = GetWitnessCommitmentIndex(block); int commitpos = GetWitnessCommitmentIndex(block);
if (commitpos != NO_WITNESS_COMMITMENT) { if (commitpos != NO_WITNESS_COMMITMENT) {
bool malleated = false; bool malleated = false;
@@ -3611,7 +3612,7 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida
LogPrint(BCLog::VALIDATION, "%s: %s prev block invalid\n", __func__, hash.ToString()); LogPrint(BCLog::VALIDATION, "%s: %s prev block invalid\n", __func__, hash.ToString());
return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk"); return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk");
} }
if (!ContextualCheckBlockHeader(block, state, m_blockman, GetParams(), pindexPrev, GetAdjustedTime())) { if (!ContextualCheckBlockHeader(block, state, m_blockman, *this, pindexPrev, GetAdjustedTime())) {
LogPrint(BCLog::VALIDATION, "%s: Consensus::ContextualCheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString()); LogPrint(BCLog::VALIDATION, "%s: Consensus::ContextualCheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());
return false; return false;
} }
@@ -3744,7 +3745,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
} }
if (!CheckBlock(block, state, m_params.GetConsensus()) || if (!CheckBlock(block, state, m_params.GetConsensus()) ||
!ContextualCheckBlock(block, state, m_params.GetConsensus(), pindex->pprev)) { !ContextualCheckBlock(block, state, m_chainman, pindex->pprev)) {
if (state.IsInvalid() && state.GetResult() != BlockValidationResult::BLOCK_MUTATED) { if (state.IsInvalid() && state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
pindex->nStatus |= BLOCK_FAILED_VALID; pindex->nStatus |= BLOCK_FAILED_VALID;
m_blockman.m_dirty_blockindex.insert(pindex); m_blockman.m_dirty_blockindex.insert(pindex);
@@ -3848,11 +3849,11 @@ bool TestBlockValidity(BlockValidationState& state,
indexDummy.phashBlock = &block_hash; indexDummy.phashBlock = &block_hash;
// NOTE: CheckBlockHeader is called by CheckBlock // NOTE: CheckBlockHeader is called by CheckBlock
if (!ContextualCheckBlockHeader(block, state, chainstate.m_blockman, chainparams, pindexPrev, GetAdjustedTime())) if (!ContextualCheckBlockHeader(block, state, chainstate.m_blockman, chainstate.m_chainman, pindexPrev, GetAdjustedTime()))
return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.ToString()); return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.ToString());
if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot)) if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot))
return error("%s: Consensus::CheckBlock: %s", __func__, state.ToString()); return error("%s: Consensus::CheckBlock: %s", __func__, state.ToString());
if (!ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindexPrev)) if (!ContextualCheckBlock(block, state, chainstate.m_chainman, pindexPrev))
return error("%s: Consensus::ContextualCheckBlock: %s", __func__, state.ToString()); return error("%s: Consensus::ContextualCheckBlock: %s", __func__, state.ToString());
if (!chainstate.ConnectBlock(block, state, &indexDummy, viewNew, true)) { if (!chainstate.ConnectBlock(block, state, &indexDummy, viewNew, true)) {
return false; return false;
@@ -4132,7 +4133,7 @@ bool CChainState::NeedsRedownload() const
// At and above m_params.SegwitHeight, segwit consensus rules must be validated // At and above m_params.SegwitHeight, segwit consensus rules must be validated
CBlockIndex* block{m_chain.Tip()}; CBlockIndex* block{m_chain.Tip()};
while (block != nullptr && DeploymentActiveAt(*block, m_params.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) { while (block != nullptr && DeploymentActiveAt(*block, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) {
if (!(block->nStatus & BLOCK_OPT_WITNESS)) { if (!(block->nStatus & BLOCK_OPT_WITNESS)) {
// block is insufficiently validated for a segwit client // block is insufficiently validated for a segwit client
return true; return true;
@@ -5146,7 +5147,7 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
// Fake BLOCK_OPT_WITNESS so that CChainState::NeedsRedownload() // Fake BLOCK_OPT_WITNESS so that CChainState::NeedsRedownload()
// won't ask to rewind the entire assumed-valid chain on startup. // won't ask to rewind the entire assumed-valid chain on startup.
if (DeploymentActiveAt(*index, GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) { if (DeploymentActiveAt(*index, *this, Consensus::DEPLOYMENT_SEGWIT)) {
index->nStatus |= BLOCK_OPT_WITNESS; index->nStatus |= BLOCK_OPT_WITNESS;
} }