mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
Merge pull request #5740 from knst/bp-versionbits
backport: bitcoin#19438 Introduce deploymentstatus (versionbits improvements)
This commit is contained in:
parent
5e8140d23f
commit
18b580591c
@ -169,6 +169,8 @@ BITCOIN_CORE_H = \
|
||||
cuckoocache.h \
|
||||
ctpl_stl.h \
|
||||
cxxtimer.hpp \
|
||||
deploymentinfo.h \
|
||||
deploymentstatus.h \
|
||||
evo/assetlocktx.h \
|
||||
evo/dmn_types.h \
|
||||
evo/cbtx.h \
|
||||
@ -349,7 +351,6 @@ BITCOIN_CORE_H = \
|
||||
validation.h \
|
||||
validationinterface.h \
|
||||
versionbits.h \
|
||||
versionbitsinfo.h \
|
||||
walletinitinterface.h \
|
||||
wallet/bdb.h \
|
||||
wallet/coincontrol.h \
|
||||
@ -403,6 +404,7 @@ libbitcoin_server_a_SOURCES = \
|
||||
coinjoin/server.cpp \
|
||||
consensus/tx_verify.cpp \
|
||||
dbwrapper.cpp \
|
||||
deploymentstatus.cpp \
|
||||
dsnotificationinterface.cpp \
|
||||
evo/assetlocktx.cpp \
|
||||
evo/cbtx.cpp \
|
||||
@ -696,6 +698,7 @@ libbitcoin_common_a_SOURCES = \
|
||||
compressor.cpp \
|
||||
core_read.cpp \
|
||||
core_write.cpp \
|
||||
deploymentinfo.cpp \
|
||||
key.cpp \
|
||||
key_io.cpp \
|
||||
merkleblock.cpp \
|
||||
@ -715,7 +718,6 @@ libbitcoin_common_a_SOURCES = \
|
||||
script/sign.cpp \
|
||||
script/signingprovider.cpp \
|
||||
script/standard.cpp \
|
||||
versionbitsinfo.cpp \
|
||||
warnings.cpp \
|
||||
$(BITCOIN_CORE_H)
|
||||
|
||||
|
@ -8,12 +8,12 @@
|
||||
|
||||
#include <chainparamsseeds.h>
|
||||
#include <consensus/merkle.h>
|
||||
#include <deploymentinfo.h>
|
||||
#include <llmq/params.h>
|
||||
#include <util/ranges.h>
|
||||
#include <util/system.h>
|
||||
#include <util/underlying.h>
|
||||
#include <versionbits.h>
|
||||
#include <versionbitsinfo.h>
|
||||
|
||||
#include <arith_uint256.h>
|
||||
|
||||
|
@ -14,13 +14,32 @@
|
||||
|
||||
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_V20, // Deployment of EHF, LLMQ Randomness Beacon
|
||||
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
|
||||
};
|
||||
constexpr bool ValidDeployment(DeploymentPos dep) { return DEPLOYMENT_TESTDUMMY <= dep && dep <= DEPLOYMENT_MN_RR; }
|
||||
|
||||
/**
|
||||
* Struct for each individual consensus rule change using BIP9.
|
||||
@ -145,7 +164,39 @@ struct Params {
|
||||
LLMQType llmqTypePlatform{LLMQType::LLMQ_NONE};
|
||||
LLMQType llmqTypeMnhf{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
|
||||
|
||||
#endif // BITCOIN_CONSENSUS_PARAMS_H
|
||||
|
54
src/deploymentinfo.cpp
Normal file
54
src/deploymentinfo.cpp
Normal 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
29
src/deploymentinfo.h
Normal 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
17
src/deploymentstatus.cpp
Normal 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
55
src/deploymentstatus.h
Normal 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
|
@ -3,6 +3,7 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <consensus/validation.h>
|
||||
#include <deploymentstatus.h>
|
||||
#include <evo/mnhftx.h>
|
||||
#include <evo/specialtx.h>
|
||||
#include <llmq/commitment.h>
|
||||
@ -278,10 +279,12 @@ CMNHFManager::Signals CMNHFManager::GetFromCache(const CBlockIndex* const pindex
|
||||
return signals;
|
||||
}
|
||||
}
|
||||
if (VersionBitsState(pindex->pprev, Params().GetConsensus(), Consensus::DEPLOYMENT_V20, versionbitscache) != ThresholdState::ACTIVE) {
|
||||
{
|
||||
LOCK(cs_cache);
|
||||
mnhfCache.insert(blockHash, {});
|
||||
return {};
|
||||
if (ThresholdState::ACTIVE != v20_activation.State(pindex->pprev, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) {
|
||||
mnhfCache.insert(blockHash, {});
|
||||
return {};
|
||||
}
|
||||
}
|
||||
bool ok = m_evoDb.Read(std::make_pair(DB_SIGNALS, blockHash), signals);
|
||||
assert(ok);
|
||||
@ -297,8 +300,10 @@ void CMNHFManager::AddToCache(const Signals& signals, const CBlockIndex* const p
|
||||
LOCK(cs_cache);
|
||||
mnhfCache.insert(blockHash, signals);
|
||||
}
|
||||
if (VersionBitsState(pindex->pprev, Params().GetConsensus(), Consensus::DEPLOYMENT_V20, versionbitscache) != ThresholdState::ACTIVE) {
|
||||
return;
|
||||
assert(pindex != nullptr);
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -102,6 +102,8 @@ private:
|
||||
// versionBit <-> height
|
||||
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:
|
||||
explicit CMNHFManager(CEvoDB& evoDb);
|
||||
~CMNHFManager();
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <util/time.h>
|
||||
#include <util/underlying.h>
|
||||
#include <validation.h>
|
||||
#include <versionbits.h>
|
||||
|
||||
#include <univalue.h>
|
||||
|
||||
|
@ -709,7 +709,7 @@ bool IsV19Active(gsl::not_null<const CBlockIndex*> pindex)
|
||||
bool IsV20Active(gsl::not_null<const CBlockIndex*> pindex)
|
||||
{
|
||||
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)
|
||||
@ -717,19 +717,19 @@ bool IsMNRewardReallocationActive(gsl::not_null<const CBlockIndex*> pindex)
|
||||
if (!IsV20Active(pindex)) return false;
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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()
|
||||
@ -1006,7 +1006,7 @@ bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, const CQuorumMana
|
||||
|
||||
case Consensus::LLMQType::LLMQ_TEST_V17: {
|
||||
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:
|
||||
return pindex->nHeight + 1 >= consensusParams.DIP0020Height;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <consensus/merkle.h>
|
||||
#include <consensus/tx_verify.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <deploymentstatus.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <policy/policy.h>
|
||||
#include <pow.h>
|
||||
@ -132,11 +133,11 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
||||
assert(pindexPrev != nullptr);
|
||||
nHeight = pindexPrev->nHeight + 1;
|
||||
|
||||
bool fDIP0003Active_context = nHeight >= chainparams.GetConsensus().DIP0003Height;
|
||||
bool fDIP0008Active_context = nHeight >= chainparams.GetConsensus().DIP0008Height;
|
||||
bool fDIP0003Active_context = DeploymentActiveAfter(pindexPrev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_DIP0003);
|
||||
bool fDIP0008Active_context = DeploymentActiveAfter(pindexPrev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_DIP0008);
|
||||
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
|
||||
// -blockversion=N to test forking scenarios
|
||||
if (Params().NetworkIDString() != CBaseChainParams::MAIN)
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <banman.h>
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <deploymentstatus.h>
|
||||
#include <evo/deterministicmns.h>
|
||||
#include <governance/governance.h>
|
||||
#include <governance/object.h>
|
||||
|
@ -12,7 +12,10 @@
|
||||
#include <chainparams.h>
|
||||
#include <coins.h>
|
||||
#include <core_io.h>
|
||||
#include <consensus/params.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <deploymentinfo.h>
|
||||
#include <deploymentstatus.h>
|
||||
#include <index/blockfilterindex.h>
|
||||
#include <index/coinstatsindex.h>
|
||||
#include <index/txindex.h>
|
||||
@ -35,7 +38,7 @@
|
||||
#include <util/system.h>
|
||||
#include <validation.h>
|
||||
#include <validationinterface.h>
|
||||
#include <versionbitsinfo.h>
|
||||
#include <versionbits.h>
|
||||
#include <warnings.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);
|
||||
}
|
||||
|
||||
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.
|
||||
// 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.
|
||||
// Buried deployments with activation height value of
|
||||
// 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);
|
||||
rv.pushKV("type", "buried");
|
||||
// getblockchaininfo reports the softfork as active from when the chain height is
|
||||
// one below the activation height
|
||||
rv.pushKV("active", tip_height + 1 >= softfork_height);
|
||||
rv.pushKV("height", softfork_height);
|
||||
softforks.pushKV(name, rv);
|
||||
rv.pushKV("active", DeploymentActiveAfter(active_chain_tip, params, dep));
|
||||
rv.pushKV("height", params.DeploymentHeight(dep));
|
||||
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.
|
||||
// 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;
|
||||
|
||||
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) {
|
||||
case ThresholdState::DEFINED: bip9.pushKV("status", "defined"); 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()) {
|
||||
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);
|
||||
if (ThresholdState::STARTED == thresholdState)
|
||||
{
|
||||
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("threshold", statsStruct.threshold);
|
||||
statsUV.pushKV("elapsed", statsStruct.elapsed);
|
||||
@ -1642,7 +1645,7 @@ static void BIP9SoftForkDescPushBack(const CBlockIndex* active_chain_tip, const
|
||||
}
|
||||
rv.pushKV("active", ThresholdState::ACTIVE == thresholdState);
|
||||
|
||||
softforks.pushKV(name, rv);
|
||||
softforks.pushKV(DeploymentName(id), rv);
|
||||
}
|
||||
|
||||
UniValue getblockchaininfo(const JSONRPCRequest& request)
|
||||
@ -1743,23 +1746,23 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
|
||||
const Consensus::Params& consensusParams = Params().GetConsensus();
|
||||
UniValue softforks(UniValue::VOBJ);
|
||||
// sorted by activation block
|
||||
BuriedForkDescPushBack(softforks,"bip34", consensusParams.BIP34Height, height);
|
||||
BuriedForkDescPushBack(softforks,"bip66", consensusParams.BIP66Height, height);
|
||||
BuriedForkDescPushBack(softforks,"bip65", consensusParams.BIP65Height, height);
|
||||
BuriedForkDescPushBack(softforks,"bip147", consensusParams.BIP147Height, height);
|
||||
BuriedForkDescPushBack(softforks, "csv", consensusParams.CSVHeight, height);
|
||||
BuriedForkDescPushBack(softforks, "dip0001", consensusParams.DIP0001Height, height);
|
||||
BuriedForkDescPushBack(softforks, "dip0003", consensusParams.DIP0003Height, height);
|
||||
BuriedForkDescPushBack(softforks, "dip0008", consensusParams.DIP0008Height, height);
|
||||
BuriedForkDescPushBack(softforks, "dip0020", consensusParams.DIP0020Height, height);
|
||||
BuriedForkDescPushBack(softforks, "dip0024", consensusParams.DIP0024Height, height);
|
||||
BuriedForkDescPushBack(softforks, "realloc", consensusParams.BRRHeight, height);
|
||||
BuriedForkDescPushBack(softforks, "v19", consensusParams.V19Height, height);
|
||||
BIP9SoftForkDescPushBack(tip, ehfSignals, softforks, "v20", consensusParams, Consensus::DEPLOYMENT_V20);
|
||||
BIP9SoftForkDescPushBack(tip, ehfSignals, softforks, "mn_rr", consensusParams, Consensus::DEPLOYMENT_MN_RR);
|
||||
BIP9SoftForkDescPushBack(tip, ehfSignals, softforks, "testdummy", consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
|
||||
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB);
|
||||
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DERSIG);
|
||||
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_CLTV);
|
||||
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_BIP147);
|
||||
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_CSV);
|
||||
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DIP0001);
|
||||
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DIP0003);
|
||||
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DIP0008);
|
||||
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DIP0020);
|
||||
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DIP0024);
|
||||
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_BRR);
|
||||
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_V19);
|
||||
SoftForkDescPushBack(tip, ehfSignals, softforks, consensusParams, Consensus::DEPLOYMENT_V20);
|
||||
SoftForkDescPushBack(tip, ehfSignals, softforks, consensusParams, Consensus::DEPLOYMENT_MN_RR);
|
||||
SoftForkDescPushBack(tip, ehfSignals, softforks, consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
|
||||
|
||||
obj.pushKV("softforks", softforks);
|
||||
obj.pushKV("softforks", softforks);
|
||||
|
||||
obj.pushKV("warnings", GetWarnings(false));
|
||||
return obj;
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <consensus/params.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <core_io.h>
|
||||
#include <deploymentinfo.h>
|
||||
#include <deploymentstatus.h>
|
||||
#include <key_io.h>
|
||||
#include <llmq/blockprocessor.h>
|
||||
#include <llmq/context.h>
|
||||
@ -39,7 +41,6 @@
|
||||
#include <util/system.h>
|
||||
#include <validation.h>
|
||||
#include <validationinterface.h>
|
||||
#include <versionbitsinfo.h>
|
||||
#include <warnings.h>
|
||||
|
||||
#include <governance/classes.h>
|
||||
@ -851,7 +852,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||
UniValue vbavailable(UniValue::VOBJ);
|
||||
for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
|
||||
Consensus::DeploymentPos pos = Consensus::DeploymentPos(j);
|
||||
ThresholdState state = VersionBitsState(pindexPrev, consensusParams, pos, versionbitscache);
|
||||
ThresholdState state = g_versionbitscache.State(pindexPrev, consensusParams, pos);
|
||||
switch (state) {
|
||||
case ThresholdState::DEFINED:
|
||||
case ThresholdState::FAILED:
|
||||
@ -859,7 +860,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||
break;
|
||||
case ThresholdState::LOCKED_IN:
|
||||
// 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...
|
||||
case ThresholdState::STARTED:
|
||||
{
|
||||
@ -868,7 +869,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||
if (setClientRules.find(vbinfo.name) == setClientRules.end()) {
|
||||
if (!vbinfo.gbt_force) {
|
||||
// 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;
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <deploymentstatus.h>
|
||||
#include <evo/evodb.h>
|
||||
#include <governance/governance.h>
|
||||
#include <llmq/blockprocessor.h>
|
||||
@ -16,6 +17,7 @@
|
||||
#include <script/interpreter.h>
|
||||
#include <spork.h>
|
||||
#include <validation.h>
|
||||
#include <versionbits.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@ -53,9 +55,9 @@ struct TestChainDATSetup : public TestChainSetup
|
||||
}
|
||||
LOCK(cs_main);
|
||||
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 {
|
||||
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);
|
||||
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);
|
||||
@ -76,8 +78,8 @@ struct TestChainDATSetup : public TestChainSetup
|
||||
LOCK(cs_main);
|
||||
// Advance from DEFINED to STARTED at 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(VersionBitsStatistics(::ChainActive().Tip(), consensus_params, deployment_id, versionbitscache).threshold, threshold(0));
|
||||
BOOST_CHECK_EQUAL(g_versionbitscache.State(::ChainActive().Tip(), consensus_params, deployment_id), ThresholdState::STARTED);
|
||||
BOOST_CHECK_EQUAL(g_versionbitscache.Statistics(::ChainActive().Tip(), consensus_params, deployment_id).threshold, threshold(0));
|
||||
// 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 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
|
||||
LOCK(cs_main);
|
||||
BOOST_CHECK_EQUAL(::ChainActive().Height(), window * (i + 2) - 1);
|
||||
BOOST_CHECK_EQUAL(VersionBitsState(::ChainActive().Tip(), consensus_params, deployment_id, versionbitscache), ThresholdState::STARTED);
|
||||
const auto vbts = VersionBitsStatistics(::ChainActive().Tip(), consensus_params, deployment_id, versionbitscache);
|
||||
BOOST_CHECK_EQUAL(g_versionbitscache.State(::ChainActive().Tip(), consensus_params, deployment_id), ThresholdState::STARTED);
|
||||
const auto vbts = g_versionbitscache.Statistics(::ChainActive().Tip(), consensus_params, deployment_id);
|
||||
BOOST_CHECK_EQUAL(vbts.threshold, threshold(i + 1));
|
||||
BOOST_CHECK(vbts.threshold <= th_start);
|
||||
BOOST_CHECK(vbts.threshold >= th_end);
|
||||
}
|
||||
}
|
||||
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 {
|
||||
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
|
||||
@ -113,7 +115,7 @@ struct TestChainDATSetup : public TestChainSetup
|
||||
}
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <consensus/params.h>
|
||||
#include <deploymentstatus.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <validation.h>
|
||||
#include <versionbits.h>
|
||||
@ -227,7 +228,7 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
|
||||
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
|
||||
const Consensus::Params &mainnetParams = chainParams->GetConsensus();
|
||||
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.
|
||||
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
|
||||
// overlap.)
|
||||
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 ||
|
||||
mainnetParams.vDeployments[i].nStartTime > mainnetParams.vDeployments[j].nTimeout);
|
||||
}
|
||||
@ -273,29 +274,29 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
|
||||
// should not be set.
|
||||
CBlockIndex *lastBlock = nullptr;
|
||||
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.
|
||||
for (uint32_t i = 1; i < mainnetParams.nMinerConfirmationWindow - 4; i++) {
|
||||
lastBlock = firstChain.Mine(mainnetParams.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||
// This works because VERSIONBITS_LAST_OLD_BLOCK_VERSION happens
|
||||
// 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
|
||||
// CBV should still not yet set the bit.
|
||||
nTime = nStartTime;
|
||||
for (uint32_t i = mainnetParams.nMinerConfirmationWindow - 4; i <= mainnetParams.nMinerConfirmationWindow; i++) {
|
||||
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,
|
||||
lastBlock = firstChain.Mine(mainnetParams.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||
// 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.
|
||||
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
|
||||
nTime += 600;
|
||||
@ -304,8 +305,8 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
|
||||
// These blocks are all before nTimeout is reached.
|
||||
while (nTime < nTimeout && blocksToMine > 0) {
|
||||
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||
BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
|
||||
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
|
||||
BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
|
||||
BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
|
||||
blocksToMine--;
|
||||
nTime += 600;
|
||||
nHeight += 1;
|
||||
@ -316,12 +317,12 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
|
||||
// the bit until the period transition.
|
||||
for (uint32_t i = 0; i < mainnetParams.nMinerConfirmationWindow - 1; i++) {
|
||||
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;
|
||||
}
|
||||
// The next block should trigger no longer setting the bit.
|
||||
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:
|
||||
// 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
|
||||
// next period.
|
||||
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.
|
||||
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.
|
||||
// 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
|
||||
// then stop at the beginning of the next period.
|
||||
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();
|
||||
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
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,6 +16,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>
|
||||
@ -157,6 +158,7 @@ bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED;
|
||||
uint64_t nPruneTarget = 0;
|
||||
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
|
||||
|
||||
// TODO: drop this global variable
|
||||
std::atomic<bool> fDIP0001ActiveAtTip{false};
|
||||
|
||||
uint256 hashAssumeValid;
|
||||
@ -1923,24 +1925,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++) {
|
||||
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)
|
||||
{
|
||||
LOCK(cs_main);
|
||||
@ -1973,15 +1957,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);
|
||||
|
||||
static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& consensusparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& consensusparams)
|
||||
{
|
||||
unsigned int flags = SCRIPT_VERIFY_NONE;
|
||||
|
||||
// Start enforcing P2SH (BIP16)
|
||||
@ -1989,27 +1972,28 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consens
|
||||
flags |= SCRIPT_VERIFY_P2SH;
|
||||
}
|
||||
|
||||
// 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 BIP147 (NULLDUMMY) rule using versionbits logic.
|
||||
if (pindex->nHeight >= consensusparams.BIP147Height) {
|
||||
// Enforce BIP147 NULLDUMMY
|
||||
if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_BIP147)) {
|
||||
flags |= SCRIPT_VERIFY_NULLDUMMY;
|
||||
}
|
||||
|
||||
if (pindex->nHeight >= consensusparams.DIP0020Height) {
|
||||
// Enforce DIP0020
|
||||
if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_DIP0020)) {
|
||||
flags |= SCRIPT_ENABLE_DIP0020_OPCODES;
|
||||
}
|
||||
|
||||
@ -2184,9 +2168,9 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
||||
}
|
||||
/// END DASH
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -3926,12 +3910,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", strprintf("block timestamp too far in the future %d %d", block.GetBlockTime(), nAdjustedTime + 2 * 60 * 60));
|
||||
|
||||
// check for version 2, 3 and 4 upgrades
|
||||
if((block.nVersion < 2 && nHeight >= consensusParams.BIP34Height) ||
|
||||
(block.nVersion < 3 && nHeight >= consensusParams.BIP66Height) ||
|
||||
(block.nVersion < 4 && nHeight >= consensusParams.BIP65Height))
|
||||
// Reject blocks with outdated version
|
||||
if ((block.nVersion < 2 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB)) ||
|
||||
(block.nVersion < 3 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_DERSIG)) ||
|
||||
(block.nVersion < 4 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CLTV))) {
|
||||
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, strprintf("bad-version(0x%08x)", block.nVersion),
|
||||
strprintf("rejected nVersion=0x%08x block", block.nVersion));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -3947,9 +3932,9 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
|
||||
AssertLockHeld(cs_main);
|
||||
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;
|
||||
}
|
||||
@ -3991,7 +3976,7 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
|
||||
// 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.
|
||||
// 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;
|
||||
if (block.vtx[0]->vin[0].scriptSig.size() < expect.size() ||
|
||||
@ -5041,7 +5026,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();
|
||||
}
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include <sync.h>
|
||||
#include <txdb.h>
|
||||
#include <txmempool.h> // For CTxMemPool::cs
|
||||
#include <versionbits.h>
|
||||
#include <serialize.h>
|
||||
#include <spentindex.h>
|
||||
#include <util/hasher.h>
|
||||
@ -1071,12 +1070,6 @@ CChain& ChainActive();
|
||||
/** Global variable that points to the active block tree (protected by cs_main) */
|
||||
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.
|
||||
|
@ -249,30 +249,50 @@ public:
|
||||
|
||||
} // 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);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
LOCK(m_mutex);
|
||||
for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) {
|
||||
caches[d].clear();
|
||||
m_caches[d].clear();
|
||||
}
|
||||
}
|
||||
AbstractEHFManager* AbstractEHFManager::globalInstance{nullptr};
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define BITCOIN_VERSIONBITS_H
|
||||
|
||||
#include <chain.h>
|
||||
#include <sync.h>
|
||||
#include <map>
|
||||
|
||||
/** 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;
|
||||
};
|
||||
|
||||
/** BIP 9 allows multiple softforks to be deployed in parallel. We cache per-period state for every one of them
|
||||
* keyed by the bit position used to signal support. */
|
||||
struct VersionBitsCache
|
||||
/** BIP 9 allows multiple softforks to be deployed in parallel. We cache
|
||||
* per-period state for every one of them. */
|
||||
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();
|
||||
};
|
||||
|
||||
/** 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
|
||||
{
|
||||
public:
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
@ -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
|
Loading…
Reference in New Issue
Block a user