diff --git a/src/Makefile.am b/src/Makefile.am index a3248f3eab..a8e1b7bc1e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -329,6 +329,7 @@ libbitcoin_server_a_SOURCES = \ chain.cpp \ consensus/tx_verify.cpp \ dbwrapper.cpp \ + deploymentstatus.cpp \ flatfile.cpp \ httprpc.cpp \ httpserver.cpp \ diff --git a/src/consensus/params.h b/src/consensus/params.h index 9b4139d76c..7d5fe1a734 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -22,13 +22,14 @@ enum BuriedDeployment : int16_t }; constexpr bool ValidDeployment(BuriedDeployment dep) { return DEPLOYMENT_HEIGHTINCB <= dep && dep <= DEPLOYMENT_SEGWIT; } -enum DeploymentPos +enum DeploymentPos : uint16_t { DEPLOYMENT_TESTDUMMY, DEPLOYMENT_TAPROOT, // Deployment of Schnorr/Taproot (BIPs 340-342) // NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp 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. diff --git a/src/deploymentstatus.cpp b/src/deploymentstatus.cpp new file mode 100644 index 0000000000..4e13fd7e0a --- /dev/null +++ b/src/deploymentstatus.cpp @@ -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 + +#include +#include + +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::DEPLOYMENT_TESTDUMMY)), "sanity check of BuriedDeployment failed (overlaps with DeploymentPos)"); diff --git a/src/deploymentstatus.h b/src/deploymentstatus.h index 32190e369d..327a5f7892 100644 --- a/src/deploymentstatus.h +++ b/src/deploymentstatus.h @@ -6,9 +6,13 @@ #define BITCOIN_DEPLOYMENTSTATUS_H #include +#include #include +/** Global cache for versionbits deployment status */ +extern VersionBitsCache versionbitscache; + /** Determine if a deployment is active for the next block */ 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); } +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 */ 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); } +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) */ 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::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 diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 807b0143a6..183b5a5d91 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -692,7 +693,7 @@ public: { LOCK(::cs_main); 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; }; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 22600c5340..7ba6e13142 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index 304cd8feb0..a89447732e 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/src/validation.cpp b/src/validation.cpp index b69faa54eb..782a6cd56d 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -684,9 +684,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"); } @@ -1607,8 +1606,6 @@ void StopScriptCheckWorkerThreads() scriptcheckqueue.StopWorkerThreads(); } -VersionBitsCache versionbitscache; - int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params) { int32_t nVersion = VERSIONBITS_TOP_BITS; @@ -1687,8 +1684,8 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consens 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; } diff --git a/src/validation.h b/src/validation.h index 50a8d7e575..0f00556053 100644 --- a/src/validation.h +++ b/src/validation.h @@ -24,7 +24,6 @@ #include #include // For CTxMemPool::cs #include -#include #include #include #include @@ -1020,8 +1019,6 @@ public: /** Global variable that points to the active block tree (protected by cs_main) */ extern std::unique_ptr pblocktree; -extern VersionBitsCache versionbitscache; - /** * Determine what nVersion a new block should use. */