mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-16 13:01:19 +02:00
Merge ddc6979b8b into merged_master (Bitcoin PR bitcoin/bitcoin#19438)
This commit is contained in:
commit
47164a1e9c
20 changed files with 324 additions and 202 deletions
|
|
@ -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>
|
||||
|
|
@ -747,9 +748,8 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
}
|
||||
|
||||
// Check for non-standard pay-to-script-hash in inputs
|
||||
const auto& params = args.m_chainparams.GetConsensus();
|
||||
auto taproot_state = VersionBitsState(m_active_chainstate.m_chain.Tip(), params, Consensus::DEPLOYMENT_TAPROOT, versionbitscache);
|
||||
if (fRequireStandard && !AreInputsStandard(tx, m_view, taproot_state == ThresholdState::ACTIVE)) {
|
||||
const bool taproot_active = DeploymentActiveAfter(m_active_chainstate.m_chain.Tip(), args.m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_TAPROOT);
|
||||
if (fRequireStandard && !AreInputsStandard(tx, m_view, taproot_active)) {
|
||||
return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs");
|
||||
}
|
||||
|
||||
|
|
@ -995,7 +995,7 @@ bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws, Prec
|
|||
// Temporarily add additional script flags based on the activation of
|
||||
// Dynamic Federations. This can be included in the
|
||||
// STANDARD_LOCKTIME_VERIFY_FLAGS in a release post-activation.
|
||||
if (IsDynaFedEnabled(m_active_chainstate.m_chain.Tip(), args.m_chainparams.GetConsensus())) {
|
||||
if (DeploymentActiveAfter(m_active_chainstate.m_chain.Tip(), args.m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_DYNA_FED)) {
|
||||
scriptVerifyFlags |= SCRIPT_SIGHASH_RANGEPROOF;
|
||||
}
|
||||
|
||||
|
|
@ -1731,32 +1731,6 @@ void StopScriptCheckWorkerThreads()
|
|||
scriptcheckqueue.StopWorkerThreads();
|
||||
}
|
||||
|
||||
VersionBitsCache versionbitscache GUARDED_BY(cs_main);
|
||||
|
||||
int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params)
|
||||
{
|
||||
LOCK(cs_main);
|
||||
int32_t nVersion = VERSIONBITS_TOP_BITS;
|
||||
|
||||
for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
|
||||
ThresholdState state = VersionBitsState(pindexPrev, params, static_cast<Consensus::DeploymentPos>(i), versionbitscache);
|
||||
if (state == ThresholdState::LOCKED_IN || state == ThresholdState::STARTED) {
|
||||
nVersion |= VersionBitsMask(params, static_cast<Consensus::DeploymentPos>(i));
|
||||
}
|
||||
}
|
||||
|
||||
// Undo default signalling behavior for dynafed unless explicitly enabled.
|
||||
if (!gArgs.GetBoolArg("-con_dyna_deploy_signal", false)) {
|
||||
auto dynafed = Consensus::DeploymentPos::DEPLOYMENT_DYNA_FED;
|
||||
int bit = params.vDeployments[dynafed].bit;
|
||||
if (bit > 0 && bit < VERSIONBITS_NUM_BITS) {
|
||||
nVersion &= ~VersionBitsMask(params, dynafed);
|
||||
}
|
||||
}
|
||||
|
||||
return nVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Threshold condition checker that triggers when unknown versionbits are seen on the network.
|
||||
*/
|
||||
|
|
@ -1778,24 +1752,14 @@ public:
|
|||
return pindex->nHeight >= params.MinBIP9WarningHeight &&
|
||||
((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) &&
|
||||
((pindex->nVersion >> bit) & 1) != 0 &&
|
||||
((ComputeBlockVersion(pindex->pprev, params) >> bit) & 1) == 0;
|
||||
((g_versionbitscache.ComputeBlockVersion(pindex->pprev, params) >> bit) & 1) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
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)
|
||||
static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& consensusparams)
|
||||
{
|
||||
return params.SegwitHeight != std::numeric_limits<int>::max();
|
||||
}
|
||||
|
||||
static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& consensusparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
unsigned int flags = SCRIPT_VERIFY_NONE;
|
||||
|
||||
// BIP16 didn't become active until Apr 1 2012 (on mainnet, and
|
||||
|
|
@ -1812,36 +1776,36 @@ 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;
|
||||
}
|
||||
|
||||
// Start enforcing Taproot using versionbits logic.
|
||||
if (VersionBitsState(pindex->pprev, consensusparams, Consensus::DEPLOYMENT_TAPROOT, versionbitscache) == ThresholdState::ACTIVE) {
|
||||
// Enforce Taproot (BIP340-BIP342)
|
||||
if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_TAPROOT)) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (IsDynaFedEnabled(pindex->pprev, consensusparams)) {
|
||||
if (DeploymentActiveAfter(pindex->pprev, consensusparams, Consensus::DEPLOYMENT_DYNA_FED)) {
|
||||
flags |= SCRIPT_SIGHASH_RANGEPROOF;
|
||||
}
|
||||
|
||||
|
|
@ -2052,9 +2016,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;
|
||||
}
|
||||
|
||||
|
|
@ -3214,7 +3178,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);
|
||||
|
|
@ -3336,23 +3300,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);
|
||||
}
|
||||
|
||||
bool IsDynaFedEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params)
|
||||
{
|
||||
LOCK(cs_main);
|
||||
return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_DYNA_FED, versionbitscache) == ThresholdState::ACTIVE);
|
||||
}
|
||||
|
||||
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.witness.vtxinwit.resize(1);
|
||||
tx.witness.vtxinwit[0].scriptWitness.stack.resize(1);
|
||||
|
|
@ -3366,7 +3318,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) {
|
||||
// ELEMENTS: Shim in blank coinbase output for witness output hash
|
||||
// Previous iterations of CA could have allowed witness data
|
||||
|
|
@ -3409,7 +3361,7 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
|
|||
static bool ContextualCheckDynaFedHeader(const CBlockHeader& block, BlockValidationState& state, const CChainParams& params, const CBlockIndex* pindexPrev)
|
||||
{
|
||||
// When not active, it's a NOP
|
||||
if (!IsDynaFedEnabled(pindexPrev, params.GetConsensus())) {
|
||||
if (!DeploymentActiveAfter(pindexPrev, params.GetConsensus(), Consensus::DEPLOYMENT_DYNA_FED)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -3519,7 +3471,7 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
|
|||
|
||||
// Check proof of work target or non-dynamic signblockscript if necessary
|
||||
const Consensus::Params& consensusParams = params.GetConsensus();
|
||||
if (!IsDynaFedEnabled(pindexPrev, consensusParams) && !CheckChallenge(block, *pindexPrev, consensusParams))
|
||||
if (!DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_DYNA_FED) && !CheckChallenge(block, *pindexPrev, consensusParams))
|
||||
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-diffbits", "incorrect proof of work");
|
||||
|
||||
// Check against checkpoints
|
||||
|
|
@ -3548,13 +3500,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));
|
||||
}
|
||||
|
||||
if (!ContextualCheckDynaFedHeader(block, state, params, pindexPrev)) {
|
||||
return false;
|
||||
|
|
@ -3573,9 +3525,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;
|
||||
}
|
||||
|
|
@ -3592,7 +3544,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() ||
|
||||
|
|
@ -3620,7 +3572,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;
|
||||
|
|
@ -4455,9 +4407,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;
|
||||
|
|
@ -4487,7 +4438,7 @@ void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman)
|
|||
nLastBlockFile = 0;
|
||||
setDirtyBlockIndex.clear();
|
||||
setDirtyFileInfo.clear();
|
||||
versionbitscache.Clear();
|
||||
g_versionbitscache.Clear();
|
||||
for (int b = 0; b < VERSIONBITS_NUM_BITS; b++) {
|
||||
warningcache[b].clear();
|
||||
}
|
||||
|
|
@ -5358,7 +5309,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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue