Skip to content

Commit 0ca390d

Browse files
committed
web(version_signaling): surface live latched share_version as ground-truth v36_active
auto_ratchet.state is re-derived in the web layer from sampling math (sampling>=95% => activated). But the node already carries the live ratchet output in m_cached_share_version — the version actually stamped on its new shares. A transient sampling-window dip can drop the derived state back to "voting" while the node has in fact already latched to V36, making the dashboard claim the cross has not happened when it has — a charter #3 truthfulness gap (operators must see the ratchet truthfully). Surface the live latch alongside the derived state in /version_signaling and /v36_status: live_share_version (the real mining version) and v36_active (live_share_version >= 36). Read-only mirror of existing state — no change to the derived state logic, no consensus path touched. The derived state stays as the chain-consensus view; v36_active is the node- local ground truth, and operators can now see both. Non-transition coins (Dash v16) report v36_active=false truthfully. Web-only, non-consensus.
1 parent 69f7ed5 commit 0ca390d

1 file changed

Lines changed: 18 additions & 2 deletions

File tree

src/core/web_server.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6104,9 +6104,17 @@ nlohmann::json MiningInterface::rest_version_signaling(const nlohmann::json* cac
61046104
} else {
61056105
effective_state = "voting";
61066106
}
6107+
// The chain-derived state above can momentarily disagree with what the
6108+
// node is ACTUALLY mining: m_cached_share_version is the live ratchet
6109+
// output (the version stamped on this node's new shares). Surface it as
6110+
// ground truth so a transient sampling dip cannot make the dashboard
6111+
// claim "voting" while the node has already latched to V36 (charter #3).
6112+
int64_t live_share_version = m_cached_share_version;
61076113
result["auto_ratchet"] = {
61086114
{"state", effective_state},
61096115
{"persisted_state", effective_state},
6116+
{"live_share_version", live_share_version},
6117+
{"v36_active", live_share_version >= TARGET_VERSION},
61106118
{"activated_at", nullptr},
61116119
{"activated_height", nullptr},
61126120
{"confirmed_at", nullptr}
@@ -6130,12 +6138,20 @@ nlohmann::json MiningInterface::rest_v36_status()
61306138
nlohmann::json vs = rest_version_signaling();
61316139

61326140
std::string state = "voting";
6133-
if (vs.contains("auto_ratchet") && vs["auto_ratchet"].contains("state"))
6134-
state = vs["auto_ratchet"].value("state", std::string("voting"));
6141+
int64_t live_share_version = m_cached_share_version;
6142+
bool v36_active = live_share_version >= 36;
6143+
if (vs.contains("auto_ratchet")) {
6144+
const auto& ar = vs["auto_ratchet"];
6145+
state = ar.value("state", std::string("voting"));
6146+
live_share_version = ar.value("live_share_version", live_share_version);
6147+
v36_active = ar.value("v36_active", v36_active);
6148+
}
61356149

61366150
result["auto_ratchet"] = {
61376151
{"state", state},
61386152
{"persisted_state", state},
6153+
{"live_share_version", live_share_version},
6154+
{"v36_active", v36_active},
61396155
{"activated_at", nullptr},
61406156
{"activated_height", nullptr},
61416157
{"confirmed_at", nullptr}

0 commit comments

Comments
 (0)