Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

quorums_dkgsessionhandler.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018-2019 The Dash Core developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
7 #include <llmq/quorums_debug.h>
8 #include <llmq/quorums_init.h>
9 #include <llmq/quorums_utils.h>
10 
12 #include <chainparams.h>
13 #include <init.h>
14 #include <net_processing.h>
15 #include <spork.h>
16 #include <validation.h>
17 
18 namespace llmq
19 {
20 
21 CDKGPendingMessages::CDKGPendingMessages(size_t _maxMessagesPerNode, int _invType) :
22  maxMessagesPerNode(_maxMessagesPerNode),
23  invType(_invType)
24 {
25 }
26 
28 {
29  // this will also consume the data, even if we bail out early
30  auto pm = std::make_shared<CDataStream>(std::move(vRecv));
31 
32  {
33  LOCK(cs);
34 
35  if (messagesPerNode[from] >= maxMessagesPerNode) {
36  // TODO ban?
37  LogPrint(BCLog::LLMQ_DKG, "CDKGPendingMessages::%s -- too many messages, peer=%d\n", __func__, from);
38  return;
39  }
40  messagesPerNode[from]++;
41  }
42 
43  CHashWriter hw(SER_GETHASH, 0);
44  hw.write(pm->data(), pm->size());
45  uint256 hash = hw.GetHash();
46 
47  LOCK2(cs_main, cs);
48 
49  if (!seenMessages.emplace(hash).second) {
50  LogPrint(BCLog::LLMQ_DKG, "CDKGPendingMessages::%s -- already seen %s, peer=%d\n", __func__, hash.ToString(), from);
51  return;
52  }
53 
54  EraseObjectRequest(from, CInv(invType, hash));
55 
56  pendingMessages.emplace_back(std::make_pair(from, std::move(pm)));
57 }
58 
59 std::list<CDKGPendingMessages::BinaryMessage> CDKGPendingMessages::PopPendingMessages(size_t maxCount)
60 {
61  LOCK(cs);
62 
63  std::list<BinaryMessage> ret;
64  while (!pendingMessages.empty() && ret.size() < maxCount) {
65  ret.emplace_back(std::move(pendingMessages.front()));
66  pendingMessages.pop_front();
67  }
68 
69  return std::move(ret);
70 }
71 
72 bool CDKGPendingMessages::HasSeen(const uint256& hash) const
73 {
74  LOCK(cs);
75  return seenMessages.count(hash) != 0;
76 }
77 
79 {
80  LOCK(cs);
81  pendingMessages.clear();
82  messagesPerNode.clear();
83  seenMessages.clear();
84 }
85 
87 
89  params(_params),
90  blsWorker(_blsWorker),
91  dkgManager(_dkgManager),
92  curSession(std::make_shared<CDKGSession>(_params, _blsWorker, _dkgManager)),
93  pendingContributions((size_t)_params.size * 2, MSG_QUORUM_CONTRIB), // we allow size*2 messages as we need to make sure we see bad behavior (double messages)
94  pendingComplaints((size_t)_params.size * 2, MSG_QUORUM_COMPLAINT),
95  pendingJustifications((size_t)_params.size * 2, MSG_QUORUM_JUSTIFICATION),
96  pendingPrematureCommitments((size_t)_params.size * 2, MSG_QUORUM_PREMATURE_COMMITMENT)
97 {
99  throw std::runtime_error("Can't initialize CDKGSessionHandler with LLMQ_NONE type.");
100  }
101 }
102 
104 {
105 }
106 
108 {
109  LOCK(cs);
110 
111  int quorumStageInt = pindexNew->nHeight % params.dkgInterval;
112  const CBlockIndex* pindexQuorum = pindexNew->GetAncestor(pindexNew->nHeight - quorumStageInt);
113 
114  currentHeight = pindexNew->nHeight;
115  quorumHeight = pindexQuorum->nHeight;
116  quorumHash = pindexQuorum->GetBlockHash();
117 
118  bool fNewPhase = (quorumStageInt % params.dkgPhaseBlocks) == 0;
119  int phaseInt = quorumStageInt / params.dkgPhaseBlocks + 1;
120  QuorumPhase oldPhase = phase;
121  if (fNewPhase && phaseInt >= QuorumPhase_Initialized && phaseInt <= QuorumPhase_Idle) {
122  phase = static_cast<QuorumPhase>(phaseInt);
123  }
124 
125  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionHandler::%s -- %s - currentHeight=%d, quorumHeight=%d, oldPhase=%d, newPhase=%d\n", __func__,
127 }
128 
129 void CDKGSessionHandler::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman)
130 {
131  // We don't handle messages in the calling thread as deserialization/processing of these would block everything
132  if (strCommand == NetMsgType::QCONTRIB) {
134  } else if (strCommand == NetMsgType::QCOMPLAINT) {
135  pendingComplaints.PushPendingMessage(pfrom->GetId(), vRecv);
136  } else if (strCommand == NetMsgType::QJUSTIFICATION) {
138  } else if (strCommand == NetMsgType::QPCOMMITMENT) {
140  }
141 }
142 
144 {
145  if (phaseHandlerThread.joinable()) {
146  throw std::runtime_error("Tried to start an already started CDKGSessionHandler thread.");
147  }
148 
149  std::string threadName = strprintf("q-phase-%d", params.type);
150  phaseHandlerThread = std::thread(&TraceThread<std::function<void()> >, threadName, std::function<void()>(std::bind(&CDKGSessionHandler::PhaseHandlerThread, this)));
151 }
152 
154 {
155  stopRequested = true;
156  if (phaseHandlerThread.joinable()) {
157  phaseHandlerThread.join();
158  }
159 }
160 
162 {
163  //AssertLockHeld(cs_main);
164 
165  const auto& consensus = Params().GetConsensus();
166 
167  curSession = std::make_shared<CDKGSession>(params, blsWorker, dkgManager);
168 
169  if (!deterministicMNManager->IsDIP3Enforced(pindexQuorum->nHeight)) {
170  return false;
171  }
172 
173  auto mns = CLLMQUtils::GetAllQuorumMembers(params.type, pindexQuorum);
174 
175  if (!curSession->Init(pindexQuorum, mns, activeMasternodeInfo.proTxHash)) {
176  LogPrintf("CDKGSessionManager::%s -- quorum initialiation failed for %s\n", __func__, curSession->params.name);
177  return false;
178  }
179 
180  return true;
181 }
182 
183 std::pair<QuorumPhase, uint256> CDKGSessionHandler::GetPhaseAndQuorumHash() const
184 {
185  LOCK(cs);
186  return std::make_pair(phase, quorumHash);
187 }
188 
189 class AbortPhaseException : public std::exception {
190 };
191 
193  QuorumPhase nextPhase,
194  const uint256& expectedQuorumHash,
195  const WhileWaitFunc& runWhileWaiting)
196 {
197  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - starting, curPhase=%d, nextPhase=%d\n", __func__, params.name, curPhase, nextPhase);
198 
199  while (true) {
200  if (stopRequested || ShutdownRequested()) {
201  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - aborting due to stop/shutdown requested\n", __func__, params.name);
202  throw AbortPhaseException();
203  }
204  auto p = GetPhaseAndQuorumHash();
205  if (!expectedQuorumHash.IsNull() && p.second != expectedQuorumHash) {
206  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - aborting due unexpected expectedQuorumHash change\n", __func__, params.name);
207  throw AbortPhaseException();
208  }
209  if (p.first == nextPhase) {
210  break;
211  }
212  if (curPhase != QuorumPhase_None && p.first != curPhase) {
213  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - aborting due unexpected phase change\n", __func__, params.name);
214  throw AbortPhaseException();
215  }
216  if (!runWhileWaiting()) {
217  MilliSleep(100);
218  }
219  }
220 
221  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - done, curPhase=%d, nextPhase=%d\n", __func__, params.name, curPhase, nextPhase);
222 
223  if (nextPhase == QuorumPhase_Initialized) {
225  } else {
227  bool changed = status.phase != (uint8_t) nextPhase;
228  status.phase = (uint8_t) nextPhase;
229  return changed;
230  });
231  }
232 }
233 
235 {
236  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - starting\n", __func__, params.name);
237 
238  while (true) {
239  if (stopRequested || ShutdownRequested()) {
240  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - aborting due to stop/shutdown requested\n", __func__, params.name);
241  throw AbortPhaseException();
242  }
243  auto p = GetPhaseAndQuorumHash();
244  if (p.second != oldQuorumHash) {
245  break;
246  }
247  MilliSleep(100);
248  }
249 
250  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - done\n", __func__, params.name);
251 }
252 
253 // Sleep some time to not fully overload the whole network
255  const uint256& expectedQuorumHash,
256  double randomSleepFactor,
257  const WhileWaitFunc& runWhileWaiting)
258 {
259  if (!curSession->AreWeMember()) {
260  // Non-members do not participate and do not create any network load, no need to sleep.
261  return;
262  }
263 
264  if (Params().MineBlocksOnDemand()) {
265  // On regtest, blocks can be mined on demand without any significant time passing between these.
266  // We shouldn't wait before phases in this case.
267  return;
268  }
269 
270  // Two blocks can come very close to each other, this happens pretty regularly. We don't want to be
271  // left behind and marked as a bad member. This means that we should not count the last block of the
272  // phase as a safe one to keep sleeping, that's why we calculate the phase sleep time as a time of
273  // the full phase minus one block here.
274  double phaseSleepTime = (params.dkgPhaseBlocks - 1) * Params().GetConsensus().nPowTargetSpacing * 1000;
275  // Expected phase sleep time per member
276  double phaseSleepTimePerMember = phaseSleepTime / params.size;
277  // Don't expect perfect block times and thus reduce the phase time to be on the secure side (caller chooses factor)
278  double adjustedPhaseSleepTimePerMember = phaseSleepTimePerMember * randomSleepFactor;
279 
280  int64_t sleepTime = (int64_t)(adjustedPhaseSleepTimePerMember * curSession->GetMyMemberIndex());
281  int64_t endTime = GetTimeMillis() + sleepTime;
282  int heightTmp{-1};
283  int heightStart{-1};
284  {
285  LOCK(cs);
286  heightTmp = heightStart = currentHeight;
287  }
288 
289  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - starting sleep for %d ms, curPhase=%d\n", __func__, params.name, sleepTime, curPhase);
290 
291  while (GetTimeMillis() < endTime) {
292  if (stopRequested || ShutdownRequested()) {
293  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - aborting due to stop/shutdown requested\n", __func__, params.name);
294  throw AbortPhaseException();
295  }
296  {
297  LOCK(cs);
298  if (currentHeight > heightTmp) {
299  // New block(s) just came in
300  int64_t expectedBlockTime = (currentHeight - heightStart) * Params().GetConsensus().nPowTargetSpacing * 1000;
301  if (expectedBlockTime > sleepTime) {
302  // Blocks came faster than we expected, jump into the phase func asap
303  break;
304  }
305  heightTmp = currentHeight;
306  }
307  if (phase != curPhase || quorumHash != expectedQuorumHash) {
308  // Smth went wrong and/or we missed quite a few blocks and it's just too late now
309  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - aborting due unexpected phase/expectedQuorumHash change\n", __func__, params.name);
310  throw AbortPhaseException();
311  }
312  }
313  if (!runWhileWaiting()) {
314  MilliSleep(100);
315  }
316  }
317 
318  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - done, curPhase=%d\n", __func__, params.name, curPhase);
319 }
320 
322  QuorumPhase nextPhase,
323  const uint256& expectedQuorumHash,
324  double randomSleepFactor,
325  const StartPhaseFunc& startPhaseFunc,
326  const WhileWaitFunc& runWhileWaiting)
327 {
328  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - starting, curPhase=%d, nextPhase=%d\n", __func__, params.name, curPhase, nextPhase);
329 
330  SleepBeforePhase(curPhase, expectedQuorumHash, randomSleepFactor, runWhileWaiting);
331  startPhaseFunc();
332  WaitForNextPhase(curPhase, nextPhase, expectedQuorumHash, runWhileWaiting);
333 
334  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - done, curPhase=%d, nextPhase=%d\n", __func__, params.name, curPhase, nextPhase);
335 }
336 
337 // returns a set of NodeIds which sent invalid messages
338 template<typename Message>
339 std::set<NodeId> BatchVerifyMessageSigs(CDKGSession& session, const std::vector<std::pair<NodeId, std::shared_ptr<Message>>>& messages)
340 {
341  if (messages.empty()) {
342  return {};
343  }
344 
345  std::set<NodeId> ret;
346  bool revertToSingleVerification = false;
347 
348  CBLSSignature aggSig;
349  std::vector<CBLSPublicKey> pubKeys;
350  std::vector<uint256> messageHashes;
351  std::set<uint256> messageHashesSet;
352  pubKeys.reserve(messages.size());
353  messageHashes.reserve(messages.size());
354  bool first = true;
355  for (const auto& p : messages ) {
356  const auto& msg = *p.second;
357 
358  auto member = session.GetMember(msg.proTxHash);
359  if (!member) {
360  // should not happen as it was verified before
361  ret.emplace(p.first);
362  continue;
363  }
364 
365  if (first) {
366  aggSig = msg.sig;
367  } else {
368  aggSig.AggregateInsecure(msg.sig);
369  }
370  first = false;
371 
372  auto msgHash = msg.GetSignHash();
373  if (!messageHashesSet.emplace(msgHash).second) {
374  // can only happen in 2 cases:
375  // 1. Someone sent us the same message twice but with differing signature, meaning that at least one of them
376  // must be invalid. In this case, we'd have to revert to single message verification nevertheless
377  // 2. Someone managed to find a way to create two different binary representations of a message that deserializes
378  // to the same object representation. This would be some form of malleability. However, this shouldn't be
379  // possible as only deterministic/unique BLS signatures and very simple data types are involved
380  revertToSingleVerification = true;
381  break;
382  }
383 
384  pubKeys.emplace_back(member->dmn->pdmnState->pubKeyOperator.Get());
385  messageHashes.emplace_back(msgHash);
386  }
387  if (!revertToSingleVerification) {
388  bool valid = aggSig.VerifyInsecureAggregated(pubKeys, messageHashes);
389  if (valid) {
390  // all good
391  return ret;
392  }
393 
394  // are all messages from the same node?
395  NodeId firstNodeId;
396  first = true;
397  bool nodeIdsAllSame = true;
398  for (auto it = messages.begin(); it != messages.end(); ++it) {
399  if (first) {
400  firstNodeId = it->first;
401  } else {
402  first = false;
403  if (it->first != firstNodeId) {
404  nodeIdsAllSame = false;
405  break;
406  }
407  }
408  }
409  // if yes, take a short path and return a set with only him
410  if (nodeIdsAllSame) {
411  ret.emplace(firstNodeId);
412  return ret;
413  }
414  // different nodes, let's figure out who are the bad ones
415  }
416 
417  for (const auto& p : messages) {
418  if (ret.count(p.first)) {
419  continue;
420  }
421 
422  const auto& msg = *p.second;
423  auto member = session.GetMember(msg.proTxHash);
424  bool valid = msg.sig.VerifyInsecure(member->dmn->pdmnState->pubKeyOperator.Get(), msg.GetSignHash());
425  if (!valid) {
426  ret.emplace(p.first);
427  }
428  }
429  return ret;
430 }
431 
432 template<typename Message, int MessageType>
433 bool ProcessPendingMessageBatch(CDKGSession& session, CDKGPendingMessages& pendingMessages, size_t maxCount)
434 {
435  auto msgs = pendingMessages.PopAndDeserializeMessages<Message>(maxCount);
436  if (msgs.empty()) {
437  return false;
438  }
439 
440  std::vector<uint256> hashes;
441  std::vector<std::pair<NodeId, std::shared_ptr<Message>>> preverifiedMessages;
442  hashes.reserve(msgs.size());
443  preverifiedMessages.reserve(msgs.size());
444 
445  for (const auto& p : msgs) {
446  if (!p.second) {
447  LogPrint(BCLog::LLMQ_DKG, "%s -- failed to deserialize message, peer=%d\n", __func__, p.first);
448  {
449  LOCK(cs_main);
450  Misbehaving(p.first, 100);
451  }
452  continue;
453  }
454  const auto& msg = *p.second;
455 
456  auto hash = ::SerializeHash(msg);
457  {
458  LOCK(cs_main);
459  EraseObjectRequest(p.first, CInv(MessageType, hash));
460  }
461 
462  bool ban = false;
463  if (!session.PreVerifyMessage(hash, msg, ban)) {
464  if (ban) {
465  LogPrint(BCLog::LLMQ_DKG, "%s -- banning node due to failed preverification, peer=%d\n", __func__, p.first);
466  {
467  LOCK(cs_main);
468  Misbehaving(p.first, 100);
469  }
470  }
471  LogPrint(BCLog::LLMQ_DKG, "%s -- skipping message due to failed preverification, peer=%d\n", __func__, p.first);
472  continue;
473  }
474  hashes.emplace_back(hash);
475  preverifiedMessages.emplace_back(p);
476  }
477  if (preverifiedMessages.empty()) {
478  return true;
479  }
480 
481  auto badNodes = BatchVerifyMessageSigs(session, preverifiedMessages);
482  if (!badNodes.empty()) {
483  LOCK(cs_main);
484  for (auto nodeId : badNodes) {
485  LogPrint(BCLog::LLMQ_DKG, "%s -- failed to verify signature, peer=%d\n", __func__, nodeId);
486  Misbehaving(nodeId, 100);
487  }
488  }
489 
490  for (size_t i = 0; i < preverifiedMessages.size(); i++) {
491  NodeId nodeId = preverifiedMessages[i].first;
492  if (badNodes.count(nodeId)) {
493  continue;
494  }
495  const auto& msg = *preverifiedMessages[i].second;
496  bool ban = false;
497  session.ReceiveMessage(hashes[i], msg, ban);
498  if (ban) {
499  LogPrint(BCLog::LLMQ_DKG, "%s -- banning node after ReceiveMessage failed, peer=%d\n", __func__, nodeId);
500  LOCK(cs_main);
501  Misbehaving(nodeId, 100);
502  badNodes.emplace(nodeId);
503  }
504  }
505 
506  return true;
507 }
508 
510 {
511  uint256 curQuorumHash;
512  int curQuorumHeight;
513 
515 
516  {
517  LOCK(cs);
522  curQuorumHash = quorumHash;
523  curQuorumHeight = quorumHeight;
524  }
525 
526  const CBlockIndex* pindexQuorum;
527  {
528  LOCK(cs_main);
529  pindexQuorum = mapBlockIndex.at(curQuorumHash);
530  }
531 
532  if (!InitNewQuorum(pindexQuorum)) {
533  // should actually never happen
534  WaitForNewQuorum(curQuorumHash);
535  throw AbortPhaseException();
536  }
537 
539  bool changed = status.phase != (uint8_t) QuorumPhase_Initialized;
540  status.phase = (uint8_t) QuorumPhase_Initialized;
541  return changed;
542  });
543 
544  CLLMQUtils::EnsureQuorumConnections(params.type, pindexQuorum, curSession->myProTxHash, gArgs.GetBoolArg("-watchquorums", DEFAULT_WATCH_QUORUMS));
546  CLLMQUtils::AddQuorumProbeConnections(params.type, pindexQuorum, curSession->myProTxHash);
547  }
548 
549  WaitForNextPhase(QuorumPhase_Initialized, QuorumPhase_Contribute, curQuorumHash, []{return false;});
550 
551  // Contribute
552  auto fContributeStart = [this]() {
553  curSession->Contribute(pendingContributions);
554  };
555  auto fContributeWait = [this] {
556  return ProcessPendingMessageBatch<CDKGContribution, MSG_QUORUM_CONTRIB>(*curSession, pendingContributions, 8);
557  };
558  HandlePhase(QuorumPhase_Contribute, QuorumPhase_Complain, curQuorumHash, 0.05, fContributeStart, fContributeWait);
559 
560  // Complain
561  auto fComplainStart = [this]() {
562  curSession->VerifyAndComplain(pendingComplaints);
563  };
564  auto fComplainWait = [this] {
565  return ProcessPendingMessageBatch<CDKGComplaint, MSG_QUORUM_COMPLAINT>(*curSession, pendingComplaints, 8);
566  };
567  HandlePhase(QuorumPhase_Complain, QuorumPhase_Justify, curQuorumHash, 0.05, fComplainStart, fComplainWait);
568 
569  // Justify
570  auto fJustifyStart = [this]() {
571  curSession->VerifyAndJustify(pendingJustifications);
572  };
573  auto fJustifyWait = [this] {
574  return ProcessPendingMessageBatch<CDKGJustification, MSG_QUORUM_JUSTIFICATION>(*curSession, pendingJustifications, 8);
575  };
576  HandlePhase(QuorumPhase_Justify, QuorumPhase_Commit, curQuorumHash, 0.05, fJustifyStart, fJustifyWait);
577 
578  // Commit
579  auto fCommitStart = [this]() {
580  curSession->VerifyAndCommit(pendingPrematureCommitments);
581  };
582  auto fCommitWait = [this] {
583  return ProcessPendingMessageBatch<CDKGPrematureCommitment, MSG_QUORUM_PREMATURE_COMMITMENT>(*curSession, pendingPrematureCommitments, 8);
584  };
585  HandlePhase(QuorumPhase_Commit, QuorumPhase_Finalize, curQuorumHash, 0.1, fCommitStart, fCommitWait);
586 
587  auto finalCommitments = curSession->FinalizeCommitments();
588  for (const auto& fqc : finalCommitments) {
590  }
591 }
592 
594 {
595  while (!stopRequested && !ShutdownRequested()) {
596  try {
597  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionHandler::%s -- %s - starting HandleDKGRound\n", __func__, params.name);
598  HandleDKGRound();
599  } catch (AbortPhaseException& e) {
601  status.aborted = true;
602  return true;
603  });
604  LogPrint(BCLog::LLMQ_DKG, "CDKGSessionHandler::%s -- %s - aborted current DKG session\n", __func__, params.name);
605  }
606  }
607 }
608 
609 } // namespace llmq
Acts as a FIFO queue for incoming DKG messages.
void write(const char *pch, size_t size)
Definition: hash.h:198
void AddMinableCommitment(const CFinalCommitment &fqc)
void UpdateLocalSessionStatus(Consensus::LLMQType llmqType, std::function< bool(CDKGDebugSessionStatus &status)> &&func)
CDKGPendingMessages pendingContributions
bool ProcessPendingMessageBatch(CDKGSession &session, CDKGPendingMessages &pendingMessages, size_t maxCount)
void TraceThread(const std::string name, Callable func)
Definition: util.h:436
static void AddQuorumProbeConnections(Consensus::LLMQType llmqType, const CBlockIndex *pindexQuorum, const uint256 &myProTxHash)
void MilliSleep(int64_t n)
Definition: utiltime.cpp:75
void PushPendingMessage(NodeId from, CDataStream &vRecv)
const char * QPCOMMITMENT
Definition: protocol.cpp:67
void ReceiveMessage(const uint256 &hash, const CDKGContribution &qc, bool &retBan)
void ProcessMessage(CNode *pfrom, const std::string &strCommand, CDataStream &vRecv, CConnman &connman)
std::function< void()> StartPhaseFunc
bool ShutdownRequested()
Definition: init.cpp:179
#define strprintf
Definition: tinyformat.h:1066
bool HasSeen(const uint256 &hash) const
inv message data
Definition: protocol.h:429
CQuorumBlockProcessor * quorumBlockProcessor
BlockMap & mapBlockIndex
Definition: validation.cpp:215
std::vector< std::pair< NodeId, std::shared_ptr< Message > > > PopAndDeserializeMessages(size_t maxCount)
CCriticalSection cs_main
Definition: validation.cpp:213
CBLSWorker * blsWorker
void ResetLocalSessionStatus(Consensus::LLMQType llmqType)
std::function< bool()> WhileWaitFunc
Definition: box.hpp:161
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:103
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: util.cpp:824
std::set< NodeId > BatchVerifyMessageSigs(CDKGSession &session, const std::vector< std::pair< NodeId, std::shared_ptr< Message >>> &messages)
std::unique_ptr< CDeterministicMNManager > deterministicMNManager
std::string name
Definition: params.h:69
bool IsNull() const
Definition: uint256.h:33
const char * QJUSTIFICATION
Definition: protocol.cpp:66
bool VerifyInsecureAggregated(const std::vector< CBLSPublicKey > &pubKeys, const std::vector< uint256 > &hashes) const
Definition: bls.cpp:348
CDKGMember * GetMember(const uint256 &proTxHash) const
uint256 GetBlockHash() const
Definition: chain.h:292
uint256 SerializeHash(const T &obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
Compute the 256-bit hash of an object&#39;s serialization.
Definition: hash.h:254
void Misbehaving(NodeId pnode, int howmuch, const std::string &message)
Increase a node&#39;s misbehavior score.
bool PreVerifyMessage(const uint256 &hash, const CDKGContribution &qc, bool &retBan) const
#define LOCK2(cs1, cs2)
Definition: sync.h:179
void WaitForNextPhase(QuorumPhase curPhase, QuorumPhase nextPhase, const uint256 &expectedQuorumHash, const WhileWaitFunc &runWhileWaiting)
std::size_t size_t
Definition: bits.hpp:21
std::map< NodeId, size_t > messagesPerNode
#define LogPrintf(...)
Definition: util.h:203
CActiveMasternodeInfo activeMasternodeInfo
CDKGPendingMessages pendingJustifications
bool MineBlocksOnDemand() const
Make miner stop after a block is found.
Definition: chainparams.h:68
#define LOCK(cs)
Definition: sync.h:178
int64_t nPowTargetSpacing
Definition: params.h:176
void SleepBeforePhase(QuorumPhase curPhase, const uint256 &expectedQuorumHash, double randomSleepFactor, const WhileWaitFunc &runWhileWaiting)
void WaitForNewQuorum(const uint256 &oldQuorumHash)
bool InitNewQuorum(const CBlockIndex *pindexQuorum)
int64_t NodeId
Definition: net.h:109
Definition: net.h:136
CDKGDebugManager * quorumDKGDebugManager
std::string ToString() const
Definition: uint256.cpp:62
NodeId GetId() const
Definition: net.h:973
void UpdatedBlockTip(const CBlockIndex *pindexNew)
std::list< BinaryMessage > pendingMessages
The DKG session is a single instance of the DKG process.
#define LogPrint(category,...)
Definition: util.h:214
std::shared_ptr< CDKGSession > curSession
uint256 GetHash()
Definition: hash.h:203
256-bit opaque blob.
Definition: uint256.h:123
ArgsManager gArgs
Definition: util.cpp:108
const char * QCOMPLAINT
Definition: protocol.cpp:65
void AggregateInsecure(const CBLSSignature &o)
Definition: bls.cpp:277
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.
int64_t GetTimeMillis()
Returns the system time (not mockable)
Definition: utiltime.cpp:56
static void EnsureQuorumConnections(Consensus::LLMQType llmqType, const CBlockIndex *pindexQuorum, const uint256 &myProTxHash, bool allowWatch)
void HandlePhase(QuorumPhase curPhase, QuorumPhase nextPhase, const uint256 &expectedQuorumHash, double randomSleepFactor, const StartPhaseFunc &startPhaseFunc, const WhileWaitFunc &runWhileWaiting)
static const bool DEFAULT_WATCH_QUORUMS
Definition: quorums_init.h:15
std::list< BinaryMessage > PopPendingMessages(size_t maxCount)
void EraseObjectRequest(CNodeState *nodestate, const CInv &inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
const char * QCONTRIB
Definition: protocol.cpp:64
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:184
CDKGSessionHandler(const Consensus::LLMQParams &_params, CBLSWorker &blsWorker, CDKGSessionManager &_dkgManager)
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:183
Information about a peer.
Definition: net.h:800
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:54
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: chain.cpp:110
CDKGPendingMessages pendingPrematureCommitments
std::pair< QuorumPhase, uint256 > GetPhaseAndQuorumHash() const
const Consensus::LLMQParams & params
static bool IsAllMembersConnectedEnabled(Consensus::LLMQType llmqType)
static std::vector< CDeterministicMNCPtr > GetAllQuorumMembers(Consensus::LLMQType llmqType, const CBlockIndex *pindexQuorum)
CDKGPendingMessages(size_t _maxMessagesPerNode, int _invType)
Released under the MIT license