PIVX Core  5.6.99
P2P Digital Currency
quorums_debug.cpp
Go to the documentation of this file.
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 
20 {
22 
23  if (!Params().GetConsensus().llmqs.count((Consensus::LLMQType)llmqType) || quorumHash.IsNull()) {
24  return ret;
25  }
26 
27  std::vector<CDeterministicMNCPtr> dmnMembers;
28  if (detailLevel == 2) {
29  const CBlockIndex* pindexQuorum = WITH_LOCK(cs_main, return LookupBlockIndex(quorumHash));
30  if (pindexQuorum != nullptr) {
31  dmnMembers = deterministicMNManager->GetAllQuorumMembers((Consensus::LLMQType) llmqType, pindexQuorum);
32  }
33  }
34 
35  ret.pushKV("llmqType", llmqType);
36  ret.pushKV("quorumHash", quorumHash.ToString());
37  ret.pushKV("quorumHeight", (int)quorumHeight);
38  ret.pushKV("phase", (int)phase);
39 
40  ret.pushKV("sentContributions", sentContributions);
41  ret.pushKV("sentComplaint", sentComplaint);
42  ret.pushKV("sentJustification", sentJustification);
43  ret.pushKV("sentPrematureCommitment", sentPrematureCommitment);
44  ret.pushKV("aborted", aborted);
45 
46  struct ArrOrCount {
47  int count{0};
49  };
50 
51  ArrOrCount badMembers;
52  ArrOrCount weComplain;
53  ArrOrCount receivedContributions;
54  ArrOrCount receivedComplaints;
55  ArrOrCount receivedJustifications;
56  ArrOrCount receivedPrematureCommitments;
57  ArrOrCount complaintsFromMembers;
58 
59  auto add = [&](ArrOrCount& v, size_t idx, bool flag) {
60  if (flag) {
61  if (detailLevel == 0) {
62  v.count++;
63  } else if (detailLevel == 1) {
64  v.arr.push_back((int)idx);
65  } else if (detailLevel == 2) {
67  a.pushKV("memberIndex", (int)idx);
68  if (idx < dmnMembers.size()) {
69  a.pushKV("proTxHash", dmnMembers[idx]->proTxHash.ToString());
70  }
71  v.arr.push_back(a);
72  }
73  }
74  };
75  auto push = [&](ArrOrCount& v, const std::string& name) {
76  if (detailLevel == 0) {
77  ret.pushKV(name, v.count);
78  } else {
79  ret.pushKV(name, v.arr);
80  }
81  };
82 
83  for (size_t i = 0; i < members.size(); i++) {
84  const auto& m = members[i];
85  add(badMembers, i, m.bad);
86  add(weComplain, i, m.weComplain);
87  add(receivedContributions, i, m.receivedContribution);
88  add(receivedComplaints, i, m.receivedComplaint);
89  add(receivedJustifications, i, m.receivedJustification);
90  add(receivedPrematureCommitments, i, m.receivedPrematureCommitment);
91  }
92  push(badMembers, "badMembers");
93  push(weComplain, "weComplain");
94  push(receivedContributions, "receivedContributions");
95  push(receivedComplaints, "receivedComplaints");
96  push(receivedJustifications, "receivedJustifications");
97  push(receivedPrematureCommitments, "receivedPrematureCommitments");
98  ret.pushKV("receivedFinalCommitment", receivedFinalCommitment);
99 
100  if (detailLevel == 2) {
102  for (const auto& dmn : dmnMembers) {
103  arr.push_back(dmn->proTxHash.ToString());
104  }
105  ret.pushKV("allMembers", arr);
106  }
107 
108  return ret;
109 }
110 
111 UniValue CDKGDebugStatus::ToJson(int detailLevel) const
112 {
113  const Consensus::Params& consensus = Params().GetConsensus();
115 
116  ret.pushKV("time", nTime);
117  ret.pushKV("timeStr", FormatISO8601DateTime(nTime));
118  UniValue sessionsJson(UniValue::VOBJ);
119  for (const auto& p : sessions) {
120  Optional<Consensus::LLMQParams> opt_params = consensus.GetLLMQParams((Consensus::LLMQType)p.first);
121  if (opt_params == nullopt) {
122  continue;
123  }
124  sessionsJson.pushKV(opt_params->name, p.second.ToJson(detailLevel));
125  }
126  ret.pushKV("session", sessionsJson);
127 
128  return ret;
129 }
130 
132 {
133  LOCK(cs);
134  ret = localStatus;
135 }
136 
138 {
139  LOCK(cs);
140 
141  auto it = localStatus.sessions.find(llmqType);
142  if (it == localStatus.sessions.end()) {
143  return;
144  }
145 
146  localStatus.sessions.erase(it);
148 }
149 
150 void CDKGDebugManager::InitLocalSessionStatus(Consensus::LLMQType llmqType, const uint256& quorumHash, int quorumHeight)
151 {
152  LOCK(cs);
153 
154  auto it = localStatus.sessions.find(llmqType);
155  if (it == localStatus.sessions.end()) {
156  it = localStatus.sessions.emplace(llmqType, CDKGDebugSessionStatus()).first;
157  }
158 
159  auto& params = Params().GetConsensus().llmqs.at(llmqType);
160  auto& session = it->second;
161  session.llmqType = llmqType;
162  session.quorumHash = quorumHash;
163  session.quorumHeight = (uint32_t)quorumHeight;
164  session.phase = 0;
165  session.statusBitset = 0;
166  session.members.clear();
167  session.members.resize((size_t)params.size);
168 }
169 
171 {
172  LOCK(cs);
173 
174  auto it = localStatus.sessions.find(llmqType);
175  if (it == localStatus.sessions.end()) {
176  return;
177  }
178 
179  if (func(it->second)) {
181  }
182 }
183 
184 void CDKGDebugManager::UpdateLocalMemberStatus(Consensus::LLMQType llmqType, size_t memberIdx, std::function<bool(CDKGDebugMemberStatus& status)>&& func)
185 {
186  LOCK(cs);
187 
188  auto it = localStatus.sessions.find(llmqType);
189  if (it == localStatus.sessions.end()) {
190  return;
191  }
192 
193  if (func(it->second.members.at(memberIdx))) {
195  }
196 }
197 
198 } // namespace llmq
const CChainParams & Params()
Return the currently selected parameters.
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:139
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:72
@ VOBJ
Definition: univalue.h:21
@ VARR
Definition: univalue.h:21
bool push_back(const UniValue &val)
Definition: univalue.cpp:108
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
std::string ToString() const
Definition: uint256.cpp:65
bool IsNull() const
Definition: uint256.h:36
void GetLocalDebugStatus(CDKGDebugStatus &ret)
void InitLocalSessionStatus(Consensus::LLMQType llmqType, const uint256 &quorumHash, int quorumHeight)
void UpdateLocalSessionStatus(Consensus::LLMQType llmqType, std::function< bool(CDKGDebugSessionStatus &status)> &&func)
CDKGDebugStatus localStatus
Definition: quorums_debug.h:95
void ResetLocalSessionStatus(Consensus::LLMQType llmqType)
void UpdateLocalMemberStatus(Consensus::LLMQType llmqType, size_t memberIdx, std::function< bool(CDKGDebugMemberStatus &status)> &&func)
std::vector< CDKGDebugMemberStatus > members
Definition: quorums_debug.h:71
UniValue ToJson(int detailLevel) const
Consensus::LLMQType llmqType
Definition: quorums_debug.h:52
UniValue ToJson(int detailLevel) const
std::map< Consensus::LLMQType, CDKGDebugSessionStatus > sessions
Definition: quorums_debug.h:85
256-bit opaque blob.
Definition: uint256.h:138
std::unique_ptr< CDeterministicMNManager > deterministicMNManager
@ LOCK
Definition: lockunlock.h:16
LLMQType
Definition: params.h:90
Definition: quorums.cpp:26
std::unique_ptr< CDKGDebugManager > quorumDKGDebugManager
RecursiveMutex cs_main
Global state.
Definition: validation.cpp:80
boost::optional< T > Optional
Substitute for C++17 std::optional.
Definition: optional.h:12
const char * name
Definition: rest.cpp:37
@ proTxHash
Definition: rpcevo.cpp:50
Parameters that influence chain consensus.
Definition: params.h:171
Optional< LLMQParams > GetLLMQParams(uint8_t llmqtype) const
Definition: params.cpp:25
std::map< LLMQType, LLMQParams > llmqs
Definition: params.h:279
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:247
int64_t GetAdjustedTime()
Definition: timedata.cpp:36
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
Definition: utiltime.cpp:102
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: validation.h:345