mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-05-06 11:58:31 +02:00
[refactor] Add deploymentstatus.h
Provides DeploymentEnabled, DeploymentActiveAt, and DeploymentActiveAfter helpers for checking the status of buried deployments. Can be overloaded so the same syntax works for non-buried deployments, allowing future soft forks to be changed from signalled to buried deployments without having to touch the implementation code. Replaces IsWitnessEnabled and IsScriptWitnessEnabled.
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include <consensus/tx_verify.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <cuckoocache.h>
|
||||
#include <deploymentstatus.h>
|
||||
#include <flatfile.h>
|
||||
#include <hash.h>
|
||||
#include <index/blockfilterindex.h>
|
||||
@@ -1649,15 +1650,6 @@ public:
|
||||
|
||||
static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS] GUARDED_BY(cs_main);
|
||||
|
||||
// 0.13.0 was shipped with a segwit deployment defined for testnet, but not for
|
||||
// mainnet. We no longer need to support disabling the segwit deployment
|
||||
// except for testing purposes, due to limitations of the functional test
|
||||
// environment. See test/functional/p2p-segwit.py.
|
||||
static bool IsScriptWitnessEnabled(const Consensus::Params& params)
|
||||
{
|
||||
return params.SegwitHeight != std::numeric_limits<int>::max();
|
||||
}
|
||||
|
||||
static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& consensusparams)
|
||||
{
|
||||
unsigned int flags = SCRIPT_VERIFY_NONE;
|
||||
@@ -1676,22 +1668,22 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consens
|
||||
|
||||
// Enforce WITNESS rules whenever P2SH is in effect (and the segwit
|
||||
// deployment is defined).
|
||||
if (flags & SCRIPT_VERIFY_P2SH && IsScriptWitnessEnabled(consensusparams)) {
|
||||
if (flags & SCRIPT_VERIFY_P2SH && DeploymentEnabled(consensusparams, Consensus::DEPLOYMENT_SEGWIT)) {
|
||||
flags |= SCRIPT_VERIFY_WITNESS;
|
||||
}
|
||||
|
||||
// Start enforcing the DERSIG (BIP66) rule
|
||||
if (pindex->nHeight >= consensusparams.BIP66Height) {
|
||||
// Enforce the DERSIG (BIP66) rule
|
||||
if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_DERSIG)) {
|
||||
flags |= SCRIPT_VERIFY_DERSIG;
|
||||
}
|
||||
|
||||
// Start enforcing CHECKLOCKTIMEVERIFY (BIP65) rule
|
||||
if (pindex->nHeight >= consensusparams.BIP65Height) {
|
||||
// Enforce CHECKLOCKTIMEVERIFY (BIP65)
|
||||
if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_CLTV)) {
|
||||
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
|
||||
}
|
||||
|
||||
// Start enforcing BIP112 (CHECKSEQUENCEVERIFY)
|
||||
if (pindex->nHeight >= consensusparams.CSVHeight) {
|
||||
// Enforce CHECKSEQUENCEVERIFY (BIP112)
|
||||
if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_CSV)) {
|
||||
flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
|
||||
}
|
||||
|
||||
@@ -1700,8 +1692,8 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consens
|
||||
flags |= SCRIPT_VERIFY_TAPROOT;
|
||||
}
|
||||
|
||||
// Start enforcing BIP147 NULLDUMMY (activated simultaneously with segwit)
|
||||
if (IsWitnessEnabled(pindex->pprev, consensusparams)) {
|
||||
// Enforce BIP147 NULLDUMMY (activated simultaneously with segwit)
|
||||
if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_SEGWIT)) {
|
||||
flags |= SCRIPT_VERIFY_NULLDUMMY;
|
||||
}
|
||||
|
||||
@@ -1891,9 +1883,9 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
||||
}
|
||||
}
|
||||
|
||||
// Start enforcing BIP68 (sequence locks)
|
||||
// Enforce BIP68 (sequence locks)
|
||||
int nLockTimeFlags = 0;
|
||||
if (pindex->nHeight >= m_params.GetConsensus().CSVHeight) {
|
||||
if (DeploymentActiveAt(*pindex, m_params.GetConsensus(), Consensus::DEPLOYMENT_CSV)) {
|
||||
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
|
||||
}
|
||||
|
||||
@@ -2986,7 +2978,7 @@ void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pi
|
||||
pindexNew->nDataPos = pos.nPos;
|
||||
pindexNew->nUndoPos = 0;
|
||||
pindexNew->nStatus |= BLOCK_HAVE_DATA;
|
||||
if (IsWitnessEnabled(pindexNew->pprev, m_params.GetConsensus())) {
|
||||
if (DeploymentActiveAt(*pindexNew, m_params.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
|
||||
pindexNew->nStatus |= BLOCK_OPT_WITNESS;
|
||||
}
|
||||
pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
|
||||
@@ -3107,17 +3099,11 @@ bool CheckBlock(const CBlock& block, BlockValidationState& state, const Consensu
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params)
|
||||
{
|
||||
int height = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
|
||||
return (height >= params.SegwitHeight);
|
||||
}
|
||||
|
||||
void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams)
|
||||
{
|
||||
int commitpos = GetWitnessCommitmentIndex(block);
|
||||
static const std::vector<unsigned char> nonce(32, 0x00);
|
||||
if (commitpos != NO_WITNESS_COMMITMENT && IsWitnessEnabled(pindexPrev, consensusParams) && !block.vtx[0]->HasWitness()) {
|
||||
if (commitpos != NO_WITNESS_COMMITMENT && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT) && !block.vtx[0]->HasWitness()) {
|
||||
CMutableTransaction tx(*block.vtx[0]);
|
||||
tx.vin[0].scriptWitness.stack.resize(1);
|
||||
tx.vin[0].scriptWitness.stack[0] = nonce;
|
||||
@@ -3130,7 +3116,7 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
|
||||
std::vector<unsigned char> commitment;
|
||||
int commitpos = GetWitnessCommitmentIndex(block);
|
||||
std::vector<unsigned char> ret(32, 0x00);
|
||||
if (consensusParams.SegwitHeight != std::numeric_limits<int>::max()) {
|
||||
if (DeploymentEnabled(consensusParams, Consensus::DEPLOYMENT_SEGWIT)) {
|
||||
if (commitpos == NO_WITNESS_COMMITMENT) {
|
||||
uint256 witnessroot = BlockWitnessMerkleRoot(block, nullptr);
|
||||
CHash256().Write(witnessroot).Write(ret).Finalize(witnessroot);
|
||||
@@ -3208,13 +3194,13 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
|
||||
if (block.GetBlockTime() > nAdjustedTime + MAX_FUTURE_BLOCK_TIME)
|
||||
return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", "block timestamp too far in the future");
|
||||
|
||||
// Reject outdated version blocks when 95% (75% on testnet) of the network has upgraded:
|
||||
// check for version 2, 3 and 4 upgrades
|
||||
if((block.nVersion < 2 && nHeight >= consensusParams.BIP34Height) ||
|
||||
(block.nVersion < 3 && nHeight >= consensusParams.BIP66Height) ||
|
||||
(block.nVersion < 4 && nHeight >= consensusParams.BIP65Height))
|
||||
// Reject blocks with outdated version
|
||||
if ((block.nVersion < 2 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB)) ||
|
||||
(block.nVersion < 3 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_DERSIG)) ||
|
||||
(block.nVersion < 4 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CLTV))) {
|
||||
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, strprintf("bad-version(0x%08x)", block.nVersion),
|
||||
strprintf("rejected nVersion=0x%08x block", block.nVersion));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -3229,9 +3215,9 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
|
||||
{
|
||||
const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
|
||||
|
||||
// Start enforcing BIP113 (Median Time Past).
|
||||
// Enforce BIP113 (Median Time Past).
|
||||
int nLockTimeFlags = 0;
|
||||
if (nHeight >= consensusParams.CSVHeight) {
|
||||
if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CSV)) {
|
||||
assert(pindexPrev != nullptr);
|
||||
nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST;
|
||||
}
|
||||
@@ -3248,7 +3234,7 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
|
||||
}
|
||||
|
||||
// Enforce rule that the coinbase starts with serialized block height
|
||||
if (nHeight >= consensusParams.BIP34Height)
|
||||
if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB))
|
||||
{
|
||||
CScript expect = CScript() << nHeight;
|
||||
if (block.vtx[0]->vin[0].scriptSig.size() < expect.size() ||
|
||||
@@ -3266,7 +3252,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
|
||||
// multiple, the last one is used.
|
||||
bool fHaveWitness = false;
|
||||
if (nHeight >= consensusParams.SegwitHeight) {
|
||||
if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT)) {
|
||||
int commitpos = GetWitnessCommitmentIndex(block);
|
||||
if (commitpos != NO_WITNESS_COMMITMENT) {
|
||||
bool malleated = false;
|
||||
@@ -4096,9 +4082,8 @@ bool CChainState::NeedsRedownload() const
|
||||
|
||||
// At and above m_params.SegwitHeight, segwit consensus rules must be validated
|
||||
CBlockIndex* block{m_chain.Tip()};
|
||||
const int segwit_height{m_params.GetConsensus().SegwitHeight};
|
||||
|
||||
while (block != nullptr && block->nHeight >= segwit_height) {
|
||||
while (block != nullptr && DeploymentActiveAt(*block, m_params.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
|
||||
if (!(block->nStatus & BLOCK_OPT_WITNESS)) {
|
||||
// block is insufficiently validated for a segwit client
|
||||
return true;
|
||||
@@ -5000,7 +4985,7 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
|
||||
|
||||
// Fake BLOCK_OPT_WITNESS so that CChainState::NeedsRedownload()
|
||||
// won't ask to rewind the entire assumed-valid chain on startup.
|
||||
if (index->pprev && ::IsWitnessEnabled(index->pprev, ::Params().GetConsensus())) {
|
||||
if (index->pprev && DeploymentActiveAt(*index, ::Params().GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
|
||||
index->nStatus |= BLOCK_OPT_WITNESS;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user