mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-08 10:31:50 -05:00
[refactor] versionbits: make VersionBitsCache a full class
Moves the VersionBits* functions to be methods of the cache class, and makes the cache and its lock private to the class.
This commit is contained in:
parent
8ee3e0bed5
commit
0cfd6c6a8f
7 changed files with 39 additions and 34 deletions
|
@ -23,7 +23,7 @@ inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus
|
||||||
inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos dep)
|
inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos dep)
|
||||||
{
|
{
|
||||||
assert(Consensus::ValidDeployment(dep));
|
assert(Consensus::ValidDeployment(dep));
|
||||||
return ThresholdState::ACTIVE == VersionBitsState(pindexPrev, params, dep, g_versionbitscache);
|
return ThresholdState::ACTIVE == g_versionbitscache.State(pindexPrev, params, dep);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Determine if a deployment is active for this block */
|
/** Determine if a deployment is active for this block */
|
||||||
|
|
|
@ -1372,7 +1372,7 @@ static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue&
|
||||||
if (consensusParams.vDeployments[id].nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) return;
|
if (consensusParams.vDeployments[id].nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) return;
|
||||||
|
|
||||||
UniValue bip9(UniValue::VOBJ);
|
UniValue bip9(UniValue::VOBJ);
|
||||||
const ThresholdState thresholdState = VersionBitsState(active_chain_tip, consensusParams, id, g_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;
|
||||||
|
@ -1386,12 +1386,12 @@ static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue&
|
||||||
}
|
}
|
||||||
bip9.pushKV("start_time", consensusParams.vDeployments[id].nStartTime);
|
bip9.pushKV("start_time", consensusParams.vDeployments[id].nStartTime);
|
||||||
bip9.pushKV("timeout", consensusParams.vDeployments[id].nTimeout);
|
bip9.pushKV("timeout", consensusParams.vDeployments[id].nTimeout);
|
||||||
int64_t since_height = VersionBitsStateSinceHeight(active_chain_tip, consensusParams, id, g_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);
|
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);
|
||||||
|
|
|
@ -841,7 +841,7 @@ static RPCHelpMan getblocktemplate()
|
||||||
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, g_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:
|
||||||
|
@ -849,7 +849,7 @@ static RPCHelpMan getblocktemplate()
|
||||||
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:
|
||||||
{
|
{
|
||||||
|
@ -858,7 +858,7 @@ static RPCHelpMan getblocktemplate()
|
||||||
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;
|
||||||
|
|
|
@ -288,7 +288,7 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
|
||||||
// Check min_activation_height is on a retarget boundary
|
// Check min_activation_height is on a retarget boundary
|
||||||
BOOST_REQUIRE_EQUAL(min_activation_height % params.nMinerConfirmationWindow, 0U);
|
BOOST_REQUIRE_EQUAL(min_activation_height % params.nMinerConfirmationWindow, 0U);
|
||||||
|
|
||||||
const uint32_t bitmask{VersionBitsMask(params, dep)};
|
const uint32_t bitmask{g_versionbitscache.Mask(params, dep)};
|
||||||
BOOST_CHECK_EQUAL(bitmask, uint32_t{1} << bit);
|
BOOST_CHECK_EQUAL(bitmask, uint32_t{1} << bit);
|
||||||
|
|
||||||
// In the first chain, test that the bit is set by CBV until it has failed.
|
// In the first chain, test that the bit is set by CBV until it has failed.
|
||||||
|
@ -426,7 +426,7 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
|
||||||
// not take precedence over STARTED/LOCKED_IN. So all softforks on
|
// not take precedence over STARTED/LOCKED_IN. So all softforks on
|
||||||
// the same bit might overlap, even when non-overlapping start-end
|
// the same bit might overlap, even when non-overlapping start-end
|
||||||
// times are picked.
|
// times are picked.
|
||||||
const uint32_t dep_mask{VersionBitsMask(chainParams->GetConsensus(), dep)};
|
const uint32_t dep_mask{g_versionbitscache.Mask(chainParams->GetConsensus(), dep)};
|
||||||
BOOST_CHECK(!(chain_all_vbits & dep_mask));
|
BOOST_CHECK(!(chain_all_vbits & dep_mask));
|
||||||
chain_all_vbits |= dep_mask;
|
chain_all_vbits |= dep_mask;
|
||||||
check_computeblockversion(chainParams->GetConsensus(), dep);
|
check_computeblockversion(chainParams->GetConsensus(), dep);
|
||||||
|
|
|
@ -1611,9 +1611,9 @@ int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Para
|
||||||
int32_t nVersion = VERSIONBITS_TOP_BITS;
|
int32_t nVersion = VERSIONBITS_TOP_BITS;
|
||||||
|
|
||||||
for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
|
for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
|
||||||
ThresholdState state = VersionBitsState(pindexPrev, params, static_cast<Consensus::DeploymentPos>(i), g_versionbitscache);
|
ThresholdState state = g_versionbitscache.State(pindexPrev, params, static_cast<Consensus::DeploymentPos>(i));
|
||||||
if (state == ThresholdState::LOCKED_IN || state == ThresholdState::STARTED) {
|
if (state == ThresholdState::LOCKED_IN || state == ThresholdState::STARTED) {
|
||||||
nVersion |= VersionBitsMask(params, static_cast<Consensus::DeploymentPos>(i));
|
nVersion |= g_versionbitscache.Mask(params, static_cast<Consensus::DeploymentPos>(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -190,32 +190,32 @@ 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)
|
||||||
{
|
{
|
||||||
LOCK(cache.mutex);
|
LOCK(m_mutex);
|
||||||
return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]);
|
return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, m_caches[pos]);
|
||||||
}
|
}
|
||||||
|
|
||||||
BIP9Stats VersionBitsStatistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
|
BIP9Stats VersionBitsCache::Statistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
|
||||||
{
|
{
|
||||||
return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindexPrev, params);
|
return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindexPrev, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
LOCK(cache.mutex);
|
LOCK(m_mutex);
|
||||||
return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, cache.caches[pos]);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VersionBitsCache::Clear()
|
void VersionBitsCache::Clear()
|
||||||
{
|
{
|
||||||
LOCK(mutex);
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,22 +73,27 @@ 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
|
||||||
{
|
{
|
||||||
Mutex mutex;
|
private:
|
||||||
ThresholdConditionCache caches[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] GUARDED_BY(mutex);
|
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. */
|
||||||
|
static 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);
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Get the BIP9 state for a given deployment for the block after pindexPrev. */
|
|
||||||
ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache);
|
|
||||||
/** Get the numerical statistics for a given deployment for the signalling period that includes the block after pindexPrev. */
|
|
||||||
BIP9Stats VersionBitsStatistics(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 VersionBitsStateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache);
|
|
||||||
uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos);
|
|
||||||
|
|
||||||
#endif // BITCOIN_VERSIONBITS_H
|
#endif // BITCOIN_VERSIONBITS_H
|
||||||
|
|
Loading…
Add table
Reference in a new issue