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 276 : UniValue CDKGDebugSessionStatus::ToJson(int detailLevel) const
20 : {
21 276 : UniValue ret(UniValue::VOBJ);
22 :
23 828 : if (!Params().GetConsensus().llmqs.count((Consensus::LLMQType)llmqType) || quorumHash.IsNull()) {
24 : return ret;
25 : }
26 :
27 276 : std::vector<CDeterministicMNCPtr> dmnMembers;
28 276 : 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 276 : ret.pushKV("llmqType", llmqType);
36 552 : ret.pushKV("quorumHash", quorumHash.ToString());
37 276 : ret.pushKV("quorumHeight", (int)quorumHeight);
38 276 : ret.pushKV("phase", (int)phase);
39 :
40 276 : ret.pushKV("sentContributions", sentContributions);
41 276 : ret.pushKV("sentComplaint", sentComplaint);
42 276 : ret.pushKV("sentJustification", sentJustification);
43 276 : ret.pushKV("sentPrematureCommitment", sentPrematureCommitment);
44 276 : ret.pushKV("aborted", aborted);
45 :
46 0 : struct ArrOrCount {
47 : int count{0};
48 : UniValue arr{UniValue::VARR};
49 : };
50 :
51 552 : ArrOrCount badMembers;
52 552 : ArrOrCount weComplain;
53 552 : ArrOrCount receivedContributions;
54 552 : ArrOrCount receivedComplaints;
55 552 : ArrOrCount receivedJustifications;
56 552 : ArrOrCount receivedPrematureCommitments;
57 552 : ArrOrCount complaintsFromMembers;
58 :
59 5244 : auto add = [&](ArrOrCount& v, size_t idx, bool flag) {
60 4968 : if (flag) {
61 1176 : if (detailLevel == 0) {
62 1176 : 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 4968 : };
75 1932 : auto push = [&](ArrOrCount& v, const std::string& name) {
76 1656 : if (detailLevel == 0) {
77 1656 : ret.pushKV(name, v.count);
78 : } else {
79 0 : ret.pushKV(name, v.arr);
80 : }
81 1932 : };
82 :
83 1104 : for (size_t i = 0; i < members.size(); i++) {
84 828 : const auto& m = members[i];
85 828 : add(badMembers, i, m.bad);
86 828 : add(weComplain, i, m.weComplain);
87 828 : add(receivedContributions, i, m.receivedContribution);
88 828 : add(receivedComplaints, i, m.receivedComplaint);
89 828 : add(receivedJustifications, i, m.receivedJustification);
90 828 : add(receivedPrematureCommitments, i, m.receivedPrematureCommitment);
91 : }
92 276 : push(badMembers, "badMembers");
93 276 : push(weComplain, "weComplain");
94 276 : push(receivedContributions, "receivedContributions");
95 276 : push(receivedComplaints, "receivedComplaints");
96 276 : push(receivedJustifications, "receivedJustifications");
97 276 : push(receivedPrematureCommitments, "receivedPrematureCommitments");
98 276 : ret.pushKV("receivedFinalCommitment", receivedFinalCommitment);
99 :
100 276 : 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 276 : return ret;
109 : }
110 :
111 276 : UniValue CDKGDebugStatus::ToJson(int detailLevel) const
112 : {
113 276 : const Consensus::Params& consensus = Params().GetConsensus();
114 276 : UniValue ret(UniValue::VOBJ);
115 :
116 276 : ret.pushKV("time", nTime);
117 552 : ret.pushKV("timeStr", FormatISO8601DateTime(nTime));
118 276 : UniValue sessionsJson(UniValue::VOBJ);
119 552 : for (const auto& p : sessions) {
120 552 : Optional<Consensus::LLMQParams> opt_params = consensus.GetLLMQParams((Consensus::LLMQType)p.first);
121 276 : if (opt_params == nullopt) {
122 0 : continue;
123 : }
124 552 : sessionsJson.pushKV(opt_params->name, p.second.ToJson(detailLevel));
125 : }
126 276 : ret.pushKV("session", sessionsJson);
127 :
128 276 : return ret;
129 : }
130 :
131 276 : void CDKGDebugManager::GetLocalDebugStatus(llmq::CDKGDebugStatus& ret)
132 : {
133 276 : LOCK(cs);
134 276 : ret = localStatus;
135 276 : }
136 :
137 340 : void CDKGDebugManager::ResetLocalSessionStatus(Consensus::LLMQType llmqType)
138 : {
139 402 : LOCK(cs);
140 :
141 340 : auto it = localStatus.sessions.find(llmqType);
142 340 : if (it == localStatus.sessions.end()) {
143 556 : return;
144 : }
145 :
146 62 : localStatus.sessions.erase(it);
147 62 : localStatus.nTime = GetAdjustedTime();
148 : }
149 :
150 79 : void CDKGDebugManager::InitLocalSessionStatus(Consensus::LLMQType llmqType, const uint256& quorumHash, int quorumHeight)
151 : {
152 79 : LOCK(cs);
153 :
154 79 : auto it = localStatus.sessions.find(llmqType);
155 79 : if (it == localStatus.sessions.end()) {
156 158 : it = localStatus.sessions.emplace(llmqType, CDKGDebugSessionStatus()).first;
157 : }
158 :
159 79 : auto& params = Params().GetConsensus().llmqs.at(llmqType);
160 79 : auto& session = it->second;
161 79 : session.llmqType = llmqType;
162 79 : session.quorumHash = quorumHash;
163 79 : session.quorumHeight = (uint32_t)quorumHeight;
164 79 : session.phase = 0;
165 79 : session.statusBitset = 0;
166 79 : session.members.clear();
167 79 : session.members.resize((size_t)params.size);
168 79 : }
169 :
170 1558 : void CDKGDebugManager::UpdateLocalSessionStatus(Consensus::LLMQType llmqType, std::function<bool(CDKGDebugSessionStatus& status)>&& func)
171 : {
172 1558 : LOCK(cs);
173 :
174 1558 : auto it = localStatus.sessions.find(llmqType);
175 1558 : if (it == localStatus.sessions.end()) {
176 1890 : return;
177 : }
178 :
179 613 : if (func(it->second)) {
180 609 : localStatus.nTime = GetAdjustedTime();
181 : }
182 : }
183 :
184 437 : void CDKGDebugManager::UpdateLocalMemberStatus(Consensus::LLMQType llmqType, size_t memberIdx, std::function<bool(CDKGDebugMemberStatus& status)>&& func)
185 : {
186 874 : LOCK(cs);
187 :
188 437 : auto it = localStatus.sessions.find(llmqType);
189 437 : if (it == localStatus.sessions.end()) {
190 0 : return;
191 : }
192 :
193 437 : if (func(it->second.members.at(memberIdx))) {
194 437 : localStatus.nTime = GetAdjustedTime();
195 : }
196 : }
197 :
198 : } // namespace llmq
|