Merge pull request #5740 from knst/bp-versionbits

backport: bitcoin#19438 Introduce deploymentstatus (versionbits improvements)
This commit is contained in:
PastaPastaPasta 2023-12-01 09:09:47 -06:00 committed by Odysseas Gabrielides
parent 5e8140d23f
commit 18b580591c
23 changed files with 377 additions and 182 deletions

View File

@ -169,6 +169,8 @@ BITCOIN_CORE_H = \
cuckoocache.h \ cuckoocache.h \
ctpl_stl.h \ ctpl_stl.h \
cxxtimer.hpp \ cxxtimer.hpp \
deploymentinfo.h \
deploymentstatus.h \
evo/assetlocktx.h \ evo/assetlocktx.h \
evo/dmn_types.h \ evo/dmn_types.h \
evo/cbtx.h \ evo/cbtx.h \
@ -349,7 +351,6 @@ BITCOIN_CORE_H = \
validation.h \ validation.h \
validationinterface.h \ validationinterface.h \
versionbits.h \ versionbits.h \
versionbitsinfo.h \
walletinitinterface.h \ walletinitinterface.h \
wallet/bdb.h \ wallet/bdb.h \
wallet/coincontrol.h \ wallet/coincontrol.h \
@ -403,6 +404,7 @@ libbitcoin_server_a_SOURCES = \
coinjoin/server.cpp \ coinjoin/server.cpp \
consensus/tx_verify.cpp \ consensus/tx_verify.cpp \
dbwrapper.cpp \ dbwrapper.cpp \
deploymentstatus.cpp \
dsnotificationinterface.cpp \ dsnotificationinterface.cpp \
evo/assetlocktx.cpp \ evo/assetlocktx.cpp \
evo/cbtx.cpp \ evo/cbtx.cpp \
@ -696,6 +698,7 @@ libbitcoin_common_a_SOURCES = \
compressor.cpp \ compressor.cpp \
core_read.cpp \ core_read.cpp \
core_write.cpp \ core_write.cpp \
deploymentinfo.cpp \
key.cpp \ key.cpp \
key_io.cpp \ key_io.cpp \
merkleblock.cpp \ merkleblock.cpp \
@ -715,7 +718,6 @@ libbitcoin_common_a_SOURCES = \
script/sign.cpp \ script/sign.cpp \
script/signingprovider.cpp \ script/signingprovider.cpp \
script/standard.cpp \ script/standard.cpp \
versionbitsinfo.cpp \
warnings.cpp \ warnings.cpp \
$(BITCOIN_CORE_H) $(BITCOIN_CORE_H)

View File

@ -8,12 +8,12 @@
#include <chainparamsseeds.h> #include <chainparamsseeds.h>
#include <consensus/merkle.h> #include <consensus/merkle.h>
#include <deploymentinfo.h>
#include <llmq/params.h> #include <llmq/params.h>
#include <util/ranges.h> #include <util/ranges.h>
#include <util/system.h> #include <util/system.h>
#include <util/underlying.h> #include <util/underlying.h>
#include <versionbits.h> #include <versionbits.h>
#include <versionbitsinfo.h>
#include <arith_uint256.h> #include <arith_uint256.h>

View File

@ -14,13 +14,32 @@
namespace Consensus { namespace Consensus {
enum DeploymentPos { enum BuriedDeployment : int16_t
{
DEPLOYMENT_HEIGHTINCB = std::numeric_limits<int16_t>::min(),
DEPLOYMENT_DERSIG,
DEPLOYMENT_CLTV,
DEPLOYMENT_BIP147,
DEPLOYMENT_CSV,
DEPLOYMENT_DIP0001,
DEPLOYMENT_DIP0003,
DEPLOYMENT_DIP0008,
DEPLOYMENT_DIP0020,
DEPLOYMENT_DIP0024,
DEPLOYMENT_BRR,
DEPLOYMENT_V19,
};
constexpr bool ValidDeployment(BuriedDeployment dep) { return DEPLOYMENT_HEIGHTINCB <= dep && dep <= DEPLOYMENT_V19; }
enum DeploymentPos : uint16_t
{
DEPLOYMENT_TESTDUMMY, DEPLOYMENT_TESTDUMMY,
DEPLOYMENT_V20, // Deployment of EHF, LLMQ Randomness Beacon DEPLOYMENT_V20, // Deployment of EHF, LLMQ Randomness Beacon
DEPLOYMENT_MN_RR, // Deployment of Masternode Reward Location Reallocation DEPLOYMENT_MN_RR, // Deployment of Masternode Reward Location Reallocation
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp // NOTE: Also add new deployments to VersionBitsDeploymentInfo in deploymentinfo.cpp
MAX_VERSION_BITS_DEPLOYMENTS MAX_VERSION_BITS_DEPLOYMENTS
}; };
constexpr bool ValidDeployment(DeploymentPos dep) { return DEPLOYMENT_TESTDUMMY <= dep && dep <= DEPLOYMENT_MN_RR; }
/** /**
* Struct for each individual consensus rule change using BIP9. * Struct for each individual consensus rule change using BIP9.
@ -145,7 +164,39 @@ struct Params {
LLMQType llmqTypePlatform{LLMQType::LLMQ_NONE}; LLMQType llmqTypePlatform{LLMQType::LLMQ_NONE};
LLMQType llmqTypeMnhf{LLMQType::LLMQ_NONE}; LLMQType llmqTypeMnhf{LLMQType::LLMQ_NONE};
LLMQType llmqTypeAssetLocks{LLMQType::LLMQ_NONE}; LLMQType llmqTypeAssetLocks{LLMQType::LLMQ_NONE};
int DeploymentHeight(BuriedDeployment dep) const
{
switch (dep) {
case DEPLOYMENT_HEIGHTINCB:
return BIP34Height;
case DEPLOYMENT_DERSIG:
return BIP66Height;
case DEPLOYMENT_CLTV:
return BIP65Height;
case DEPLOYMENT_BIP147:
return BIP147Height;
case DEPLOYMENT_CSV:
return CSVHeight;
case DEPLOYMENT_DIP0001:
return DIP0001Height;
case DEPLOYMENT_DIP0003:
return DIP0003Height;
case DEPLOYMENT_DIP0008:
return DIP0008Height;
case DEPLOYMENT_DIP0020:
return DIP0020Height;
case DEPLOYMENT_DIP0024:
return DIP0024Height;
case DEPLOYMENT_BRR:
return BRRHeight;
case DEPLOYMENT_V19:
return V19Height;
} // no default case, so the compiler can warn about missing cases
return std::numeric_limits<int>::max();
}
}; };
} // namespace Consensus } // namespace Consensus
#endif // BITCOIN_CONSENSUS_PARAMS_H #endif // BITCOIN_CONSENSUS_PARAMS_H

54
src/deploymentinfo.cpp Normal file
View File

@ -0,0 +1,54 @@
// Copyright (c) 2016-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 <deploymentinfo.h>
#include <consensus/params.h>
const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] = {
{
/*.name =*/ "testdummy",
/*.gbt_force =*/ true,
},
{
/*.name =*/"v20",
/*.gbt_force =*/true,
},
{
/*.name =*/"mn_rr",
/*.gbt_force =*/true,
},
};
std::string DeploymentName(Consensus::BuriedDeployment dep)
{
assert(ValidDeployment(dep));
switch (dep) {
case Consensus::DEPLOYMENT_HEIGHTINCB:
return "bip34";
case Consensus::DEPLOYMENT_CLTV:
return "bip65";
case Consensus::DEPLOYMENT_DERSIG:
return "bip66";
case Consensus::DEPLOYMENT_BIP147:
return "bip147";
case Consensus::DEPLOYMENT_CSV:
return "csv";
case Consensus::DEPLOYMENT_DIP0001:
return "dip0001";
case Consensus::DEPLOYMENT_DIP0003:
return "dip0003";
case Consensus::DEPLOYMENT_DIP0008:
return "dip0008";
case Consensus::DEPLOYMENT_DIP0020:
return "dip0020";
case Consensus::DEPLOYMENT_DIP0024:
return "dip0024";
case Consensus::DEPLOYMENT_BRR:
return "realloc";
case Consensus::DEPLOYMENT_V19:
return "v19";
} // no default case, so the compiler can warn about missing cases
return "";
}

29
src/deploymentinfo.h Normal file
View File

@ -0,0 +1,29 @@
// Copyright (c) 2016-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_DEPLOYMENTINFO_H
#define BITCOIN_DEPLOYMENTINFO_H
#include <consensus/params.h>
#include <string>
struct VBDeploymentInfo {
/** Deployment name */
const char *name;
/** Whether GBT clients can safely ignore this rule in simplified usage */
bool gbt_force;
};
extern const VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS];
std::string DeploymentName(Consensus::BuriedDeployment dep);
inline std::string DeploymentName(Consensus::DeploymentPos pos)
{
assert(Consensus::ValidDeployment(pos));
return VersionBitsDeploymentInfo[pos].name;
}
#endif // BITCOIN_DEPLOYMENTINFO_H

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 g_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)");

55
src/deploymentstatus.h Normal file
View File

@ -0,0 +1,55 @@
// 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.
#ifndef BITCOIN_DEPLOYMENTSTATUS_H
#define BITCOIN_DEPLOYMENTSTATUS_H
#include <chain.h>
#include <versionbits.h>
#include <limits>
/** Global cache for versionbits deployment status */
extern VersionBitsCache g_versionbitscache;
/** Determine if a deployment is active for the next block */
inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::BuriedDeployment dep)
{
assert(Consensus::ValidDeployment(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 == g_versionbitscache.State(pindexPrev, params, dep);
}
/** Determine if a deployment is active for this block */
inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::BuriedDeployment dep)
{
assert(Consensus::ValidDeployment(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) */
inline bool DeploymentEnabled(const Consensus::Params& params, Consensus::BuriedDeployment dep)
{
assert(Consensus::ValidDeployment(dep));
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

View File

@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <consensus/validation.h> #include <consensus/validation.h>
#include <deploymentstatus.h>
#include <evo/mnhftx.h> #include <evo/mnhftx.h>
#include <evo/specialtx.h> #include <evo/specialtx.h>
#include <llmq/commitment.h> #include <llmq/commitment.h>
@ -278,10 +279,12 @@ CMNHFManager::Signals CMNHFManager::GetFromCache(const CBlockIndex* const pindex
return signals; return signals;
} }
} }
if (VersionBitsState(pindex->pprev, Params().GetConsensus(), Consensus::DEPLOYMENT_V20, versionbitscache) != ThresholdState::ACTIVE) { {
LOCK(cs_cache); LOCK(cs_cache);
mnhfCache.insert(blockHash, {}); if (ThresholdState::ACTIVE != v20_activation.State(pindex->pprev, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) {
return {}; mnhfCache.insert(blockHash, {});
return {};
}
} }
bool ok = m_evoDb.Read(std::make_pair(DB_SIGNALS, blockHash), signals); bool ok = m_evoDb.Read(std::make_pair(DB_SIGNALS, blockHash), signals);
assert(ok); assert(ok);
@ -297,8 +300,10 @@ void CMNHFManager::AddToCache(const Signals& signals, const CBlockIndex* const p
LOCK(cs_cache); LOCK(cs_cache);
mnhfCache.insert(blockHash, signals); mnhfCache.insert(blockHash, signals);
} }
if (VersionBitsState(pindex->pprev, Params().GetConsensus(), Consensus::DEPLOYMENT_V20, versionbitscache) != ThresholdState::ACTIVE) { assert(pindex != nullptr);
return; {
LOCK(cs_cache);
if (ThresholdState::ACTIVE != v20_activation.State(pindex->pprev, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) return;
} }
m_evoDb.Write(std::make_pair(DB_SIGNALS, blockHash), signals); m_evoDb.Write(std::make_pair(DB_SIGNALS, blockHash), signals);
} }

View File

@ -102,6 +102,8 @@ private:
// versionBit <-> height // versionBit <-> height
unordered_lru_cache<uint256, Signals, StaticSaltedHasher> mnhfCache GUARDED_BY(cs_cache) {MNHFCacheSize}; unordered_lru_cache<uint256, Signals, StaticSaltedHasher> mnhfCache GUARDED_BY(cs_cache) {MNHFCacheSize};
// This cache is used only for v20 activation to avoid double lock throught VersionBitsConditionChecker::SignalHeight
VersionBitsCache v20_activation GUARDED_BY(cs_cache);
public: public:
explicit CMNHFManager(CEvoDB& evoDb); explicit CMNHFManager(CEvoDB& evoDb);
~CMNHFManager(); ~CMNHFManager();

View File

@ -17,6 +17,7 @@
#include <util/time.h> #include <util/time.h>
#include <util/underlying.h> #include <util/underlying.h>
#include <validation.h> #include <validation.h>
#include <versionbits.h>
#include <univalue.h> #include <univalue.h>

View File

@ -709,7 +709,7 @@ bool IsV19Active(gsl::not_null<const CBlockIndex*> pindex)
bool IsV20Active(gsl::not_null<const CBlockIndex*> pindex) bool IsV20Active(gsl::not_null<const CBlockIndex*> pindex)
{ {
LOCK(cs_llmq_vbc); LOCK(cs_llmq_vbc);
return VersionBitsState(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_V20, llmq_versionbitscache) == ThresholdState::ACTIVE; return llmq_versionbitscache.State(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_V20) == ThresholdState::ACTIVE;
} }
bool IsMNRewardReallocationActive(gsl::not_null<const CBlockIndex*> pindex) bool IsMNRewardReallocationActive(gsl::not_null<const CBlockIndex*> pindex)
@ -717,19 +717,19 @@ bool IsMNRewardReallocationActive(gsl::not_null<const CBlockIndex*> pindex)
if (!IsV20Active(pindex)) return false; if (!IsV20Active(pindex)) return false;
LOCK(cs_llmq_vbc); LOCK(cs_llmq_vbc);
return VersionBitsState(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_MN_RR, llmq_versionbitscache) == ThresholdState::ACTIVE; return llmq_versionbitscache.State(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_MN_RR) == ThresholdState::ACTIVE;
} }
ThresholdState GetV20State(gsl::not_null<const CBlockIndex*> pindex) ThresholdState GetV20State(gsl::not_null<const CBlockIndex*> pindex)
{ {
LOCK(cs_llmq_vbc); LOCK(cs_llmq_vbc);
return VersionBitsState(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_V20, llmq_versionbitscache); return llmq_versionbitscache.State(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_V20);
} }
int GetV20Since(gsl::not_null<const CBlockIndex*> pindex) int GetV20Since(gsl::not_null<const CBlockIndex*> pindex)
{ {
LOCK(cs_llmq_vbc); LOCK(cs_llmq_vbc);
return VersionBitsStateSinceHeight(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_V20, llmq_versionbitscache); return llmq_versionbitscache.StateSinceHeight(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_V20);
} }
bool IsInstantSendLLMQTypeShared() bool IsInstantSendLLMQTypeShared()
@ -1006,7 +1006,7 @@ bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, const CQuorumMana
case Consensus::LLMQType::LLMQ_TEST_V17: { case Consensus::LLMQType::LLMQ_TEST_V17: {
LOCK(cs_llmq_vbc); LOCK(cs_llmq_vbc);
return VersionBitsState(pindex, consensusParams, Consensus::DEPLOYMENT_TESTDUMMY, llmq_versionbitscache) == ThresholdState::ACTIVE; return llmq_versionbitscache.State(pindex, consensusParams, Consensus::DEPLOYMENT_TESTDUMMY) == ThresholdState::ACTIVE;
} }
case Consensus::LLMQType::LLMQ_100_67: case Consensus::LLMQType::LLMQ_100_67:
return pindex->nHeight + 1 >= consensusParams.DIP0020Height; return pindex->nHeight + 1 >= consensusParams.DIP0020Height;

View File

@ -13,6 +13,7 @@
#include <consensus/merkle.h> #include <consensus/merkle.h>
#include <consensus/tx_verify.h> #include <consensus/tx_verify.h>
#include <consensus/validation.h> #include <consensus/validation.h>
#include <deploymentstatus.h>
#include <policy/feerate.h> #include <policy/feerate.h>
#include <policy/policy.h> #include <policy/policy.h>
#include <pow.h> #include <pow.h>
@ -132,11 +133,11 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
assert(pindexPrev != nullptr); assert(pindexPrev != nullptr);
nHeight = pindexPrev->nHeight + 1; nHeight = pindexPrev->nHeight + 1;
bool fDIP0003Active_context = nHeight >= chainparams.GetConsensus().DIP0003Height; bool fDIP0003Active_context = DeploymentActiveAfter(pindexPrev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_DIP0003);
bool fDIP0008Active_context = nHeight >= chainparams.GetConsensus().DIP0008Height; bool fDIP0008Active_context = DeploymentActiveAfter(pindexPrev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_DIP0008);
bool fV20Active_context = llmq::utils::IsV20Active(pindexPrev); bool fV20Active_context = llmq::utils::IsV20Active(pindexPrev);
pblock->nVersion = ComputeBlockVersion(pindexPrev, chainparams.GetConsensus()); pblock->nVersion = g_versionbitscache.ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
// Non-mainnet only: allow overriding block.nVersion with // Non-mainnet only: allow overriding block.nVersion with
// -blockversion=N to test forking scenarios // -blockversion=N to test forking scenarios
if (Params().NetworkIDString() != CBaseChainParams::MAIN) if (Params().NetworkIDString() != CBaseChainParams::MAIN)

View File

@ -8,6 +8,7 @@
#include <banman.h> #include <banman.h>
#include <chain.h> #include <chain.h>
#include <chainparams.h> #include <chainparams.h>
#include <deploymentstatus.h>
#include <evo/deterministicmns.h> #include <evo/deterministicmns.h>
#include <governance/governance.h> #include <governance/governance.h>
#include <governance/object.h> #include <governance/object.h>

View File

@ -12,7 +12,10 @@
#include <chainparams.h> #include <chainparams.h>
#include <coins.h> #include <coins.h>
#include <core_io.h> #include <core_io.h>
#include <consensus/params.h>
#include <consensus/validation.h> #include <consensus/validation.h>
#include <deploymentinfo.h>
#include <deploymentstatus.h>
#include <index/blockfilterindex.h> #include <index/blockfilterindex.h>
#include <index/coinstatsindex.h> #include <index/coinstatsindex.h>
#include <index/txindex.h> #include <index/txindex.h>
@ -35,7 +38,7 @@
#include <util/system.h> #include <util/system.h>
#include <validation.h> #include <validation.h>
#include <validationinterface.h> #include <validationinterface.h>
#include <versionbitsinfo.h> #include <versionbits.h>
#include <warnings.h> #include <warnings.h>
#include <evo/specialtx.h> #include <evo/specialtx.h>
@ -1572,25 +1575,25 @@ static UniValue verifychain(const JSONRPCRequest& request)
active_chainstate, Params(), active_chainstate.CoinsTip(), *node.evodb, check_level, check_depth); active_chainstate, Params(), active_chainstate.CoinsTip(), *node.evodb, check_level, check_depth);
} }
static void BuriedForkDescPushBack(UniValue& softforks, const std::string &name, int softfork_height, int tip_height) EXCLUSIVE_LOCKS_REQUIRED(cs_main) static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue& softforks, const Consensus::Params& params, Consensus::BuriedDeployment dep)
{ {
// For buried deployments. // For buried deployments.
// A buried deployment is one where the height of the activation has been hardcoded into // A buried deployment is one where the height of the activation has been hardcoded into
// the client implementation long after the consensus change has activated. See BIP 90. // the client implementation long after the consensus change has activated. See BIP 90.
// Buried deployments with activation height value of // Buried deployments with activation height value of
// std::numeric_limits<int>::max() are disabled and thus hidden. // std::numeric_limits<int>::max() are disabled and thus hidden.
if (softfork_height == std::numeric_limits<int>::max()) return; if (!DeploymentEnabled(params, dep)) return;
UniValue rv(UniValue::VOBJ); UniValue rv(UniValue::VOBJ);
rv.pushKV("type", "buried"); rv.pushKV("type", "buried");
// getblockchaininfo reports the softfork as active from when the chain height is // getblockchaininfo reports the softfork as active from when the chain height is
// one below the activation height // one below the activation height
rv.pushKV("active", tip_height + 1 >= softfork_height); rv.pushKV("active", DeploymentActiveAfter(active_chain_tip, params, dep));
rv.pushKV("height", softfork_height); rv.pushKV("height", params.DeploymentHeight(dep));
softforks.pushKV(name, rv); softforks.pushKV(DeploymentName(dep), rv);
} }
static void BIP9SoftForkDescPushBack(const CBlockIndex* active_chain_tip, const std::unordered_map<uint8_t, int>& signals, UniValue& softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) EXCLUSIVE_LOCKS_REQUIRED(cs_main) static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, const std::unordered_map<uint8_t, int>& signals, UniValue& softforks, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
{ {
// For BIP9 deployments. // For BIP9 deployments.
// Deployments (e.g. testdummy) with timeout value before Jan 1, 2009 are hidden. // Deployments (e.g. testdummy) with timeout value before Jan 1, 2009 are hidden.
@ -1599,7 +1602,7 @@ static void BIP9SoftForkDescPushBack(const CBlockIndex* active_chain_tip, const
if (consensusParams.vDeployments[id].nTimeout <= 1230768000) return; if (consensusParams.vDeployments[id].nTimeout <= 1230768000) return;
UniValue bip9(UniValue::VOBJ); UniValue bip9(UniValue::VOBJ);
const ThresholdState thresholdState = VersionBitsState(active_chain_tip, consensusParams, id, versionbitscache); const ThresholdState thresholdState = g_versionbitscache.State(active_chain_tip, consensusParams, id);
switch (thresholdState) { switch (thresholdState) {
case ThresholdState::DEFINED: bip9.pushKV("status", "defined"); break; case ThresholdState::DEFINED: bip9.pushKV("status", "defined"); break;
case ThresholdState::STARTED: bip9.pushKV("status", "started"); break; case ThresholdState::STARTED: bip9.pushKV("status", "started"); break;
@ -1617,12 +1620,12 @@ static void BIP9SoftForkDescPushBack(const CBlockIndex* active_chain_tip, const
if (auto it = signals.find(consensusParams.vDeployments[id].bit); it != signals.end()) { if (auto it = signals.find(consensusParams.vDeployments[id].bit); it != signals.end()) {
bip9.pushKV("ehf_height", it->second); bip9.pushKV("ehf_height", it->second);
} }
int64_t since_height = VersionBitsStateSinceHeight(active_chain_tip, consensusParams, id, versionbitscache); int64_t since_height = g_versionbitscache.StateSinceHeight(active_chain_tip, consensusParams, id);
bip9.pushKV("since", since_height); bip9.pushKV("since", since_height);
if (ThresholdState::STARTED == thresholdState) if (ThresholdState::STARTED == thresholdState)
{ {
UniValue statsUV(UniValue::VOBJ); UniValue statsUV(UniValue::VOBJ);
BIP9Stats statsStruct = VersionBitsStatistics(active_chain_tip, consensusParams, id, versionbitscache); BIP9Stats statsStruct = g_versionbitscache.Statistics(active_chain_tip, consensusParams, id);
statsUV.pushKV("period", statsStruct.period); statsUV.pushKV("period", statsStruct.period);
statsUV.pushKV("threshold", statsStruct.threshold); statsUV.pushKV("threshold", statsStruct.threshold);
statsUV.pushKV("elapsed", statsStruct.elapsed); statsUV.pushKV("elapsed", statsStruct.elapsed);
@ -1642,7 +1645,7 @@ static void BIP9SoftForkDescPushBack(const CBlockIndex* active_chain_tip, const
} }
rv.pushKV("active", ThresholdState::ACTIVE == thresholdState); rv.pushKV("active", ThresholdState::ACTIVE == thresholdState);
softforks.pushKV(name, rv); softforks.pushKV(DeploymentName(id), rv);
} }
UniValue getblockchaininfo(const JSONRPCRequest& request) UniValue getblockchaininfo(const JSONRPCRequest& request)
@ -1743,23 +1746,23 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
const Consensus::Params& consensusParams = Params().GetConsensus(); const Consensus::Params& consensusParams = Params().GetConsensus();
UniValue softforks(UniValue::VOBJ); UniValue softforks(UniValue::VOBJ);
// sorted by activation block // sorted by activation block
BuriedForkDescPushBack(softforks,"bip34", consensusParams.BIP34Height, height); SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB);
BuriedForkDescPushBack(softforks,"bip66", consensusParams.BIP66Height, height); SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DERSIG);
BuriedForkDescPushBack(softforks,"bip65", consensusParams.BIP65Height, height); SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_CLTV);
BuriedForkDescPushBack(softforks,"bip147", consensusParams.BIP147Height, height); SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_BIP147);
BuriedForkDescPushBack(softforks, "csv", consensusParams.CSVHeight, height); SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_CSV);
BuriedForkDescPushBack(softforks, "dip0001", consensusParams.DIP0001Height, height); SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DIP0001);
BuriedForkDescPushBack(softforks, "dip0003", consensusParams.DIP0003Height, height); SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DIP0003);
BuriedForkDescPushBack(softforks, "dip0008", consensusParams.DIP0008Height, height); SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DIP0008);
BuriedForkDescPushBack(softforks, "dip0020", consensusParams.DIP0020Height, height); SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DIP0020);
BuriedForkDescPushBack(softforks, "dip0024", consensusParams.DIP0024Height, height); SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DIP0024);
BuriedForkDescPushBack(softforks, "realloc", consensusParams.BRRHeight, height); SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_BRR);
BuriedForkDescPushBack(softforks, "v19", consensusParams.V19Height, height); SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_V19);
BIP9SoftForkDescPushBack(tip, ehfSignals, softforks, "v20", consensusParams, Consensus::DEPLOYMENT_V20); SoftForkDescPushBack(tip, ehfSignals, softforks, consensusParams, Consensus::DEPLOYMENT_V20);
BIP9SoftForkDescPushBack(tip, ehfSignals, softforks, "mn_rr", consensusParams, Consensus::DEPLOYMENT_MN_RR); SoftForkDescPushBack(tip, ehfSignals, softforks, consensusParams, Consensus::DEPLOYMENT_MN_RR);
BIP9SoftForkDescPushBack(tip, ehfSignals, softforks, "testdummy", consensusParams, Consensus::DEPLOYMENT_TESTDUMMY); SoftForkDescPushBack(tip, ehfSignals, softforks, consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
obj.pushKV("softforks", softforks); obj.pushKV("softforks", softforks);
obj.pushKV("warnings", GetWarnings(false)); obj.pushKV("warnings", GetWarnings(false));
return obj; return obj;

View File

@ -11,6 +11,8 @@
#include <consensus/params.h> #include <consensus/params.h>
#include <consensus/validation.h> #include <consensus/validation.h>
#include <core_io.h> #include <core_io.h>
#include <deploymentinfo.h>
#include <deploymentstatus.h>
#include <key_io.h> #include <key_io.h>
#include <llmq/blockprocessor.h> #include <llmq/blockprocessor.h>
#include <llmq/context.h> #include <llmq/context.h>
@ -39,7 +41,6 @@
#include <util/system.h> #include <util/system.h>
#include <validation.h> #include <validation.h>
#include <validationinterface.h> #include <validationinterface.h>
#include <versionbitsinfo.h>
#include <warnings.h> #include <warnings.h>
#include <governance/classes.h> #include <governance/classes.h>
@ -851,7 +852,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
UniValue vbavailable(UniValue::VOBJ); UniValue vbavailable(UniValue::VOBJ);
for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) { for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
Consensus::DeploymentPos pos = Consensus::DeploymentPos(j); Consensus::DeploymentPos pos = Consensus::DeploymentPos(j);
ThresholdState state = VersionBitsState(pindexPrev, consensusParams, pos, versionbitscache); ThresholdState state = g_versionbitscache.State(pindexPrev, consensusParams, pos);
switch (state) { switch (state) {
case ThresholdState::DEFINED: case ThresholdState::DEFINED:
case ThresholdState::FAILED: case ThresholdState::FAILED:
@ -859,7 +860,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
break; break;
case ThresholdState::LOCKED_IN: case ThresholdState::LOCKED_IN:
// Ensure bit is set in block version // Ensure bit is set in block version
pblock->nVersion |= VersionBitsMask(consensusParams, pos); pblock->nVersion |= g_versionbitscache.Mask(consensusParams, pos);
// FALL THROUGH to get vbavailable set... // FALL THROUGH to get vbavailable set...
case ThresholdState::STARTED: case ThresholdState::STARTED:
{ {
@ -868,7 +869,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
if (setClientRules.find(vbinfo.name) == setClientRules.end()) { if (setClientRules.find(vbinfo.name) == setClientRules.end()) {
if (!vbinfo.gbt_force) { if (!vbinfo.gbt_force) {
// If the client doesn't support this, don't indicate it in the [default] version // If the client doesn't support this, don't indicate it in the [default] version
pblock->nVersion &= ~VersionBitsMask(consensusParams, pos); pblock->nVersion &= ~g_versionbitscache.Mask(consensusParams, pos);
} }
} }
break; break;

View File

@ -6,6 +6,7 @@
#include <chainparams.h> #include <chainparams.h>
#include <consensus/validation.h> #include <consensus/validation.h>
#include <deploymentstatus.h>
#include <evo/evodb.h> #include <evo/evodb.h>
#include <governance/governance.h> #include <governance/governance.h>
#include <llmq/blockprocessor.h> #include <llmq/blockprocessor.h>
@ -16,6 +17,7 @@
#include <script/interpreter.h> #include <script/interpreter.h>
#include <spork.h> #include <spork.h>
#include <validation.h> #include <validation.h>
#include <versionbits.h>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
@ -53,9 +55,9 @@ struct TestChainDATSetup : public TestChainSetup
} }
LOCK(cs_main); LOCK(cs_main);
if (expected_lockin) { if (expected_lockin) {
BOOST_CHECK_EQUAL(VersionBitsState(::ChainActive().Tip(), consensus_params, deployment_id, versionbitscache), ThresholdState::LOCKED_IN); BOOST_CHECK_EQUAL(g_versionbitscache.State(::ChainActive().Tip(), consensus_params, deployment_id), ThresholdState::LOCKED_IN);
} else { } else {
BOOST_CHECK_EQUAL(VersionBitsState(::ChainActive().Tip(), consensus_params, deployment_id, versionbitscache), ThresholdState::STARTED); BOOST_CHECK_EQUAL(g_versionbitscache.State(::ChainActive().Tip(), consensus_params, deployment_id), ThresholdState::STARTED);
} }
} }
@ -67,7 +69,7 @@ struct TestChainDATSetup : public TestChainSetup
{ {
LOCK(cs_main); LOCK(cs_main);
BOOST_CHECK_EQUAL(::ChainActive().Height(), window - 2); BOOST_CHECK_EQUAL(::ChainActive().Height(), window - 2);
BOOST_CHECK_EQUAL(VersionBitsState(::ChainActive().Tip(), consensus_params, deployment_id, versionbitscache), ThresholdState::DEFINED); BOOST_CHECK_EQUAL(g_versionbitscache.State(::ChainActive().Tip(), consensus_params, deployment_id), ThresholdState::DEFINED);
} }
CreateAndProcessBlock({}, coinbaseKey); CreateAndProcessBlock({}, coinbaseKey);
@ -76,8 +78,8 @@ struct TestChainDATSetup : public TestChainSetup
LOCK(cs_main); LOCK(cs_main);
// Advance from DEFINED to STARTED at height = window - 1 // Advance from DEFINED to STARTED at height = window - 1
BOOST_CHECK_EQUAL(::ChainActive().Height(), window - 1); BOOST_CHECK_EQUAL(::ChainActive().Height(), window - 1);
BOOST_CHECK_EQUAL(VersionBitsState(::ChainActive().Tip(), consensus_params, deployment_id, versionbitscache), ThresholdState::STARTED); BOOST_CHECK_EQUAL(g_versionbitscache.State(::ChainActive().Tip(), consensus_params, deployment_id), ThresholdState::STARTED);
BOOST_CHECK_EQUAL(VersionBitsStatistics(::ChainActive().Tip(), consensus_params, deployment_id, versionbitscache).threshold, threshold(0)); BOOST_CHECK_EQUAL(g_versionbitscache.Statistics(::ChainActive().Tip(), consensus_params, deployment_id).threshold, threshold(0));
// Next block should be signaling by default // Next block should be signaling by default
const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.llmq_ctx, *m_node.evodb, ::ChainstateActive(), *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.llmq_ctx, *m_node.evodb, ::ChainstateActive(), *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
const uint32_t bitmask = ((uint32_t)1) << consensus_params.vDeployments[deployment_id].bit; const uint32_t bitmask = ((uint32_t)1) << consensus_params.vDeployments[deployment_id].bit;
@ -93,17 +95,17 @@ struct TestChainDATSetup : public TestChainSetup
// Still STARTED but with a (potentially) new threshold // Still STARTED but with a (potentially) new threshold
LOCK(cs_main); LOCK(cs_main);
BOOST_CHECK_EQUAL(::ChainActive().Height(), window * (i + 2) - 1); BOOST_CHECK_EQUAL(::ChainActive().Height(), window * (i + 2) - 1);
BOOST_CHECK_EQUAL(VersionBitsState(::ChainActive().Tip(), consensus_params, deployment_id, versionbitscache), ThresholdState::STARTED); BOOST_CHECK_EQUAL(g_versionbitscache.State(::ChainActive().Tip(), consensus_params, deployment_id), ThresholdState::STARTED);
const auto vbts = VersionBitsStatistics(::ChainActive().Tip(), consensus_params, deployment_id, versionbitscache); const auto vbts = g_versionbitscache.Statistics(::ChainActive().Tip(), consensus_params, deployment_id);
BOOST_CHECK_EQUAL(vbts.threshold, threshold(i + 1)); BOOST_CHECK_EQUAL(vbts.threshold, threshold(i + 1));
BOOST_CHECK(vbts.threshold <= th_start); BOOST_CHECK(vbts.threshold <= th_start);
BOOST_CHECK(vbts.threshold >= th_end); BOOST_CHECK(vbts.threshold >= th_end);
} }
} }
if (LOCK(cs_main); check_activation_at_min) { if (LOCK(cs_main); check_activation_at_min) {
BOOST_CHECK_EQUAL(VersionBitsStatistics(::ChainActive().Tip(), consensus_params, deployment_id, versionbitscache).threshold, th_end); BOOST_CHECK_EQUAL(g_versionbitscache.Statistics(::ChainActive().Tip(), consensus_params, deployment_id).threshold, th_end);
} else { } else {
BOOST_CHECK(VersionBitsStatistics(::ChainActive().Tip(), consensus_params, deployment_id, versionbitscache).threshold > th_end); BOOST_CHECK(g_versionbitscache.Statistics(::ChainActive().Tip(), consensus_params, deployment_id).threshold > th_end);
} }
// activate // activate
@ -113,7 +115,7 @@ struct TestChainDATSetup : public TestChainSetup
} }
{ {
LOCK(cs_main); LOCK(cs_main);
BOOST_CHECK_EQUAL(VersionBitsState(::ChainActive().Tip(), consensus_params, deployment_id, versionbitscache), ThresholdState::ACTIVE); BOOST_CHECK_EQUAL(g_versionbitscache.State(::ChainActive().Tip(), consensus_params, deployment_id), ThresholdState::ACTIVE);
} }
} }

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>
@ -227,7 +228,7 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
const Consensus::Params &mainnetParams = chainParams->GetConsensus(); const Consensus::Params &mainnetParams = chainParams->GetConsensus();
for (int i=0; i<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) { for (int i=0; i<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
uint32_t bitmask = VersionBitsMask(mainnetParams, static_cast<Consensus::DeploymentPos>(i)); uint32_t bitmask = g_versionbitscache.Mask(mainnetParams, static_cast<Consensus::DeploymentPos>(i));
// Make sure that no deployment tries to set an invalid bit. // Make sure that no deployment tries to set an invalid bit.
BOOST_CHECK_EQUAL(bitmask & ~(uint32_t)VERSIONBITS_TOP_MASK, bitmask); BOOST_CHECK_EQUAL(bitmask & ~(uint32_t)VERSIONBITS_TOP_MASK, bitmask);
@ -239,7 +240,7 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
// activated soft fork could be later changed to be earlier to avoid // activated soft fork could be later changed to be earlier to avoid
// overlap.) // overlap.)
for (int j=i+1; j<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; j++) { for (int j=i+1; j<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; j++) {
if (VersionBitsMask(mainnetParams, static_cast<Consensus::DeploymentPos>(j)) == bitmask) { if (g_versionbitscache.Mask(mainnetParams, static_cast<Consensus::DeploymentPos>(j)) == bitmask) {
BOOST_CHECK(mainnetParams.vDeployments[j].nStartTime > mainnetParams.vDeployments[i].nTimeout || BOOST_CHECK(mainnetParams.vDeployments[j].nStartTime > mainnetParams.vDeployments[i].nTimeout ||
mainnetParams.vDeployments[i].nStartTime > mainnetParams.vDeployments[j].nTimeout); mainnetParams.vDeployments[i].nStartTime > mainnetParams.vDeployments[j].nTimeout);
} }
@ -273,29 +274,29 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
// should not be set. // should not be set.
CBlockIndex *lastBlock = nullptr; CBlockIndex *lastBlock = nullptr;
lastBlock = firstChain.Mine(mainnetParams.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); lastBlock = firstChain.Mine(mainnetParams.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0); BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
// Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet. // Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet.
for (uint32_t i = 1; i < mainnetParams.nMinerConfirmationWindow - 4; i++) { for (uint32_t i = 1; i < mainnetParams.nMinerConfirmationWindow - 4; i++) {
lastBlock = firstChain.Mine(mainnetParams.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); lastBlock = firstChain.Mine(mainnetParams.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
// This works because VERSIONBITS_LAST_OLD_BLOCK_VERSION happens // This works because VERSIONBITS_LAST_OLD_BLOCK_VERSION happens
// to be 4, and the bit we're testing happens to be bit 28. // to be 4, and the bit we're testing happens to be bit 28.
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0); BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
} }
// Now mine 5 more blocks at the start time -- MTP should not have passed yet, so // Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
// CBV should still not yet set the bit. // CBV should still not yet set the bit.
nTime = nStartTime; nTime = nStartTime;
for (uint32_t i = mainnetParams.nMinerConfirmationWindow - 4; i <= mainnetParams.nMinerConfirmationWindow; i++) { for (uint32_t i = mainnetParams.nMinerConfirmationWindow - 4; i <= mainnetParams.nMinerConfirmationWindow; i++) {
lastBlock = firstChain.Mine(mainnetParams.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); lastBlock = firstChain.Mine(mainnetParams.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0); BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
} }
// Advance to the next period and transition to STARTED, // Advance to the next period and transition to STARTED,
lastBlock = firstChain.Mine(mainnetParams.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); lastBlock = firstChain.Mine(mainnetParams.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
// so ComputeBlockVersion should now set the bit, // so ComputeBlockVersion should now set the bit,
BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0); BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
// and should also be using the VERSIONBITS_TOP_BITS. // and should also be using the VERSIONBITS_TOP_BITS.
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS); BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
// Check that ComputeBlockVersion will set the bit until nTimeout // Check that ComputeBlockVersion will set the bit until nTimeout
nTime += 600; nTime += 600;
@ -304,8 +305,8 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
// These blocks are all before nTimeout is reached. // These blocks are all before nTimeout is reached.
while (nTime < nTimeout && blocksToMine > 0) { while (nTime < nTimeout && blocksToMine > 0) {
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0); BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS); BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
blocksToMine--; blocksToMine--;
nTime += 600; nTime += 600;
nHeight += 1; nHeight += 1;
@ -316,12 +317,12 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
// the bit until the period transition. // the bit until the period transition.
for (uint32_t i = 0; i < mainnetParams.nMinerConfirmationWindow - 1; i++) { for (uint32_t i = 0; i < mainnetParams.nMinerConfirmationWindow - 1; i++) {
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0); BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
nHeight += 1; nHeight += 1;
} }
// The next block should trigger no longer setting the bit. // The next block should trigger no longer setting the bit.
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0); BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
// On a new chain: // On a new chain:
// verify that the bit will be set after lock-in, and then stop being set // verify that the bit will be set after lock-in, and then stop being set
@ -331,24 +332,24 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
// Mine one period worth of blocks, and check that the bit will be on for the // Mine one period worth of blocks, and check that the bit will be on for the
// next period. // next period.
lastBlock = secondChain.Mine(mainnetParams.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); lastBlock = secondChain.Mine(mainnetParams.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0); BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
// Mine another period worth of blocks, signaling the new bit. // Mine another period worth of blocks, signaling the new bit.
lastBlock = secondChain.Mine(mainnetParams.nMinerConfirmationWindow * 2, nTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip(); lastBlock = secondChain.Mine(mainnetParams.nMinerConfirmationWindow * 2, nTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip();
// After one period of setting the bit on each block, it should have locked in. // After one period of setting the bit on each block, it should have locked in.
// We keep setting the bit for one more period though, until activation. // We keep setting the bit for one more period though, until activation.
BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0); BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
// Now check that we keep mining the block until the end of this period, and // Now check that we keep mining the block until the end of this period, and
// then stop at the beginning of the next period. // then stop at the beginning of the next period.
lastBlock = secondChain.Mine((mainnetParams.nMinerConfirmationWindow * 3) - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); lastBlock = secondChain.Mine((mainnetParams.nMinerConfirmationWindow * 3) - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1 << bit)) != 0); BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & (1 << bit)) != 0);
lastBlock = secondChain.Mine(mainnetParams.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); lastBlock = secondChain.Mine(mainnetParams.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0); BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
// Finally, verify that after a soft fork has activated, CBV no longer uses // Finally, verify that after a soft fork has activated, CBV no longer uses
// VERSIONBITS_LAST_OLD_BLOCK_VERSION. // VERSIONBITS_LAST_OLD_BLOCK_VERSION.
//BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS); //BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
} }

View File

@ -16,6 +16,7 @@
#include <consensus/tx_verify.h> #include <consensus/tx_verify.h>
#include <consensus/validation.h> #include <consensus/validation.h>
#include <cuckoocache.h> #include <cuckoocache.h>
#include <deploymentstatus.h>
#include <flatfile.h> #include <flatfile.h>
#include <hash.h> #include <hash.h>
#include <index/blockfilterindex.h> #include <index/blockfilterindex.h>
@ -157,6 +158,7 @@ bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED;
uint64_t nPruneTarget = 0; uint64_t nPruneTarget = 0;
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
// TODO: drop this global variable
std::atomic<bool> fDIP0001ActiveAtTip{false}; std::atomic<bool> fDIP0001ActiveAtTip{false};
uint256 hashAssumeValid; uint256 hashAssumeValid;
@ -1923,24 +1925,6 @@ void StopScriptCheckWorkerThreads()
scriptcheckqueue.StopWorkerThreads(); 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++) {
Consensus::DeploymentPos pos = Consensus::DeploymentPos(i);
ThresholdState state = VersionBitsState(pindexPrev, params, pos, versionbitscache);
if (state == ThresholdState::LOCKED_IN || state == ThresholdState::STARTED) {
nVersion |= VersionBitsMask(params, static_cast<Consensus::DeploymentPos>(i));
}
}
return nVersion;
}
bool GetBlockHash(uint256& hashRet, int nBlockHeight) bool GetBlockHash(uint256& hashRet, int nBlockHeight)
{ {
LOCK(cs_main); LOCK(cs_main);
@ -1973,15 +1957,14 @@ public:
return pindex->nHeight >= params.MinBIP9WarningHeight && return pindex->nHeight >= params.MinBIP9WarningHeight &&
((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && ((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) &&
((pindex->nVersion >> bit) & 1) != 0 && ((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); static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS] GUARDED_BY(cs_main);
static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& consensusparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& consensusparams)
AssertLockHeld(cs_main); {
unsigned int flags = SCRIPT_VERIFY_NONE; unsigned int flags = SCRIPT_VERIFY_NONE;
// Start enforcing P2SH (BIP16) // Start enforcing P2SH (BIP16)
@ -1989,27 +1972,28 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consens
flags |= SCRIPT_VERIFY_P2SH; flags |= SCRIPT_VERIFY_P2SH;
} }
// Start enforcing the DERSIG (BIP66) rule // Enforce the DERSIG (BIP66) rule
if (pindex->nHeight >= consensusparams.BIP66Height) { if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_DERSIG)) {
flags |= SCRIPT_VERIFY_DERSIG; flags |= SCRIPT_VERIFY_DERSIG;
} }
// Start enforcing CHECKLOCKTIMEVERIFY (BIP65) rule // Enforce CHECKLOCKTIMEVERIFY (BIP65)
if (pindex->nHeight >= consensusparams.BIP65Height) { if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_CLTV)) {
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
} }
// Start enforcing BIP112 (CHECKSEQUENCEVERIFY) // Enforce CHECKSEQUENCEVERIFY (BIP112)
if (pindex->nHeight >= consensusparams.CSVHeight) { if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_CSV)) {
flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
} }
// Start enforcing BIP147 (NULLDUMMY) rule using versionbits logic. // Enforce BIP147 NULLDUMMY
if (pindex->nHeight >= consensusparams.BIP147Height) { if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_BIP147)) {
flags |= SCRIPT_VERIFY_NULLDUMMY; flags |= SCRIPT_VERIFY_NULLDUMMY;
} }
if (pindex->nHeight >= consensusparams.DIP0020Height) { // Enforce DIP0020
if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_DIP0020)) {
flags |= SCRIPT_ENABLE_DIP0020_OPCODES; flags |= SCRIPT_ENABLE_DIP0020_OPCODES;
} }
@ -2184,9 +2168,9 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
} }
/// END DASH /// END DASH
// Start enforcing BIP68 (sequence locks) // Enforce BIP68 (sequence locks)
int nLockTimeFlags = 0; int nLockTimeFlags = 0;
if (pindex->nHeight >= m_params.GetConsensus().CSVHeight) { if (DeploymentActiveAt(*pindex, m_params.GetConsensus(), Consensus::DEPLOYMENT_CSV)) {
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE; nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
} }
@ -3926,12 +3910,13 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
if (block.GetBlockTime() > nAdjustedTime + MAX_FUTURE_BLOCK_TIME) if (block.GetBlockTime() > nAdjustedTime + MAX_FUTURE_BLOCK_TIME)
return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", strprintf("block timestamp too far in the future %d %d", block.GetBlockTime(), nAdjustedTime + 2 * 60 * 60)); return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", strprintf("block timestamp too far in the future %d %d", block.GetBlockTime(), nAdjustedTime + 2 * 60 * 60));
// check for version 2, 3 and 4 upgrades // Reject blocks with outdated version
if((block.nVersion < 2 && nHeight >= consensusParams.BIP34Height) || if ((block.nVersion < 2 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB)) ||
(block.nVersion < 3 && nHeight >= consensusParams.BIP66Height) || (block.nVersion < 3 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_DERSIG)) ||
(block.nVersion < 4 && nHeight >= consensusParams.BIP65Height)) (block.nVersion < 4 && DeploymentActiveAfter(pindexPrev, consensusParams, 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));
}
return true; return true;
} }
@ -3947,9 +3932,9 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1; const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
// Start enforcing BIP113 (Median Time Past). // Enforce BIP113 (Median Time Past).
int nLockTimeFlags = 0; int nLockTimeFlags = 0;
if (nHeight >= consensusParams.CSVHeight) { if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CSV)) {
assert(pindexPrev != nullptr); assert(pindexPrev != nullptr);
nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST; nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST;
} }
@ -3991,7 +3976,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
// After DIP3/DIP4 activation, we don't enforce the height in the input script anymore. // After DIP3/DIP4 activation, we don't enforce the height in the input script anymore.
// The CbTx special transaction payload will then contain the height, which is checked in CheckCbTx // The CbTx special transaction payload will then contain the height, which is checked in CheckCbTx
if (nHeight >= consensusParams.BIP34Height && !fDIP0003Active_context) if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB) && !fDIP0003Active_context)
{ {
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() ||
@ -5041,7 +5026,7 @@ void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman)
nLastBlockFile = 0; nLastBlockFile = 0;
setDirtyBlockIndex.clear(); setDirtyBlockIndex.clear();
setDirtyFileInfo.clear(); setDirtyFileInfo.clear();
versionbitscache.Clear(); g_versionbitscache.Clear();
for (int b = 0; b < VERSIONBITS_NUM_BITS; b++) { for (int b = 0; b < VERSIONBITS_NUM_BITS; b++) {
warningcache[b].clear(); warningcache[b].clear();
} }

View File

@ -23,7 +23,6 @@
#include <sync.h> #include <sync.h>
#include <txdb.h> #include <txdb.h>
#include <txmempool.h> // For CTxMemPool::cs #include <txmempool.h> // For CTxMemPool::cs
#include <versionbits.h>
#include <serialize.h> #include <serialize.h>
#include <spentindex.h> #include <spentindex.h>
#include <util/hasher.h> #include <util/hasher.h>
@ -1071,12 +1070,6 @@ CChain& ChainActive();
/** 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.
*/
int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params);
/** /**
* Return true if hash can be found in ::ChainActive() at nBlockHeight height. * Return true if hash can be found in ::ChainActive() at nBlockHeight height.

View File

@ -249,30 +249,50 @@ public:
} // namespace } // namespace
ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache) ThresholdState VersionBitsCache::State(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
{ {
return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]); LOCK(m_mutex);
return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, m_caches[pos]);
} }
BIP9Stats VersionBitsStatistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache) BIP9Stats VersionBitsCache::Statistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
{ {
return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindexPrev, params, cache.caches[pos]); LOCK(m_mutex);
return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindexPrev, params, m_caches[pos]);
} }
int VersionBitsStateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache) int VersionBitsCache::StateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
{ {
return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, cache.caches[pos]); LOCK(m_mutex);
return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, m_caches[pos]);
} }
uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos) uint32_t VersionBitsCache::Mask(const Consensus::Params& params, Consensus::DeploymentPos pos)
{ {
return VersionBitsConditionChecker(pos).Mask(params); return VersionBitsConditionChecker(pos).Mask(params);
} }
int32_t VersionBitsCache::ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params)
{
LOCK(m_mutex);
int32_t nVersion = VERSIONBITS_TOP_BITS;
for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
Consensus::DeploymentPos pos = static_cast<Consensus::DeploymentPos>(i);
ThresholdState state = VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, m_caches[pos]);
if (state == ThresholdState::LOCKED_IN || state == ThresholdState::STARTED) {
nVersion |= Mask(params, pos);
}
}
return nVersion;
}
void VersionBitsCache::Clear() void VersionBitsCache::Clear()
{ {
LOCK(m_mutex);
for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) { for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) {
caches[d].clear(); m_caches[d].clear();
} }
} }
AbstractEHFManager* AbstractEHFManager::globalInstance{nullptr}; AbstractEHFManager* AbstractEHFManager::globalInstance{nullptr};

View File

@ -6,6 +6,7 @@
#define BITCOIN_VERSIONBITS_H #define BITCOIN_VERSIONBITS_H
#include <chain.h> #include <chain.h>
#include <sync.h>
#include <map> #include <map>
/** What block version to use for new blocks (pre versionbits) */ /** What block version to use for new blocks (pre versionbits) */
@ -71,23 +72,33 @@ public:
int GetStateSinceHeightFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const; int GetStateSinceHeightFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const;
}; };
/** BIP 9 allows multiple softforks to be deployed in parallel. We cache per-period state for every one of them /** BIP 9 allows multiple softforks to be deployed in parallel. We cache
* keyed by the bit position used to signal support. */ * per-period state for every one of them. */
struct VersionBitsCache class VersionBitsCache
{ {
ThresholdConditionCache caches[Consensus::MAX_VERSION_BITS_DEPLOYMENTS]; private:
Mutex m_mutex;
ThresholdConditionCache m_caches[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] GUARDED_BY(m_mutex);
public:
/** Get the numerical statistics for a given deployment for the signalling period that includes the block after pindexPrev. */
BIP9Stats Statistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos);
static uint32_t Mask(const Consensus::Params& params, Consensus::DeploymentPos pos);
/** Get the BIP9 state for a given deployment for the block after pindexPrev. */
ThresholdState State(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos);
/** Get the block height at which the BIP9 deployment switched into the state for the block after pindexPrev. */
int StateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos);
/** Determine what nVersion a new block should use
*/
int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params);
void Clear(); void Clear();
}; };
/** Get the BIP9 state for a given deployment at the current tip. */
ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache);
/** Get the numerical statistics for the BIP9 state for a given deployment at the current tip. */
BIP9Stats VersionBitsStatistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache);
/** Get the block height at which the BIP9 deployment switched into the state for the block building on the current tip. */
int VersionBitsStateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache);
uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos);
class AbstractEHFManager class AbstractEHFManager
{ {
public: public:

View File

@ -1,22 +0,0 @@
// Copyright (c) 2016-2018 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 <versionbitsinfo.h>
#include <consensus/params.h>
const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] = {
{
/*.name =*/ "testdummy",
/*.gbt_force =*/ true,
},
{
/*.name =*/"v20",
/*.gbt_force =*/true,
},
{
/*.name =*/"mn_rr",
/*.gbt_force =*/true,
},
};

View File

@ -1,17 +0,0 @@
// Copyright (c) 2016-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_VERSIONBITSINFO_H
#define BITCOIN_VERSIONBITSINFO_H
struct VBDeploymentInfo {
/** Deployment name */
const char *name;
/** Whether GBT clients can safely ignore this rule in simplified usage */
bool gbt_force;
};
extern const struct VBDeploymentInfo VersionBitsDeploymentInfo[];
#endif // BITCOIN_VERSIONBITSINFO_H