Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

quorums_blockprocessor.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_utils.h>
9 
10 #include <evo/specialtx.h>
11 
12 #include <chain.h>
13 #include <chainparams.h>
14 #include <consensus/validation.h>
15 #include <net.h>
16 #include <net_processing.h>
17 #include <primitives/block.h>
18 #include <validation.h>
19 
20 namespace llmq
21 {
22 
24 
25 static const std::string DB_MINED_COMMITMENT = "q_mc";
26 static const std::string DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT = "q_mcih";
27 
28 static const std::string DB_BEST_BLOCK_UPGRADE = "q_bbu2";
29 
30 void CQuorumBlockProcessor::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman)
31 {
32  if (strCommand == NetMsgType::QFCOMMITMENT) {
34  vRecv >> qc;
35 
36  auto hash = ::SerializeHash(qc);
37  {
38  LOCK(cs_main);
40  }
41 
42  if (qc.IsNull()) {
43  LOCK(cs_main);
44  LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- null commitment from peer=%d\n", __func__, pfrom->GetId());
45  Misbehaving(pfrom->GetId(), 100);
46  return;
47  }
48 
49  if (!Params().GetConsensus().llmqs.count((Consensus::LLMQType)qc.llmqType)) {
50  LOCK(cs_main);
51  LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- invalid commitment type %d from peer=%d\n", __func__,
52  qc.llmqType, pfrom->GetId());
53  Misbehaving(pfrom->GetId(), 100);
54  return;
55  }
56  auto type = (Consensus::LLMQType)qc.llmqType;
57  const auto& params = Params().GetConsensus().llmqs.at(type);
58 
59  // Verify that quorumHash is part of the active chain and that it's the first block in the DKG interval
60  const CBlockIndex* pquorumIndex;
61  {
62  LOCK(cs_main);
63  if (!mapBlockIndex.count(qc.quorumHash)) {
64  LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- unknown block %s in commitment, peer=%d\n", __func__,
65  qc.quorumHash.ToString(), pfrom->GetId());
66  // can't really punish the node here, as we might simply be the one that is on the wrong chain or not
67  // fully synced
68  return;
69  }
70  pquorumIndex = mapBlockIndex[qc.quorumHash];
71  if (chainActive.Tip()->GetAncestor(pquorumIndex->nHeight) != pquorumIndex) {
72  LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- block %s not in active chain, peer=%d\n", __func__,
73  qc.quorumHash.ToString(), pfrom->GetId());
74  // same, can't punish
75  return;
76  }
77  int quorumHeight = pquorumIndex->nHeight - (pquorumIndex->nHeight % params.dkgInterval);
78  if (quorumHeight != pquorumIndex->nHeight) {
79  LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- block %s is not the first block in the DKG interval, peer=%d\n", __func__,
80  qc.quorumHash.ToString(), pfrom->GetId());
81  Misbehaving(pfrom->GetId(), 100);
82  return;
83  }
84  }
85 
86  {
87  // Check if we already got a better one locally
88  // We do this before verifying the commitment to avoid DoS
90  auto k = std::make_pair(type, qc.quorumHash);
91  auto it = minableCommitmentsByQuorum.find(k);
92  if (it != minableCommitmentsByQuorum.end()) {
93  auto jt = minableCommitments.find(it->second);
94  if (jt != minableCommitments.end()) {
95  if (jt->second.CountSigners() <= qc.CountSigners()) {
96  return;
97  }
98  }
99  }
100  }
101 
102  auto members = CLLMQUtils::GetAllQuorumMembers(type, pquorumIndex);
103 
104  if (!qc.Verify(members, true)) {
105  LOCK(cs_main);
106  LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- commitment for quorum %s:%d is not valid, peer=%d\n", __func__,
107  qc.quorumHash.ToString(), qc.llmqType, pfrom->GetId());
108  Misbehaving(pfrom->GetId(), 100);
109  return;
110  }
111 
112  LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- received commitment for quorum %s:%d, validMembers=%d, signers=%d, peer=%d\n", __func__,
113  qc.quorumHash.ToString(), qc.llmqType, qc.CountValidMembers(), qc.CountSigners(), pfrom->GetId());
114 
116  }
117 }
118 
120 {
122 
123  bool fDIP0003Active = pindex->nHeight >= Params().GetConsensus().DIP0003Height;
124  if (!fDIP0003Active) {
126  return true;
127  }
128 
129  std::map<Consensus::LLMQType, CFinalCommitment> qcs;
130  if (!GetCommitmentsFromBlock(block, pindex, qcs, state)) {
131  return false;
132  }
133 
134  // The following checks make sure that there is always a (possibly null) commitment while in the mining phase
135  // until the first non-null commitment has been mined. After the non-null commitment, no other commitments are
136  // allowed, including null commitments.
137  for (const auto& p : Params().GetConsensus().llmqs) {
138  // skip these checks when replaying blocks after the crash
139  if (!chainActive.Tip()) {
140  break;
141  }
142 
143  auto type = p.first;
144 
145  // does the currently processed block contain a (possibly null) commitment for the current session?
146  bool hasCommitmentInNewBlock = qcs.count(type) != 0;
147  bool isCommitmentRequired = IsCommitmentRequired(type, pindex->nHeight);
148 
149  if (hasCommitmentInNewBlock && !isCommitmentRequired) {
150  // If we're either not in the mining phase or a non-null commitment was mined already, reject the block
151  return state.DoS(100, false, REJECT_INVALID, "bad-qc-not-allowed");
152  }
153 
154  if (!hasCommitmentInNewBlock && isCommitmentRequired) {
155  // If no non-null commitment was mined for the mining phase yet and the new block does not include
156  // a (possibly null) commitment, the block should be rejected.
157  return state.DoS(100, false, REJECT_INVALID, "bad-qc-missing");
158  }
159  }
160 
161  auto blockHash = block.GetHash();
162 
163  for (auto& p : qcs) {
164  auto& qc = p.second;
165  if (!ProcessCommitment(pindex->nHeight, blockHash, qc, state)) {
166  return false;
167  }
168  }
169 
170  evoDb.Write(DB_BEST_BLOCK_UPGRADE, blockHash);
171 
172  return true;
173 }
174 
175 // We store a mapping from minedHeight->quorumHeight in the DB
176 // minedHeight is inversed so that entries are traversable in reversed order
177 static std::tuple<std::string, Consensus::LLMQType, uint32_t> BuildInversedHeightKey(Consensus::LLMQType llmqType, int nMinedHeight)
178 {
179  // nMinedHeight must be converted to big endian to make it comparable when serialized
180  return std::make_tuple(DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT, llmqType, htobe32(std::numeric_limits<uint32_t>::max() - nMinedHeight));
181 }
182 
183 bool CQuorumBlockProcessor::ProcessCommitment(int nHeight, const uint256& blockHash, const CFinalCommitment& qc, CValidationState& state)
184 {
185  auto& params = Params().GetConsensus().llmqs.at((Consensus::LLMQType)qc.llmqType);
186 
187  uint256 quorumHash = GetQuorumBlockHash((Consensus::LLMQType)qc.llmqType, nHeight);
188 
189  // skip `bad-qc-block` checks below when replaying blocks after the crash
190  if (!chainActive.Tip()) {
191  quorumHash = qc.quorumHash;
192  }
193 
194  if (quorumHash.IsNull()) {
195  return state.DoS(100, false, REJECT_INVALID, "bad-qc-block");
196  }
197  if (quorumHash != qc.quorumHash) {
198  return state.DoS(100, false, REJECT_INVALID, "bad-qc-block");
199  }
200 
201  if (qc.IsNull()) {
202  if (!qc.VerifyNull()) {
203  return state.DoS(100, false, REJECT_INVALID, "bad-qc-invalid-null");
204  }
205  return true;
206  }
207 
208  if (HasMinedCommitment(params.type, quorumHash)) {
209  // should not happen as it's already handled in ProcessBlock
210  return state.DoS(100, false, REJECT_INVALID, "bad-qc-dup");
211  }
212 
213  if (!IsMiningPhase(params.type, nHeight)) {
214  // should not happen as it's already handled in ProcessBlock
215  return state.DoS(100, false, REJECT_INVALID, "bad-qc-height");
216  }
217 
218  auto quorumIndex = mapBlockIndex.at(qc.quorumHash);
219  auto members = CLLMQUtils::GetAllQuorumMembers(params.type, quorumIndex);
220 
221  if (!qc.Verify(members, true)) {
222  return state.DoS(100, false, REJECT_INVALID, "bad-qc-invalid");
223  }
224 
225  // Store commitment in DB
226  evoDb.Write(std::make_pair(DB_MINED_COMMITMENT, std::make_pair(params.type, quorumHash)), std::make_pair(qc, blockHash));
227  evoDb.Write(BuildInversedHeightKey(params.type, nHeight), quorumIndex->nHeight);
228 
229  {
231  hasMinedCommitmentCache.erase(std::make_pair(params.type, quorumHash));
232  }
233 
234  LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- processed commitment from block. type=%d, quorumHash=%s, signers=%s, validMembers=%d, quorumPublicKey=%s\n", __func__,
235  qc.llmqType, quorumHash.ToString(), qc.CountSigners(), qc.CountValidMembers(), qc.quorumPublicKey.ToString());
236 
237  return true;
238 }
239 
240 bool CQuorumBlockProcessor::UndoBlock(const CBlock& block, const CBlockIndex* pindex)
241 {
243 
244  std::map<Consensus::LLMQType, CFinalCommitment> qcs;
245  CValidationState dummy;
246  if (!GetCommitmentsFromBlock(block, pindex, qcs, dummy)) {
247  return false;
248  }
249 
250  for (auto& p : qcs) {
251  auto& qc = p.second;
252  if (qc.IsNull()) {
253  continue;
254  }
255 
256  evoDb.Erase(std::make_pair(DB_MINED_COMMITMENT, std::make_pair(qc.llmqType, qc.quorumHash)));
258  {
260  hasMinedCommitmentCache.erase(std::make_pair((Consensus::LLMQType)qc.llmqType, qc.quorumHash));
261  }
262 
263  // if a reorg happened, we should allow to mine this commitment later
265  }
266 
268 
269  return true;
270 }
271 
272 // TODO remove this with 0.15.0
274 {
275  LOCK(cs_main);
276  uint256 bestBlock;
277  if (evoDb.GetRawDB().Read(DB_BEST_BLOCK_UPGRADE, bestBlock) && bestBlock == chainActive.Tip()->GetBlockHash()) {
278  return;
279  }
280 
281  LogPrintf("CQuorumBlockProcessor::%s -- Upgrading DB...\n", __func__);
282 
285  while (pindex) {
286  if (fPruneMode && !(pindex->nStatus & BLOCK_HAVE_DATA)) {
287  // Too late, we already pruned blocks we needed to reprocess commitments
288  throw std::runtime_error(std::string(__func__) + ": Quorum Commitments DB upgrade failed, you need to re-download the blockchain");
289  }
290  CBlock block;
291  bool r = ReadBlockFromDisk(block, pindex, Params().GetConsensus());
292  assert(r);
293 
294  std::map<Consensus::LLMQType, CFinalCommitment> qcs;
295  CValidationState dummyState;
296  GetCommitmentsFromBlock(block, pindex, qcs, dummyState);
297 
298  for (const auto& p : qcs) {
299  const auto& qc = p.second;
300  if (qc.IsNull()) {
301  continue;
302  }
303  auto quorumIndex = mapBlockIndex.at(qc.quorumHash);
304  evoDb.GetRawDB().Write(std::make_pair(DB_MINED_COMMITMENT, std::make_pair(qc.llmqType, qc.quorumHash)), std::make_pair(qc, pindex->GetBlockHash()));
305  evoDb.GetRawDB().Write(BuildInversedHeightKey((Consensus::LLMQType)qc.llmqType, pindex->nHeight), quorumIndex->nHeight);
306  }
307 
308  evoDb.GetRawDB().Write(DB_BEST_BLOCK_UPGRADE, pindex->GetBlockHash());
309 
310  pindex = chainActive.Next(pindex);
311  }
312  }
313 
314  LogPrintf("CQuorumBlockProcessor::%s -- Upgrade done...\n", __func__);
315 }
316 
317 bool CQuorumBlockProcessor::GetCommitmentsFromBlock(const CBlock& block, const CBlockIndex* pindex, std::map<Consensus::LLMQType, CFinalCommitment>& ret, CValidationState& state)
318 {
320 
321  auto& consensus = Params().GetConsensus();
322  bool fDIP0003Active = pindex->nHeight >= consensus.DIP0003Height;
323 
324  ret.clear();
325 
326  for (const auto& tx : block.vtx) {
327  if (tx->nType == TRANSACTION_QUORUM_COMMITMENT) {
329  if (!GetTxPayload(*tx, qc)) {
330  // should not happen as it was verified before processing the block
331  return state.DoS(100, false, REJECT_INVALID, "bad-qc-payload");
332  }
333 
334  // only allow one commitment per type and per block
335  if (ret.count((Consensus::LLMQType)qc.commitment.llmqType)) {
336  return state.DoS(100, false, REJECT_INVALID, "bad-qc-dup");
337  }
338 
339  ret.emplace((Consensus::LLMQType)qc.commitment.llmqType, std::move(qc.commitment));
340  }
341  }
342 
343  if (!fDIP0003Active && !ret.empty()) {
344  return state.DoS(100, false, REJECT_INVALID, "bad-qc-premature");
345  }
346 
347  return true;
348 }
349 
351 {
352  const auto& params = Params().GetConsensus().llmqs.at(llmqType);
353  int phaseIndex = nHeight % params.dkgInterval;
354  if (phaseIndex >= params.dkgMiningWindowStart && phaseIndex <= params.dkgMiningWindowEnd) {
355  return true;
356  }
357  return false;
358 }
359 
361 {
362  uint256 quorumHash = GetQuorumBlockHash(llmqType, nHeight);
363 
364  // perform extra check for quorumHash.IsNull as the quorum hash is unknown for the first block of a session
365  // this is because the currently processed block's hash will be the quorumHash of this session
366  bool isMiningPhase = !quorumHash.IsNull() && IsMiningPhase(llmqType, nHeight);
367 
368  // did we already mine a non-null commitment for this session?
369  bool hasMinedCommitment = !quorumHash.IsNull() && HasMinedCommitment(llmqType, quorumHash);
370 
371  return isMiningPhase && !hasMinedCommitment;
372 }
373 
374 // WARNING: This method returns uint256() on the first block of the DKG interval (because the block hash is not known yet)
376 {
378 
379  auto& params = Params().GetConsensus().llmqs.at(llmqType);
380 
381  int quorumStartHeight = nHeight - (nHeight % params.dkgInterval);
382  uint256 quorumBlockHash;
383  if (!GetBlockHash(quorumBlockHash, quorumStartHeight)) {
384  return uint256();
385  }
386  return quorumBlockHash;
387 }
388 
390 {
391  auto cacheKey = std::make_pair(llmqType, quorumHash);
392  {
394  auto cacheIt = hasMinedCommitmentCache.find(cacheKey);
395  if (cacheIt != hasMinedCommitmentCache.end()) {
396  return cacheIt->second;
397  }
398  }
399 
400  auto key = std::make_pair(DB_MINED_COMMITMENT, std::make_pair(llmqType, quorumHash));
401  bool ret = evoDb.Exists(key);
402 
404  hasMinedCommitmentCache.emplace(cacheKey, ret);
405  return ret;
406 }
407 
408 bool CQuorumBlockProcessor::GetMinedCommitment(Consensus::LLMQType llmqType, const uint256& quorumHash, CFinalCommitment& retQc, uint256& retMinedBlockHash)
409 {
410  auto key = std::make_pair(DB_MINED_COMMITMENT, std::make_pair(llmqType, quorumHash));
411  std::pair<CFinalCommitment, uint256> p;
412  if (!evoDb.Read(key, p)) {
413  return false;
414  }
415  retQc = std::move(p.first);
416  retMinedBlockHash = p.second;
417  return true;
418 }
419 
420 // The returned quorums are in reversed order, so the most recent one is at index 0
421 std::vector<const CBlockIndex*> CQuorumBlockProcessor::GetMinedCommitmentsUntilBlock(Consensus::LLMQType llmqType, const CBlockIndex* pindex, size_t maxCount)
422 {
423  LOCK(evoDb.cs);
424 
426 
427  auto firstKey = BuildInversedHeightKey(llmqType, pindex->nHeight);
428  auto lastKey = BuildInversedHeightKey(llmqType, 0);
429 
430  dbIt->Seek(firstKey);
431 
432  std::vector<const CBlockIndex*> ret;
433  ret.reserve(maxCount);
434 
435  while (dbIt->Valid() && ret.size() < maxCount) {
436  decltype(firstKey) curKey;
437  int quorumHeight;
438  if (!dbIt->GetKey(curKey) || curKey >= lastKey) {
439  break;
440  }
441  if (std::get<0>(curKey) != DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT || std::get<1>(curKey) != llmqType) {
442  break;
443  }
444 
445  uint32_t nMinedHeight = std::numeric_limits<uint32_t>::max() - be32toh(std::get<2>(curKey));
446  if (nMinedHeight > pindex->nHeight) {
447  break;
448  }
449 
450  if (!dbIt->GetValue(quorumHeight)) {
451  break;
452  }
453 
454  auto quorumIndex = pindex->GetAncestor(quorumHeight);
455  assert(quorumIndex);
456  ret.emplace_back(quorumIndex);
457 
458  dbIt->Next();
459  }
460 
461  return ret;
462 }
463 
464 // The returned quorums are in reversed order, so the most recent one is at index 0
465 std::map<Consensus::LLMQType, std::vector<const CBlockIndex*>> CQuorumBlockProcessor::GetMinedAndActiveCommitmentsUntilBlock(const CBlockIndex* pindex)
466 {
467  std::map<Consensus::LLMQType, std::vector<const CBlockIndex*>> ret;
468 
469  for (const auto& p : Params().GetConsensus().llmqs) {
470  auto& v = ret[p.second.type];
471  v.reserve(p.second.signingActiveQuorumCount);
472  auto commitments = GetMinedCommitmentsUntilBlock(p.second.type, pindex, p.second.signingActiveQuorumCount);
473  for (auto& c : commitments) {
474  v.emplace_back(c);
475  }
476  }
477 
478  return ret;
479 }
480 
482 {
484  return minableCommitments.count(hash) != 0;
485 }
486 
488 {
489  bool relay = false;
490  uint256 commitmentHash = ::SerializeHash(fqc);
491 
492  {
494 
495  auto k = std::make_pair((Consensus::LLMQType) fqc.llmqType, fqc.quorumHash);
496  auto ins = minableCommitmentsByQuorum.emplace(k, commitmentHash);
497  if (ins.second) {
498  minableCommitments.emplace(commitmentHash, fqc);
499  relay = true;
500  } else {
501  auto& oldFqc = minableCommitments.at(ins.first->second);
502  if (fqc.CountSigners() > oldFqc.CountSigners()) {
503  // new commitment has more signers, so override the known one
504  ins.first->second = commitmentHash;
505  minableCommitments.erase(ins.first->second);
506  minableCommitments.emplace(commitmentHash, fqc);
507  relay = true;
508  }
509  }
510  }
511 
512  // We only relay the new commitment if it's new or better then the old one
513  if (relay) {
514  CInv inv(MSG_QUORUM_FINAL_COMMITMENT, commitmentHash);
515  g_connman->RelayInv(inv, DMN_PROTO_VERSION);
516  }
517 }
518 
520 {
522  auto it = minableCommitments.find(commitmentHash);
523  if (it == minableCommitments.end()) {
524  return false;
525  }
526  ret = it->second;
527  return true;
528 }
529 
530 // Will return false if no commitment should be mined
531 // Will return true and a null commitment if no minable commitment is known and none was mined yet
533 {
535 
536  if (!IsCommitmentRequired(llmqType, nHeight)) {
537  // no commitment required
538  return false;
539  }
540 
541  uint256 quorumHash = GetQuorumBlockHash(llmqType, nHeight);
542  if (quorumHash.IsNull()) {
543  return false;
544  }
545 
547 
548  auto k = std::make_pair(llmqType, quorumHash);
549  auto it = minableCommitmentsByQuorum.find(k);
550  if (it == minableCommitmentsByQuorum.end()) {
551  // null commitment required
552  ret = CFinalCommitment(Params().GetConsensus().llmqs.at(llmqType), quorumHash);
553  return true;
554  }
555 
556  ret = minableCommitments.at(it->second);
557 
558  return true;
559 }
560 
562 {
564 
566  if (!GetMinableCommitment(llmqType, nHeight, qc.commitment)) {
567  return false;
568  }
569 
570  qc.nHeight = nHeight;
571 
573  tx.nVersion = 3;
575  SetTxPayload(tx, qc);
576 
577  ret = MakeTransactionRef(tx);
578 
579  return true;
580 }
581 
582 } // namespace llmq
void Erase(const K &key)
Definition: evodb.h:83
bool GetTxPayload(const std::vector< unsigned char > &payload, T &obj)
Definition: specialtx.h:21
bool GetBlockHash(uint256 &hashRet, int nBlockHeight)
Return true if hash can be found in chainActive at nBlockHeight height.
static const int DMN_PROTO_VERSION
introduction of DIP3/deterministic masternodes
Definition: version.h:48
void AddMinableCommitment(const CFinalCommitment &fqc)
bool fPruneMode
True if we&#39;re running in -prune mode.
Definition: validation.cpp:230
bool Exists(const K &key)
Definition: evodb.h:76
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:177
bool IsCommitmentRequired(Consensus::LLMQType llmqType, int nHeight)
Definition: block.h:72
const char * QFCOMMITMENT
Definition: protocol.cpp:63
inv message data
Definition: protocol.h:429
CQuorumBlockProcessor * quorumBlockProcessor
CCriticalSection cs
Definition: evodb.h:35
BlockMap & mapBlockIndex
Definition: validation.cpp:215
void Write(const K &key, const V &value)
Definition: evodb.h:69
int Height() const
Return the maximal height in the chain.
Definition: chain.h:484
CCriticalSection cs_main
Definition: validation.cpp:213
bool Read(const K &key, V &value)
Definition: evodb.h:62
bool DoS(int level, bool ret=false, unsigned int chRejectCodeIn=0, const std::string &strRejectReasonIn="", bool corruptionIn=false, const std::string &strDebugMessageIn="")
Definition: validation.h:36
bool GetMinableCommitmentTx(Consensus::LLMQType llmqType, int nHeight, CTransactionRef &ret)
Consensus::LLMQType llmqType
uint32_t be32toh(uint32_t big_endian_32bits)
Definition: endian.h:198
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:103
bool ProcessBlock(const CBlock &block, const CBlockIndex *pindex, CValidationState &state)
static const std::string DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT
bool HasMinedCommitment(Consensus::LLMQType llmqType, const uint256 &quorumHash)
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:345
static const unsigned char REJECT_INVALID
Definition: validation.h:13
bool IsNull() const
Definition: uint256.h:33
CDBWrapper & GetRawDB()
Definition: evodb.h:89
uint32_t htobe32(uint32_t host_32bits)
Definition: endian.h:184
static const std::string DB_MINED_COMMITMENT
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.
static CTransactionRef MakeTransactionRef()
Definition: transaction.h:346
LLMQType
Definition: params.h:48
#define LogPrintf(...)
Definition: util.h:203
std::map< Consensus::LLMQType, std::vector< const CBlockIndex * > > GetMinedAndActiveCommitmentsUntilBlock(const CBlockIndex *pindex)
std::string ToString() const
Definition: bls.h:210
#define LOCK(cs)
Definition: sync.h:178
void ProcessMessage(CNode *pfrom, const std::string &strCommand, CDataStream &vRecv, CConnman &connman)
CBlockIndex * Next(const CBlockIndex *pindex) const
Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip...
Definition: chain.h:476
int DIP0003Height
Block height at which DIP0003 becomes active.
Definition: params.h:158
CurTransaction & GetCurTransaction()
Definition: evodb.h:55
Definition: net.h:136
std::string ToString() const
Definition: uint256.cpp:62
NodeId GetId() const
Definition: net.h:973
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:273
std::map< LLMQType, LLMQParams > llmqs
Definition: params.h:189
bool GetMinableCommitmentByHash(const uint256 &commitmentHash, CFinalCommitment &ret)
bool HasMinableCommitment(const uint256 &hash)
#define LogPrint(category,...)
Definition: util.h:214
int DIP0003EnforcementHeight
Block height at which DIP0003 becomes enforced.
Definition: params.h:160
uint256 GetHash() const
Definition: block.cpp:14
Capture information about block/transaction validation.
Definition: validation.h:22
bool GetMinedCommitment(Consensus::LLMQType llmqType, const uint256 &quorumHash, CFinalCommitment &ret, uint256 &retMinedBlockHash)
256-bit opaque blob.
Definition: uint256.h:123
bool IsMiningPhase(Consensus::LLMQType llmqType, int nHeight)
bool Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:298
std::vector< CTransactionRef > vtx
Definition: block.h:76
static const std::string DB_BEST_BLOCK_UPGRADE
bool GetCommitmentsFromBlock(const CBlock &block, const CBlockIndex *pindex, std::map< Consensus::LLMQType, CFinalCommitment > &ret, CValidationState &state)
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.
bool UndoBlock(const CBlock &block, const CBlockIndex *pindex)
std::map< std::pair< Consensus::LLMQType, uint256 >, uint256 > minableCommitmentsByQuorum
std::unordered_map< std::pair< Consensus::LLMQType, uint256 >, bool, StaticSaltedHasher > hasMinedCommitmentCache
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:453
bool GetMinableCommitment(Consensus::LLMQType llmqType, int nHeight, CFinalCommitment &ret)
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:97
bool Verify(const std::vector< CDeterministicMNCPtr > &members, bool checkSigs) const
static std::tuple< std::string, Consensus::LLMQType, uint32_t > BuildInversedHeightKey(Consensus::LLMQType llmqType, int nMinedHeight)
void EraseObjectRequest(CNodeState *nodestate, const CInv &inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
A mutable version of CTransaction.
Definition: transaction.h:291
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
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: chain.cpp:110
full block available in blk*.dat
Definition: chain.h:154
std::unique_ptr< CDBTransactionIterator< CDBTransaction > > NewIteratorUniquePtr()
Definition: dbwrapper.h:722
CChain & chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:217
AssertLockHeld(g_cs_orphans)
std::vector< const CBlockIndex * > GetMinedCommitmentsUntilBlock(Consensus::LLMQType llmqType, const CBlockIndex *pindex, size_t maxCount)
void SetTxPayload(CMutableTransaction &tx, const T &payload)
Definition: specialtx.h:43
static std::vector< CDeterministicMNCPtr > GetAllQuorumMembers(Consensus::LLMQType llmqType, const CBlockIndex *pindexQuorum)
std::map< uint256, CFinalCommitment > minableCommitments
uint256 GetQuorumBlockHash(Consensus::LLMQType llmqType, int nHeight)
bool ProcessCommitment(int nHeight, const uint256 &blockHash, const CFinalCommitment &qc, CValidationState &state)
Released under the MIT license