Skip to content

Commit 240cad0

Browse files
committed
rpc: getdeploymentinfo: include signalling info
1 parent 376c0c6 commit 240cad0

File tree

5 files changed

+49
-15
lines changed

5 files changed

+49
-15
lines changed

src/rpc/blockchain.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -1448,7 +1448,8 @@ static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue&
14481448
// BIP9 signalling status, if applicable
14491449
if (has_signal) {
14501450
UniValue statsUV(UniValue::VOBJ);
1451-
BIP9Stats statsStruct = g_versionbitscache.Statistics(active_chain_tip, consensusParams, id);
1451+
std::vector<bool> signals;
1452+
BIP9Stats statsStruct = g_versionbitscache.Statistics(active_chain_tip, consensusParams, id, &signals);
14521453
statsUV.pushKV("period", statsStruct.period);
14531454
statsUV.pushKV("elapsed", statsStruct.elapsed);
14541455
statsUV.pushKV("count", statsStruct.count);
@@ -1457,6 +1458,13 @@ static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue&
14571458
statsUV.pushKV("possible", statsStruct.possible);
14581459
}
14591460
bip9.pushKV("statistics", statsUV);
1461+
1462+
std::string sig;
1463+
sig.reserve(signals.size());
1464+
for (const bool s : signals) {
1465+
sig.push_back(s ? '#' : '-');
1466+
}
1467+
bip9.pushKV("signalling", sig);
14601468
}
14611469

14621470
UniValue rv(UniValue::VOBJ);
@@ -1585,6 +1593,7 @@ const std::vector<RPCResult> RPCHelpForDeployment{
15851593
{RPCResult::Type::NUM, "count", "the number of blocks with the version bit set in the current period"},
15861594
{RPCResult::Type::BOOL, "possible", /*optional=*/true, "returns false if there are not enough blocks left in this period to pass activation threshold (only for \"started\" status)"},
15871595
}},
1596+
{RPCResult::Type::STR, "signalling", "indicates blocks that signalled with a # and blocks that did not with a -"},
15881597
}},
15891598
};
15901599

src/test/fuzz/versionbits.cpp

+14-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class TestConditionChecker : public AbstractThresholdConditionChecker
5151

5252
ThresholdState GetStateFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateFor(pindexPrev, dummy_params, m_cache); }
5353
int GetStateSinceHeightFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateSinceHeightFor(pindexPrev, dummy_params, m_cache); }
54-
BIP9Stats GetStateStatisticsFor(const CBlockIndex* pindex) const { return AbstractThresholdConditionChecker::GetStateStatisticsFor(pindex, dummy_params); }
54+
BIP9Stats GetStateStatisticsFor(const CBlockIndex* pindex, std::vector<bool>* signals=nullptr) const { return AbstractThresholdConditionChecker::GetStateStatisticsFor(pindex, dummy_params, signals); }
5555

5656
bool Condition(int32_t version) const
5757
{
@@ -227,6 +227,7 @@ FUZZ_TARGET_INIT(versionbits, initialize)
227227
last_stats.threshold = threshold;
228228
last_stats.count = last_stats.elapsed = 0;
229229
last_stats.possible = (period >= threshold);
230+
std::vector<bool> last_signals{};
230231

231232
int prev_next_height = (prev == nullptr ? 0 : prev->nHeight + 1);
232233
assert(exp_since <= prev_next_height);
@@ -248,13 +249,24 @@ FUZZ_TARGET_INIT(versionbits, initialize)
248249
assert(since == exp_since);
249250

250251
// check that after mining this block stats change as expected
251-
const BIP9Stats stats = checker.GetStateStatisticsFor(current_block);
252+
std::vector<bool> signals;
253+
const BIP9Stats stats = checker.GetStateStatisticsFor(current_block, &signals);
254+
const BIP9Stats stats_no_signals = checker.GetStateStatisticsFor(current_block);
255+
assert(stats.period == stats_no_signals.period && stats.threshold == stats_no_signals.threshold
256+
&& stats.elapsed == stats_no_signals.elapsed && stats.count == stats_no_signals.count
257+
&& stats.possible == stats_no_signals.possible);
258+
252259
assert(stats.period == period);
253260
assert(stats.threshold == threshold);
254261
assert(stats.elapsed == b);
255262
assert(stats.count == last_stats.count + (signal ? 1 : 0));
256263
assert(stats.possible == (stats.count + period >= stats.elapsed + threshold));
257264
last_stats = stats;
265+
266+
assert(signals.size() == last_signals.size() + 1);
267+
assert(signals.back() == signal);
268+
last_signals.push_back(signal);
269+
assert(signals == last_signals);
258270
}
259271

260272
if (exp_state == ThresholdState::STARTED) {

src/versionbits.cpp

+16-8
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
9898
return state;
9999
}
100100

101-
BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockIndex* pindex, const Consensus::Params& params) const
101+
BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockIndex* pindex, const Consensus::Params& params, std::vector<bool>* signalling_blocks) const
102102
{
103103
BIP9Stats stats = {};
104104

@@ -108,18 +108,26 @@ BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockI
108108
if (pindex == nullptr) return stats;
109109

110110
// Find beginning of period
111-
int start_height = pindex->nHeight - (pindex->nHeight % stats.period);
111+
int blocks_in_period = 1 + (pindex->nHeight % stats.period);
112+
113+
// Reset signalling_blocks
114+
if (signalling_blocks) {
115+
signalling_blocks->assign(blocks_in_period, false);
116+
}
112117

113118
// Count from current block to beginning of period
114119
int elapsed = 0;
115120
int count = 0;
116121
const CBlockIndex* currentIndex = pindex;
117-
for(;;) {
122+
do {
118123
++elapsed;
119-
if (Condition(currentIndex, params)) ++count;
120-
if (currentIndex->nHeight <= start_height) break;
124+
--blocks_in_period;
125+
if (Condition(currentIndex, params)) {
126+
++count;
127+
if (signalling_blocks) signalling_blocks->at(blocks_in_period) = true;
128+
}
121129
currentIndex = currentIndex->pprev;
122-
}
130+
} while(blocks_in_period > 0);
123131

124132
stats.elapsed = elapsed;
125133
stats.count = count;
@@ -197,9 +205,9 @@ ThresholdState VersionBitsCache::State(const CBlockIndex* pindexPrev, const Cons
197205
return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, m_caches[pos]);
198206
}
199207

200-
BIP9Stats VersionBitsCache::Statistics(const CBlockIndex* pindex, const Consensus::Params& params, Consensus::DeploymentPos pos)
208+
BIP9Stats VersionBitsCache::Statistics(const CBlockIndex* pindex, const Consensus::Params& params, Consensus::DeploymentPos pos, std::vector<bool>* signalling_blocks)
201209
{
202-
return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindex, params);
210+
return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindex, params, signalling_blocks);
203211
}
204212

205213
int VersionBitsCache::StateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)

src/versionbits.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,10 @@ class AbstractThresholdConditionChecker {
6464
virtual int Threshold(const Consensus::Params& params) const =0;
6565

6666
public:
67-
/** Returns the numerical statistics of an in-progress BIP9 softfork in the period including pindex */
68-
BIP9Stats GetStateStatisticsFor(const CBlockIndex* pindex, const Consensus::Params& params) const;
67+
/** Returns the numerical statistics of an in-progress BIP9 softfork in the period including pindex
68+
* If provided, signalling_blocks is set to true/false based on whether each block in the period signalled
69+
*/
70+
BIP9Stats GetStateStatisticsFor(const CBlockIndex* pindex, const Consensus::Params& params, std::vector<bool>* signalling_blocks = nullptr) const;
6971
/** Returns the state for pindex A based on parent pindexPrev B. Applies any state transition if conditions are present.
7072
* Caches state from first block of period. */
7173
ThresholdState GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const;
@@ -82,8 +84,10 @@ class VersionBitsCache
8284
ThresholdConditionCache m_caches[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] GUARDED_BY(m_mutex);
8385

8486
public:
85-
/** Get the numerical statistics for a given deployment for the signalling period that includes pindex. */
86-
static BIP9Stats Statistics(const CBlockIndex* pindex, const Consensus::Params& params, Consensus::DeploymentPos pos);
87+
/** Get the numerical statistics for a given deployment for the signalling period that includes pindex.
88+
* If provided, signalling_blocks is set to true/false based on whether each block in the period signalled
89+
*/
90+
static BIP9Stats Statistics(const CBlockIndex* pindex, const Consensus::Params& params, Consensus::DeploymentPos pos, std::vector<bool>* signalling_blocks = nullptr);
8791

8892
static uint32_t Mask(const Consensus::Params& params, Consensus::DeploymentPos pos);
8993

test/functional/rpc_blockchain.py

+1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ def check_signalling_deploymentinfo_result(self, gdi_result, height, blockhash,
202202
'count': height - 143,
203203
'possible': True,
204204
},
205+
'signalling': '#'*(height-143),
205206
},
206207
'active': False
207208
},

0 commit comments

Comments
 (0)