[refactor] Add versionbits deployments to deploymentstatus.h

Adds support for versionbits deployments to DeploymentEnabled,
DeploymentActiveAfter and DeploymentActiveAt. Also moves versionbitscache
from validation to deploymentstatus.
This commit is contained in:
Anthony Towns 2020-07-03 04:01:23 +10:00
parent 2b0d291da8
commit de55304f6e
9 changed files with 50 additions and 12 deletions

View file

@ -329,6 +329,7 @@ libbitcoin_server_a_SOURCES = \
chain.cpp \ chain.cpp \
consensus/tx_verify.cpp \ consensus/tx_verify.cpp \
dbwrapper.cpp \ dbwrapper.cpp \
deploymentstatus.cpp \
flatfile.cpp \ flatfile.cpp \
httprpc.cpp \ httprpc.cpp \
httpserver.cpp \ httpserver.cpp \

View file

@ -22,13 +22,14 @@ enum BuriedDeployment : int16_t
}; };
constexpr bool ValidDeployment(BuriedDeployment dep) { return DEPLOYMENT_HEIGHTINCB <= dep && dep <= DEPLOYMENT_SEGWIT; } constexpr bool ValidDeployment(BuriedDeployment dep) { return DEPLOYMENT_HEIGHTINCB <= dep && dep <= DEPLOYMENT_SEGWIT; }
enum DeploymentPos enum DeploymentPos : uint16_t
{ {
DEPLOYMENT_TESTDUMMY, DEPLOYMENT_TESTDUMMY,
DEPLOYMENT_TAPROOT, // Deployment of Schnorr/Taproot (BIPs 340-342) DEPLOYMENT_TAPROOT, // Deployment of Schnorr/Taproot (BIPs 340-342)
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp // NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp
MAX_VERSION_BITS_DEPLOYMENTS MAX_VERSION_BITS_DEPLOYMENTS
}; };
constexpr bool ValidDeployment(DeploymentPos dep) { return DEPLOYMENT_TESTDUMMY <= dep && dep <= DEPLOYMENT_TAPROOT; }
/** /**
* Struct for each individual consensus rule change using BIP9. * Struct for each individual consensus rule change using BIP9.

17
src/deploymentstatus.cpp Normal file
View file

@ -0,0 +1,17 @@
// Copyright (c) 2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <deploymentstatus.h>
#include <consensus/params.h>
#include <versionbits.h>
VersionBitsCache versionbitscache;
/* Basic sanity checking for BuriedDeployment/DeploymentPos enums and
* ValidDeployment check */
static_assert(ValidDeployment(Consensus::DEPLOYMENT_TESTDUMMY), "sanity check of DeploymentPos failed (TESTDUMMY not valid)");
static_assert(!ValidDeployment(Consensus::MAX_VERSION_BITS_DEPLOYMENTS), "sanity check of DeploymentPos failed (MAX value considered valid)");
static_assert(!ValidDeployment(static_cast<Consensus::BuriedDeployment>(Consensus::DEPLOYMENT_TESTDUMMY)), "sanity check of BuriedDeployment failed (overlaps with DeploymentPos)");

View file

@ -6,9 +6,13 @@
#define BITCOIN_DEPLOYMENTSTATUS_H #define BITCOIN_DEPLOYMENTSTATUS_H
#include <chain.h> #include <chain.h>
#include <versionbits.h>
#include <limits> #include <limits>
/** Global cache for versionbits deployment status */
extern VersionBitsCache versionbitscache;
/** Determine if a deployment is active for the next block */ /** Determine if a deployment is active for the next block */
inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::BuriedDeployment dep) inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::BuriedDeployment dep)
{ {
@ -16,6 +20,12 @@ inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus
return (pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1) >= params.DeploymentHeight(dep); return (pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1) >= params.DeploymentHeight(dep);
} }
inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos dep)
{
assert(Consensus::ValidDeployment(dep));
return ThresholdState::ACTIVE == VersionBitsState(pindexPrev, params, dep, versionbitscache);
}
/** Determine if a deployment is active for this block */ /** Determine if a deployment is active for this block */
inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::BuriedDeployment dep) inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::BuriedDeployment dep)
{ {
@ -23,6 +33,12 @@ inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params
return index.nHeight >= params.DeploymentHeight(dep); return index.nHeight >= params.DeploymentHeight(dep);
} }
inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::DeploymentPos dep)
{
assert(Consensus::ValidDeployment(dep));
return DeploymentActiveAfter(index.pprev, params, dep);
}
/** Determine if a deployment is enabled (can ever be active) */ /** Determine if a deployment is enabled (can ever be active) */
inline bool DeploymentEnabled(const Consensus::Params& params, Consensus::BuriedDeployment dep) inline bool DeploymentEnabled(const Consensus::Params& params, Consensus::BuriedDeployment dep)
{ {
@ -30,4 +46,10 @@ inline bool DeploymentEnabled(const Consensus::Params& params, Consensus::Buried
return params.DeploymentHeight(dep) != std::numeric_limits<int>::max(); return params.DeploymentHeight(dep) != std::numeric_limits<int>::max();
} }
inline bool DeploymentEnabled(const Consensus::Params& params, Consensus::DeploymentPos dep)
{
assert(Consensus::ValidDeployment(dep));
return params.vDeployments[dep].nTimeout != 0;
}
#endif // BITCOIN_DEPLOYMENTSTATUS_H #endif // BITCOIN_DEPLOYMENTSTATUS_H

View file

@ -6,6 +6,7 @@
#include <banman.h> #include <banman.h>
#include <chain.h> #include <chain.h>
#include <chainparams.h> #include <chainparams.h>
#include <deploymentstatus.h>
#include <external_signer.h> #include <external_signer.h>
#include <init.h> #include <init.h>
#include <interfaces/chain.h> #include <interfaces/chain.h>
@ -692,7 +693,7 @@ public:
{ {
LOCK(::cs_main); LOCK(::cs_main);
const CBlockIndex* tip = Assert(m_node.chainman)->ActiveChain().Tip(); const CBlockIndex* tip = Assert(m_node.chainman)->ActiveChain().Tip();
return VersionBitsState(tip, Params().GetConsensus(), Consensus::DEPLOYMENT_TAPROOT, versionbitscache) == ThresholdState::ACTIVE; return DeploymentActiveAfter(tip, Params().GetConsensus(), Consensus::DEPLOYMENT_TAPROOT);
} }
NodeContext& m_node; NodeContext& m_node;
}; };

View file

@ -12,6 +12,7 @@
#include <coins.h> #include <coins.h>
#include <consensus/validation.h> #include <consensus/validation.h>
#include <core_io.h> #include <core_io.h>
#include <deploymentstatus.h>
#include <hash.h> #include <hash.h>
#include <index/blockfilterindex.h> #include <index/blockfilterindex.h>
#include <index/coinstatsindex.h> #include <index/coinstatsindex.h>

View file

@ -5,6 +5,7 @@
#include <chain.h> #include <chain.h>
#include <chainparams.h> #include <chainparams.h>
#include <consensus/params.h> #include <consensus/params.h>
#include <deploymentstatus.h>
#include <test/util/setup_common.h> #include <test/util/setup_common.h>
#include <validation.h> #include <validation.h>
#include <versionbits.h> #include <versionbits.h>

View file

@ -684,9 +684,8 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
} }
// Check for non-standard pay-to-script-hash in inputs // Check for non-standard pay-to-script-hash in inputs
const auto& params = args.m_chainparams.GetConsensus(); const bool taproot_active = DeploymentActiveAfter(m_active_chainstate.m_chain.Tip(), args.m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_TAPROOT);
auto taproot_state = VersionBitsState(m_active_chainstate.m_chain.Tip(), params, Consensus::DEPLOYMENT_TAPROOT, versionbitscache); if (fRequireStandard && !AreInputsStandard(tx, m_view, taproot_active)) {
if (fRequireStandard && !AreInputsStandard(tx, m_view, taproot_state == ThresholdState::ACTIVE)) {
return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs"); return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs");
} }
@ -1607,8 +1606,6 @@ void StopScriptCheckWorkerThreads()
scriptcheckqueue.StopWorkerThreads(); scriptcheckqueue.StopWorkerThreads();
} }
VersionBitsCache versionbitscache;
int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params) int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params)
{ {
int32_t nVersion = VERSIONBITS_TOP_BITS; int32_t nVersion = VERSIONBITS_TOP_BITS;
@ -1687,8 +1684,8 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consens
flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
} }
// Start enforcing Taproot using versionbits logic. // Enforce Taproot (BIP340-BIP342)
if (VersionBitsState(pindex->pprev, consensusparams, Consensus::DEPLOYMENT_TAPROOT, versionbitscache) == ThresholdState::ACTIVE) { if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_TAPROOT)) {
flags |= SCRIPT_VERIFY_TAPROOT; flags |= SCRIPT_VERIFY_TAPROOT;
} }

View file

@ -24,7 +24,6 @@
#include <sync.h> #include <sync.h>
#include <txmempool.h> // For CTxMemPool::cs #include <txmempool.h> // For CTxMemPool::cs
#include <txdb.h> #include <txdb.h>
#include <versionbits.h>
#include <serialize.h> #include <serialize.h>
#include <util/check.h> #include <util/check.h>
#include <util/hasher.h> #include <util/hasher.h>
@ -1020,8 +1019,6 @@ public:
/** Global variable that points to the active block tree (protected by cs_main) */ /** Global variable that points to the active block tree (protected by cs_main) */
extern std::unique_ptr<CBlockTreeDB> pblocktree; extern std::unique_ptr<CBlockTreeDB> pblocktree;
extern VersionBitsCache versionbitscache;
/** /**
* Determine what nVersion a new block should use. * Determine what nVersion a new block should use.
*/ */