Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

rpcquorums.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017-2020 The Dash Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <chainparams.h>
6 #include <rpc/server.h>
7 #include <validation.h>
8 
10 
11 #include <llmq/quorums.h>
13 #include <llmq/quorums_debug.h>
15 #include <llmq/quorums_signing.h>
17 
19 {
20  throw std::runtime_error(
21  "quorum list ( count )\n"
22  "List of on-chain quorums\n"
23  "\nArguments:\n"
24  "1. count (number, optional) Number of quorums to list. Will list active quorums\n"
25  " if \"count\" is not specified.\n"
26  "\nResult:\n"
27  "{\n"
28  " \"quorumName\" : [ (array of strings) List of quorum hashes per some quorum type.\n"
29  " \"quorumHash\" (string) Quorum hash. Note: most recent quorums come first.\n"
30  " ,...\n"
31  " ],\n"
32  "}\n"
33  "\nExamples:\n"
34  + HelpExampleCli("quorum", "list")
35  + HelpExampleCli("quorum", "list 10")
36  + HelpExampleRpc("quorum", "list, 10")
37  );
38 }
39 
41 {
42  if (request.fHelp || (request.params.size() != 1 && request.params.size() != 2))
44 
45  LOCK(cs_main);
46 
47  int count = -1;
48  if (!request.params[1].isNull()) {
49  count = ParseInt32V(request.params[1], "count");
50  if (count < 0) {
51  throw JSONRPCError(RPC_INVALID_PARAMETER, "count can't be negative");
52  }
53  }
54 
56 
57  for (auto& p : Params().GetConsensus().llmqs) {
59 
60  auto quorums = llmq::quorumManager->ScanQuorums(p.first, chainActive.Tip(), count > -1 ? count : p.second.signingActiveQuorumCount);
61  for (auto& q : quorums) {
62  v.push_back(q->qc.quorumHash.ToString());
63  }
64 
65  ret.push_back(Pair(p.second.name, v));
66  }
67 
68 
69  return ret;
70 }
71 
73 {
74  throw std::runtime_error(
75  "quorum info llmqType \"quorumHash\" ( includeSkShare )\n"
76  "Return information about a quorum\n"
77  "\nArguments:\n"
78  "1. llmqType (int, required) LLMQ type.\n"
79  "2. \"quorumHash\" (string, required) Block hash of quorum.\n"
80  "3. includeSkShare (boolean, optional) Include secret key share in output.\n"
81  );
82 }
83 
84 UniValue BuildQuorumInfo(const llmq::CQuorumCPtr& quorum, bool includeMembers, bool includeSkShare)
85 {
87 
88  ret.push_back(Pair("height", quorum->pindexQuorum->nHeight));
89  ret.push_back(Pair("type", quorum->params.name));
90  ret.push_back(Pair("quorumHash", quorum->qc.quorumHash.ToString()));
91  ret.push_back(Pair("minedBlock", quorum->minedBlockHash.ToString()));
92 
93  if (includeMembers) {
94  UniValue membersArr(UniValue::VARR);
95  for (size_t i = 0; i < quorum->members.size(); i++) {
96  auto& dmn = quorum->members[i];
98  mo.push_back(Pair("proTxHash", dmn->proTxHash.ToString()));
99  mo.push_back(Pair("pubKeyOperator", dmn->pdmnState->pubKeyOperator.Get().ToString()));
100  mo.push_back(Pair("valid", quorum->qc.validMembers[i]));
101  if (quorum->qc.validMembers[i]) {
102  CBLSPublicKey pubKey = quorum->GetPubKeyShare(i);
103  if (pubKey.IsValid()) {
104  mo.push_back(Pair("pubKeyShare", pubKey.ToString()));
105  }
106  }
107  membersArr.push_back(mo);
108  }
109 
110  ret.push_back(Pair("members", membersArr));
111  }
112  ret.push_back(Pair("quorumPublicKey", quorum->qc.quorumPublicKey.ToString()));
113  CBLSSecretKey skShare = quorum->GetSkShare();
114  if (includeSkShare && skShare.IsValid()) {
115  ret.push_back(Pair("secretKeyShare", skShare.ToString()));
116  }
117  return ret;
118 }
119 
121 {
122  if (request.fHelp || (request.params.size() != 3 && request.params.size() != 4))
124 
125  LOCK(cs_main);
126 
127  Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[1], "llmqType");
128  if (!Params().GetConsensus().llmqs.count(llmqType)) {
129  throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
130  }
131 
132  const auto& llmqParams = Params().GetConsensus().llmqs.at(llmqType);
133 
134  uint256 quorumHash = ParseHashV(request.params[2], "quorumHash");
135  bool includeSkShare = false;
136  if (!request.params[3].isNull()) {
137  includeSkShare = ParseBoolV(request.params[3], "includeSkShare");
138  }
139 
140  auto quorum = llmq::quorumManager->GetQuorum(llmqType, quorumHash);
141  if (!quorum) {
142  throw JSONRPCError(RPC_INVALID_PARAMETER, "quorum not found");
143  }
144 
145  return BuildQuorumInfo(quorum, true, includeSkShare);
146 }
147 
149 {
150  throw std::runtime_error(
151  "quorum dkgstatus ( detail_level )\n"
152  "Return the status of the current DKG process.\n"
153  "Works only when SPORK_17_QUORUM_DKG_ENABLED spork is ON.\n"
154  "\nArguments:\n"
155  "1. detail_level (number, optional, default=0) Detail level of output.\n"
156  " 0=Only show counts. 1=Show member indexes. 2=Show member's ProTxHashes.\n"
157  );
158 }
159 
161 {
162  if (request.fHelp || (request.params.size() < 1 || request.params.size() > 2)) {
164  }
165 
166  int detailLevel = 0;
167  if (!request.params[1].isNull()) {
168  detailLevel = ParseInt32V(request.params[1], "detail_level");
169  if (detailLevel < 0 || detailLevel > 2) {
170  throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid detail_level");
171  }
172  }
173 
174  llmq::CDKGDebugStatus status;
176 
177  auto ret = status.ToJson(detailLevel);
178 
179  LOCK(cs_main);
180  int tipHeight = chainActive.Height();
181 
182  UniValue minableCommitments(UniValue::VOBJ);
183  UniValue quorumConnections(UniValue::VOBJ);
184  for (const auto& p : Params().GetConsensus().llmqs) {
185  auto& params = p.second;
186 
187  if (fMasternodeMode) {
188  const CBlockIndex* pindexQuorum = chainActive[tipHeight - (tipHeight % params.dkgInterval)];
189  auto allConnections = llmq::CLLMQUtils::GetQuorumConnections(params.type, pindexQuorum, activeMasternodeInfo.proTxHash, false);
190  auto outboundConnections = llmq::CLLMQUtils::GetQuorumConnections(params.type, pindexQuorum, activeMasternodeInfo.proTxHash, true);
191  std::map<uint256, CAddress> foundConnections;
192  g_connman->ForEachNode([&](const CNode* pnode) {
193  if (!pnode->verifiedProRegTxHash.IsNull() && allConnections.count(pnode->verifiedProRegTxHash)) {
194  foundConnections.emplace(pnode->verifiedProRegTxHash, pnode->addr);
195  }
196  });
198  for (auto& ec : allConnections) {
200  obj.push_back(Pair("proTxHash", ec.ToString()));
201  if (foundConnections.count(ec)) {
202  obj.push_back(Pair("connected", true));
203  obj.push_back(Pair("address", foundConnections[ec].ToString(false)));
204  } else {
205  obj.push_back(Pair("connected", false));
206  }
207  obj.push_back(Pair("outbound", outboundConnections.count(ec) != 0));
208  arr.push_back(obj);
209  }
210  quorumConnections.push_back(Pair(params.name, arr));
211  }
212 
214  if (llmq::quorumBlockProcessor->GetMinableCommitment(params.type, tipHeight, fqc)) {
216  fqc.ToJson(obj);
217  minableCommitments.push_back(Pair(params.name, obj));
218  }
219  }
220 
221  ret.push_back(Pair("minableCommitments", minableCommitments));
222  ret.push_back(Pair("quorumConnections", quorumConnections));
223 
224  return ret;
225 }
226 
228 {
229  throw std::runtime_error(
230  "quorum memberof \"proTxHash\" (quorumCount)\n"
231  "Checks which quorums the given masternode is a member of.\n"
232  "\nArguments:\n"
233  "1. \"proTxHash\" (string, required) ProTxHash of the masternode.\n"
234  "2. scanQuorumsCount (number, optional) Number of quorums to scan for. If not specified,\n"
235  " the active quorum count for each specific quorum type is used."
236  );
237 }
238 
240 {
241  if (request.fHelp || (request.params.size() < 2 || request.params.size() > 3)) {
243  }
244 
245  uint256 protxHash = ParseHashV(request.params[1], "proTxHash");
246  int scanQuorumsCount = -1;
247  if (!request.params[2].isNull()) {
248  scanQuorumsCount = ParseInt32V(request.params[2], "scanQuorumsCount");
249  if (scanQuorumsCount <= 0) {
250  throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid scanQuorumsCount parameter");
251  }
252  }
253 
254  const CBlockIndex* pindexTip;
255  {
256  LOCK(cs_main);
257  pindexTip = chainActive.Tip();
258  }
259 
260  auto mnList = deterministicMNManager->GetListForBlock(pindexTip);
261  auto dmn = mnList.GetMN(protxHash);
262  if (!dmn) {
263  throw JSONRPCError(RPC_INVALID_PARAMETER, "masternode not found");
264  }
265 
266  UniValue result(UniValue::VARR);
267 
268  for (const auto& p : Params().GetConsensus().llmqs) {
269  auto& params = p.second;
270  size_t count = params.signingActiveQuorumCount;
271  if (scanQuorumsCount != -1) {
272  count = (size_t)scanQuorumsCount;
273  }
274  auto quorums = llmq::quorumManager->ScanQuorums(params.type, count);
275  for (auto& quorum : quorums) {
276  if (quorum->IsMember(dmn->proTxHash)) {
277  auto json = BuildQuorumInfo(quorum, false, false);
278  json.push_back(Pair("isValidMember", quorum->IsValidMember(dmn->proTxHash)));
279  json.push_back(Pair("memberIndex", quorum->GetMemberIndex(dmn->proTxHash)));
280  result.push_back(json);
281  }
282  }
283  }
284 
285  return result;
286 }
287 
289 {
290  throw std::runtime_error(
291  "quorum sign llmqType \"id\" \"msgHash\" ( \"quorumHash\" )\n"
292  "Threshold-sign a message\n"
293  "\nArguments:\n"
294  "1. llmqType (int, required) LLMQ type.\n"
295  "2. \"id\" (string, required) Request id.\n"
296  "3. \"msgHash\" (string, required) Message hash.\n"
297  "4. \"quorumHash\" (string, optional) The quorum identifier.\n"
298  );
299 }
300 
302 {
303  throw std::runtime_error(
304  "quorum hasrecsig llmqType \"id\" \"msgHash\"\n"
305  "Test if a valid recovered signature is present\n"
306  "\nArguments:\n"
307  "1. llmqType (int, required) LLMQ type.\n"
308  "2. \"id\" (string, required) Request id.\n"
309  "3. \"msgHash\" (string, required) Message hash.\n"
310  );
311 }
312 
314 {
315  throw std::runtime_error(
316  "quorum getrecsig llmqType \"id\" \"msgHash\"\n"
317  "Get a recovered signature\n"
318  "\nArguments:\n"
319  "1. llmqType (int, required) LLMQ type.\n"
320  "2. \"id\" (string, required) Request id.\n"
321  "3. \"msgHash\" (string, required) Message hash.\n"
322  );
323 }
324 
326 {
327  throw std::runtime_error(
328  "quorum isconflicting llmqType \"id\" \"msgHash\"\n"
329  "Test if a conflict exists\n"
330  "\nArguments:\n"
331  "1. llmqType (int, required) LLMQ type.\n"
332  "2. \"id\" (string, required) Request id.\n"
333  "3. \"msgHash\" (string, required) Message hash.\n"
334  );
335 }
336 
338 {
339  auto cmd = request.params[0].get_str();
340  if (request.fHelp || (request.params.size() != 4)) {
341  if (cmd == "sign") {
342  if ((request.params.size() < 4) || (request.params.size() > 5)) {
344  }
345  } else if (cmd == "hasrecsig") {
347  } else if (cmd == "getrecsig") {
349  } else if (cmd == "isconflicting") {
351  } else {
352  // shouldn't happen as it's already handled by the caller
353  throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid cmd");
354  }
355  }
356 
357  Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[1], "llmqType");
358  if (!Params().GetConsensus().llmqs.count(llmqType)) {
359  throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
360  }
361 
362  uint256 id = ParseHashV(request.params[2], "id");
363  uint256 msgHash = ParseHashV(request.params[3], "msgHash");
364 
365  if (cmd == "sign") {
366  if (!request.params[4].isNull()) {
367  uint256 quorumHash = ParseHashV(request.params[4], "quorumHash");
368  auto quorum = llmq::quorumManager->GetQuorum(llmqType, quorumHash);
369  if (!quorum) {
370  throw JSONRPCError(RPC_INVALID_PARAMETER, "quorum not found");
371  }
373  return true;
374  } else {
375  return llmq::quorumSigningManager->AsyncSignIfMember(llmqType, id, msgHash);
376  }
377  } else if (cmd == "hasrecsig") {
378  return llmq::quorumSigningManager->HasRecoveredSig(llmqType, id, msgHash);
379  } else if (cmd == "getrecsig") {
380  llmq::CRecoveredSig recSig;
381  if (!llmq::quorumSigningManager->GetRecoveredSigForId(llmqType, id, recSig)) {
382  throw JSONRPCError(RPC_INVALID_PARAMETER, "recovered signature not found");
383  }
384  if (recSig.msgHash != msgHash) {
385  throw JSONRPCError(RPC_INVALID_PARAMETER, "recovered signature not found");
386  }
387  return recSig.ToJson();
388  } else if (cmd == "isconflicting") {
389  return llmq::quorumSigningManager->IsConflicting(llmqType, id, msgHash);
390  } else {
391  // shouldn't happen as it's already handled by the caller
392  throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid cmd");
393  }
394 }
395 
397 {
398  throw std::runtime_error(
399  "quorum selectquorum llmqType \"id\"\n"
400  "Returns the quorum that would/should sign a request\n"
401  "\nArguments:\n"
402  "1. llmqType (int, required) LLMQ type.\n"
403  "2. \"id\" (string, required) Request id.\n"
404  );
405 }
406 
408 {
409  if (request.fHelp || request.params.size() != 3) {
411  }
412 
413  Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[1], "llmqType");
414  if (!Params().GetConsensus().llmqs.count(llmqType)) {
415  throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
416  }
417 
418  uint256 id = ParseHashV(request.params[2], "id");
419 
421 
423  if (!quorum) {
424  throw JSONRPCError(RPC_MISC_ERROR, "no quorums active");
425  }
426  ret.push_back(Pair("quorumHash", quorum->qc.quorumHash.ToString()));
427 
428  UniValue recoveryMembers(UniValue::VARR);
429  for (int i = 0; i < quorum->params.recoveryMembers; i++) {
431  recoveryMembers.push_back(dmn->proTxHash.ToString());
432  }
433  ret.push_back(Pair("recoveryMembers", recoveryMembers));
434 
435  return ret;
436 }
437 
439 {
440  throw std::runtime_error(
441  "quorum dkgsimerror \"type\" rate\n"
442  "This enables simulation of errors and malicious behaviour in the DKG. Do NOT use this on mainnet\n"
443  "as you will get yourself very likely PoSe banned for this.\n"
444  "\nArguments:\n"
445  "1. \"type\" (string, required) Error type.\n"
446  "2. rate (number, required) Rate at which to simulate this error type.\n"
447  );
448 }
449 
451 {
452  auto cmd = request.params[0].get_str();
453  if (request.fHelp || (request.params.size() != 3)) {
455  }
456 
457  std::string type = request.params[1].get_str();
458  double rate = ParseDoubleV(request.params[2], "rate");
459 
460  if (rate < 0 || rate > 1) {
461  throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid rate. Must be between 0 and 1");
462  }
463 
464  llmq::SetSimulatedDKGErrorRate(type, rate);
465 
466  return UniValue();
467 }
468 
469 
470 [[ noreturn ]] void quorum_help()
471 {
472  throw std::runtime_error(
473  "quorum \"command\" ...\n"
474  "Set of commands for quorums/LLMQs.\n"
475  "To get help on individual commands, use \"help quorum command\".\n"
476  "\nArguments:\n"
477  "1. \"command\" (string, required) The command to execute\n"
478  "\nAvailable commands:\n"
479  " list - List of on-chain quorums\n"
480  " info - Return information about a quorum\n"
481  " dkgsimerror - Simulates DKG errors and malicious behavior\n"
482  " dkgstatus - Return the status of the current DKG process\n"
483  " memberof - Checks which quorums the given masternode is a member of\n"
484  " sign - Threshold-sign a message\n"
485  " hasrecsig - Test if a valid recovered signature is present\n"
486  " getrecsig - Get a recovered signature\n"
487  " isconflicting - Test if a conflict exists\n"
488  " selectquorum - Return the quorum that would/should sign a request\n"
489  );
490 }
491 
493 {
494  if (request.fHelp && request.params.empty()) {
495  quorum_help();
496  }
497 
498  std::string command;
499  if (!request.params[0].isNull()) {
500  command = request.params[0].get_str();
501  }
502 
503  if (command == "list") {
504  return quorum_list(request);
505  } else if (command == "info") {
506  return quorum_info(request);
507  } else if (command == "dkgstatus") {
508  return quorum_dkgstatus(request);
509  } else if (command == "memberof") {
510  return quorum_memberof(request);
511  } else if (command == "sign" || command == "hasrecsig" || command == "getrecsig" || command == "isconflicting") {
512  return quorum_sigs_cmd(request);
513  } else if (command == "selectquorum") {
514  return quorum_selectquorum(request);
515  } else if (command == "dkgsimerror") {
516  return quorum_dkgsimerror(request);
517  } else {
518  quorum_help();
519  }
520 }
521 
522 static const CRPCCommand commands[] =
523 { // category name actor (function)
524  // --------------------- ------------------------ -----------------------
525  { "evo", "quorum", &quorum, {} },
526 };
527 
529 {
530  for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
531  tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
532 }
void SetSimulatedDKGErrorRate(const std::string &type, double rate)
static std::set< uint256 > GetQuorumConnections(Consensus::LLMQType llmqType, const CBlockIndex *pindexQuorum, const uint256 &forMember, bool onlyOutbound)
CSigSharesManager * quorumSigSharesManager
UniValue quorum(const JSONRPCRequest &request)
Definition: rpcquorums.cpp:492
double ParseDoubleV(const UniValue &v, const std::string &strName)
Definition: server.cpp:170
UniValue BuildQuorumInfo(const llmq::CQuorumCPtr &quorum, bool includeMembers, bool includeSkShare)
Definition: rpcquorums.cpp:84
UniValue ToJson(int detailLevel) const
Dash RPC command dispatcher.
Definition: server.h:140
UniValue quorum_selectquorum(const JSONRPCRequest &request)
Definition: rpcquorums.cpp:407
void quorum_selectquorum_help()
Definition: rpcquorums.cpp:396
void quorum_getrecsig_help()
Definition: rpcquorums.cpp:313
int32_t ParseInt32V(const UniValue &v, const std::string &strName)
Definition: server.cpp:152
CQuorumBlockProcessor * quorumBlockProcessor
int Height() const
Return the maximal height in the chain.
Definition: chain.h:484
CCriticalSection cs_main
Definition: validation.cpp:213
void quorum_memberof_help()
Definition: rpcquorums.cpp:227
void RegisterQuorumsRPCCommands(CRPCTable &tableRPC)
Register Quorums RPC commands.
Definition: rpcquorums.cpp:528
const std::string & get_str() const
std::vector< CQuorumCPtr > ScanQuorums(Consensus::LLMQType llmqType, size_t maxCount)
Definition: quorums.cpp:279
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: server.cpp:583
bool AsyncSignIfMember(Consensus::LLMQType llmqType, const uint256 &id, const uint256 &msgHash, bool allowReSign=false)
std::unique_ptr< CDeterministicMNManager > deterministicMNManager
bool appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:353
UniValue quorum_sigs_cmd(const JSONRPCRequest &request)
Definition: rpcquorums.cpp:337
static const CRPCCommand commands[]
Definition: rpcquorums.cpp:522
bool IsNull() const
Definition: uint256.h:33
Invalid, missing or duplicate parameter.
Definition: protocol.h:53
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded Values (throws error if not hex).
Definition: server.cpp:121
CQuorumManager * quorumManager
Definition: quorums.cpp:30
bool HasRecoveredSig(Consensus::LLMQType llmqType, const uint256 &id, const uint256 &msgHash)
static CDeterministicMNCPtr SelectMemberForRecovery(const CQuorumCPtr &quorum, const uint256 &id, int attempt)
bool fMasternodeMode
Definition: util.cpp:93
LLMQType
Definition: params.h:48
void quorum_dkgsimerror_help()
Definition: rpcquorums.cpp:438
std::string name
Definition: server.h:132
CRPCTable tableRPC
Definition: server.cpp:616
std::size_t size_t
Definition: bits.hpp:21
bool push_back(const UniValue &val)
Definition: univalue.cpp:110
void quorum_isconflicting_help()
Definition: rpcquorums.cpp:325
CActiveMasternodeInfo activeMasternodeInfo
UniValue params
Definition: server.h:42
std::string ToString() const
Definition: bls.h:210
CQuorumCPtr SelectQuorumForSigning(Consensus::LLMQType llmqType, const uint256 &selectionHash, int signHeight=-1, int signOffset=SIGN_HEIGHT_OFFSET)
#define LOCK(cs)
Definition: sync.h:178
void quorum_sign_help()
Definition: rpcquorums.cpp:288
UniValue quorum_dkgsimerror(const JSONRPCRequest &request)
Definition: rpcquorums.cpp:450
void GetLocalDebugStatus(CDKGDebugStatus &ret)
bool empty() const
Definition: univalue.h:67
void quorum_info_help()
Definition: rpcquorums.cpp:72
void quorum_dkgstatus_help()
Definition: rpcquorums.cpp:148
General application defined errors.
Definition: protocol.h:48
CDKGDebugManager * quorumDKGDebugManager
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: server.cpp:578
static std::pair< std::string, UniValue > Pair(const char *cKey, const char *cVal)
Definition: univalue.h:185
UniValue quorum_list(const JSONRPCRequest &request)
Definition: rpcquorums.cpp:40
UniValue quorum_info(const JSONRPCRequest &request)
Definition: rpcquorums.cpp:120
bool isNull() const
Definition: univalue.h:78
std::map< LLMQType, LLMQParams > llmqs
Definition: params.h:189
void quorum_hasrecsig_help()
Definition: rpcquorums.cpp:301
const CAddress addr
Definition: net.h:834
bool fHelp
Definition: server.h:43
256-bit opaque blob.
Definition: uint256.h:123
uint256 verifiedProRegTxHash
Definition: net.h:941
#define ARRAYLEN(array)
void AsyncSign(const CQuorumCPtr &quorum, const uint256 &id, const uint256 &msgHash)
bool IsConflicting(Consensus::LLMQType llmqType, const uint256 &id, const uint256 &msgHash)
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:170
const CChainParams & Params()
Return the currently selected parameters.
UniValue ToJson() const
UniValue quorum_dkgstatus(const JSONRPCRequest &request)
Definition: rpcquorums.cpp:160
UniValue quorum_memberof(const JSONRPCRequest &request)
Definition: rpcquorums.cpp:239
std::shared_ptr< const CQuorum > CQuorumCPtr
Definition: quorums.h:73
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:453
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:97
static int count
Definition: tests.c:45
bool ParseBoolV(const UniValue &v, const std::string &strName)
Definition: server.cpp:179
CQuorumCPtr GetQuorum(Consensus::LLMQType llmqType, const uint256 &quorumHash)
Definition: quorums.cpp:337
CSigningManager * quorumSigningManager
UniValue JSONRPCError(int code, const std::string &message)
Definition: protocol.cpp:54
size_t size() const
Definition: univalue.h:69
Information about a peer.
Definition: net.h:800
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:54
void quorum_help()
Definition: rpcquorums.cpp:470
void ToJson(UniValue &obj) const
CChain & chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:217
void quorum_list_help()
Definition: rpcquorums.cpp:18
bool IsValid() const
Definition: bls.h:94
Released under the MIT license