Skip to content

Commit

Permalink
Show BIP9 progress in getblockchaininfo (bitcoin#2435)
Browse files Browse the repository at this point in the history
* Implement VersionBitsCountBlocksInWindow

This gives the count of blocks that voted for the given BIP9 deployment

* Add additional information to BIP9 softforks returned by getblockchaininfo

* make sure progress doesn't exceed 1
  • Loading branch information
codablock authored and UdjinM6 committed Nov 12, 2018
1 parent 46462d6 commit 3685c85
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,16 @@ static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Conse
if (THRESHOLD_STARTED == thresholdState)
{
rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit));

int nBlockCount = VersionBitsCountBlocksInWindow(chainActive.Tip(), consensusParams, id);
int64_t nPeriod = consensusParams.vDeployments[id].nWindowSize ? consensusParams.vDeployments[id].nWindowSize : consensusParams.nMinerConfirmationWindow;
int64_t nThreshold = consensusParams.vDeployments[id].nThreshold ? consensusParams.vDeployments[id].nThreshold : consensusParams.nRuleChangeActivationThreshold;
int64_t nWindowStart = chainActive.Height() - (chainActive.Height() % nPeriod);
rv.push_back(Pair("period", nPeriod));
rv.push_back(Pair("threshold", nThreshold));
rv.push_back(Pair("windowStart", nWindowStart));
rv.push_back(Pair("windowBlocks", nBlockCount));
rv.push_back(Pair("windowProgress", std::min(1.0, (double)nBlockCount / nThreshold)));
}
rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime));
rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout));
Expand Down Expand Up @@ -1252,6 +1262,11 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
" \"xxxx\" : { (string) name of the softfork\n"
" \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n"
" \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n"
" \"period\": xx, (numeric) the window size/period for this softfork (only for \"started\" status)\n"
" \"threshold\": xx, (numeric) the threshold for this softfork (only for \"started\" status)\n"
" \"windowStart\": xx, (numeric) the starting block height of the current window (only for \"started\" status)\n"
" \"windowBlocks\": xx, (numeric) the number of blocks in the current window that had the version bit set for this softfork (only for \"started\" status)\n"
" \"windowProgress\": xx, (numeric) the progress (between 0 and 1) for activation of this softfork (only for \"started\" status)\n"
" \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
" \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
" \"since\": xx (numeric) height of the first block to which the status applies\n"
Expand Down
20 changes: 20 additions & 0 deletions src/versionbits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,21 @@ int AbstractThresholdConditionChecker::GetStateSinceHeightFor(const CBlockIndex*
return pindexPrev->nHeight + 1;
}

int AbstractThresholdConditionChecker::CountBlocksInWindow(const CBlockIndex* pindex, const Consensus::Params& params) const
{
int nPeriod = Period(params);
int nStopHeight = pindex->nHeight - (pindex->nHeight % nPeriod) - 1;
const CBlockIndex* pindexCount = pindex;
int count = 0;
while (pindexCount && pindexCount->nHeight != nStopHeight) {
if (Condition(pindexCount, params)) {
count++;
}
pindexCount = pindexCount->pprev;
}
return count;
}

namespace
{
/**
Expand Down Expand Up @@ -185,6 +200,11 @@ int VersionBitsStateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::
return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, cache.caches[pos]);
}

int VersionBitsCountBlocksInWindow(const CBlockIndex* pindex, const Consensus::Params& params, Consensus::DeploymentPos pos)
{
return VersionBitsConditionChecker(pos).CountBlocksInWindow(pindex, params);
}

uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos)
{
return VersionBitsConditionChecker(pos).Mask(params);
Expand Down
2 changes: 2 additions & 0 deletions src/versionbits.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class AbstractThresholdConditionChecker {
// Note that the functions below take a pindexPrev as input: they compute information for block B based on its parent.
ThresholdState GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const;
int GetStateSinceHeightFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const;
int CountBlocksInWindow(const CBlockIndex* pindex, const Consensus::Params& params) const;
};

struct VersionBitsCache
Expand All @@ -67,6 +68,7 @@ struct VersionBitsCache

ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache);
int VersionBitsStateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache);
int VersionBitsCountBlocksInWindow(const CBlockIndex* pindex, const Consensus::Params& params, Consensus::DeploymentPos pos);
uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos);

#endif

0 comments on commit 3685c85

Please sign in to comment.