Line data Source code
1 : // Copyright (c) 2018-2021 The Dash Core developers
2 : // Copyright (c) 2022 The PIVX Core developers
3 : // Distributed under the MIT/X11 software license, see the accompanying
4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 :
6 : #include "llmq/quorums_debug.h"
7 :
8 : #include "chainparams.h"
9 : #include "evo/deterministicmns.h"
10 : #include "llmq/quorums_utils.h"
11 : #include "utiltime.h"
12 : #include "validation.h"
13 :
14 : namespace llmq
15 : {
16 :
17 : std::unique_ptr<CDKGDebugManager> quorumDKGDebugManager{nullptr};
18 :
19 306 : UniValue CDKGDebugSessionStatus::ToJson(int detailLevel) const
20 : {
21 306 : UniValue ret(UniValue::VOBJ);
22 :
23 918 : if (!Params().GetConsensus().llmqs.count((Consensus::LLMQType)llmqType) || quorumHash.IsNull()) {
24 : return ret;
25 : }
26 :
27 306 : std::vector<CDeterministicMNCPtr> dmnMembers;
28 306 : if (detailLevel == 2) {
29 0 : const CBlockIndex* pindexQuorum = WITH_LOCK(cs_main, return LookupBlockIndex(quorumHash));
30 0 : if (pindexQuorum != nullptr) {
31 0 : dmnMembers = deterministicMNManager->GetAllQuorumMembers((Consensus::LLMQType) llmqType, pindexQuorum);
32 : }
33 : }
34 :
35 306 : ret.pushKV("llmqType", llmqType);
36 612 : ret.pushKV("quorumHash", quorumHash.ToString());
37 306 : ret.pushKV("quorumHeight", (int)quorumHeight);
38 306 : ret.pushKV("phase", (int)phase);
39 :
40 306 : ret.pushKV("sentContributions", sentContributions);
41 306 : ret.pushKV("sentComplaint", sentComplaint);
42 306 : ret.pushKV("sentJustification", sentJustification);
43 306 : ret.pushKV("sentPrematureCommitment", sentPrematureCommitment);
44 306 : ret.pushKV("aborted", aborted);
45 :
46 0 : struct ArrOrCount {
47 : int count{0};
48 : UniValue arr{UniValue::VARR};
49 : };
50 :
51 612 : ArrOrCount badMembers;
52 612 : ArrOrCount weComplain;
53 612 : ArrOrCount receivedContributions;
54 612 : ArrOrCount receivedComplaints;
55 612 : ArrOrCount receivedJustifications;
56 612 : ArrOrCount receivedPrematureCommitments;
57 612 : ArrOrCount complaintsFromMembers;
58 :
59 5814 : auto add = [&](ArrOrCount& v, size_t idx, bool flag) {
60 5508 : if (flag) {
61 1291 : if (detailLevel == 0) {
62 1291 : v.count++;
63 0 : } else if (detailLevel == 1) {
64 0 : v.arr.push_back((int)idx);
65 0 : } else if (detailLevel == 2) {
66 0 : UniValue a(UniValue::VOBJ);
67 0 : a.pushKV("memberIndex", (int)idx);
68 0 : if (idx < dmnMembers.size()) {
69 0 : a.pushKV("proTxHash", dmnMembers[idx]->proTxHash.ToString());
70 : }
71 0 : v.arr.push_back(a);
72 : }
73 : }
74 5508 : };
75 2142 : auto push = [&](ArrOrCount& v, const std::string& name) {
76 1836 : if (detailLevel == 0) {
77 1836 : ret.pushKV(name, v.count);
78 : } else {
79 0 : ret.pushKV(name, v.arr);
80 : }
81 2142 : };
82 :
83 1224 : for (size_t i = 0; i < members.size(); i++) {
84 918 : const auto& m = members[i];
85 918 : add(badMembers, i, m.bad);
86 918 : add(weComplain, i, m.weComplain);
87 918 : add(receivedContributions, i, m.receivedContribution);
88 918 : add(receivedComplaints, i, m.receivedComplaint);
89 918 : add(receivedJustifications, i, m.receivedJustification);
90 918 : add(receivedPrematureCommitments, i, m.receivedPrematureCommitment);
91 : }
92 306 : push(badMembers, "badMembers");
93 306 : push(weComplain, "weComplain");
94 306 : push(receivedContributions, "receivedContributions");
95 306 : push(receivedComplaints, "receivedComplaints");
96 306 : push(receivedJustifications, "receivedJustifications");
97 306 : push(receivedPrematureCommitments, "receivedPrematureCommitments");
98 306 : ret.pushKV("receivedFinalCommitment", receivedFinalCommitment);
99 :
100 306 : if (detailLevel == 2) {
101 0 : UniValue arr(UniValue::VARR);
102 0 : for (const auto& dmn : dmnMembers) {
103 0 : arr.push_back(dmn->proTxHash.ToString());
104 : }
105 0 : ret.pushKV("allMembers", arr);
106 : }
107 :
108 306 : return ret;
109 : }
110 :
111 306 : UniValue CDKGDebugStatus::ToJson(int detailLevel) const
112 : {
113 306 : const Consensus::Params& consensus = Params().GetConsensus();
114 306 : UniValue ret(UniValue::VOBJ);
115 :
116 306 : ret.pushKV("time", nTime);
117 612 : ret.pushKV("timeStr", FormatISO8601DateTime(nTime));
118 306 : UniValue sessionsJson(UniValue::VOBJ);
119 612 : for (const auto& p : sessions) {
120 612 : Optional<Consensus::LLMQParams> opt_params = consensus.GetLLMQParams((Consensus::LLMQType)p.first);
121 306 : if (opt_params == nullopt) {
122 0 : continue;
123 : }
124 612 : sessionsJson.pushKV(opt_params->name, p.second.ToJson(detailLevel));
125 : }
126 306 : ret.pushKV("session", sessionsJson);
127 :
128 306 : return ret;
129 : }
130 :
131 306 : void CDKGDebugManager::GetLocalDebugStatus(llmq::CDKGDebugStatus& ret)
132 : {
133 306 : LOCK(cs);
134 306 : ret = localStatus;
135 306 : }
136 :
137 352 : void CDKGDebugManager::ResetLocalSessionStatus(Consensus::LLMQType llmqType)
138 : {
139 418 : LOCK(cs);
140 :
141 352 : auto it = localStatus.sessions.find(llmqType);
142 352 : if (it == localStatus.sessions.end()) {
143 572 : return;
144 : }
145 :
146 66 : localStatus.sessions.erase(it);
147 66 : localStatus.nTime = GetAdjustedTime();
148 : }
149 :
150 82 : void CDKGDebugManager::InitLocalSessionStatus(Consensus::LLMQType llmqType, const uint256& quorumHash, int quorumHeight)
151 : {
152 82 : LOCK(cs);
153 :
154 82 : auto it = localStatus.sessions.find(llmqType);
155 82 : if (it == localStatus.sessions.end()) {
156 164 : it = localStatus.sessions.emplace(llmqType, CDKGDebugSessionStatus()).first;
157 : }
158 :
159 82 : auto& params = Params().GetConsensus().llmqs.at(llmqType);
160 82 : auto& session = it->second;
161 82 : session.llmqType = llmqType;
162 82 : session.quorumHash = quorumHash;
163 82 : session.quorumHeight = (uint32_t)quorumHeight;
164 82 : session.phase = 0;
165 82 : session.statusBitset = 0;
166 82 : session.members.clear();
167 82 : session.members.resize((size_t)params.size);
168 82 : }
169 :
170 1636 : void CDKGDebugManager::UpdateLocalSessionStatus(Consensus::LLMQType llmqType, std::function<bool(CDKGDebugSessionStatus& status)>&& func)
171 : {
172 1636 : LOCK(cs);
173 :
174 1636 : auto it = localStatus.sessions.find(llmqType);
175 1636 : if (it == localStatus.sessions.end()) {
176 2008 : return;
177 : }
178 :
179 632 : if (func(it->second)) {
180 630 : localStatus.nTime = GetAdjustedTime();
181 : }
182 : }
183 :
184 458 : void CDKGDebugManager::UpdateLocalMemberStatus(Consensus::LLMQType llmqType, size_t memberIdx, std::function<bool(CDKGDebugMemberStatus& status)>&& func)
185 : {
186 916 : LOCK(cs);
187 :
188 458 : auto it = localStatus.sessions.find(llmqType);
189 458 : if (it == localStatus.sessions.end()) {
190 0 : return;
191 : }
192 :
193 458 : if (func(it->second.members.at(memberIdx))) {
194 458 : localStatus.nTime = GetAdjustedTime();
195 : }
196 : }
197 :
198 : } // namespace llmq
|