Bitcoin ABC  0.24.7
P2P Digital Currency
processor.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018-2019 The Bitcoin 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 <avalanche/processor.h>
6 
9 #include <avalanche/validation.h>
10 #include <avalanche/voterecord.h>
11 #include <chain.h>
12 #include <key_io.h> // For DecodeSecret
13 #include <net.h>
14 #include <netmessagemaker.h>
15 #include <reverse_iterator.h>
16 #include <scheduler.h>
17 #include <util/bitmanip.h>
18 #include <util/translation.h>
19 #include <validation.h>
20 
21 #include <chrono>
22 #include <tuple>
23 
27 static constexpr std::chrono::milliseconds AVALANCHE_TIME_STEP{10};
28 
29 // Unfortunately, the bitcoind codebase is full of global and we are kinda
30 // forced into it here.
31 std::unique_ptr<avalanche::Processor> g_avalanche;
32 
33 namespace avalanche {
34 static bool IsWorthPolling(const CBlockIndex *pindex)
37 
38  if (pindex->nStatus.isInvalid()) {
39  // No point polling invalid blocks.
40  return false;
41  }
42 
43  if (::ChainstateActive().IsBlockFinalized(pindex)) {
44  // There is no point polling finalized block.
45  return false;
46  }
47 
48  return true;
49 }
50 
51 static bool VerifyProof(const Proof &proof, bilingual_str &error) {
52  ProofValidationState proof_state;
53 
54  if (!proof.verify(proof_state)) {
55  switch (proof_state.GetResult()) {
57  error = _("The avalanche proof has no stake.");
58  return false;
60  error = _("The avalanche proof stake is too low.");
61  return false;
63  error = _("The avalanche proof has duplicated stake.");
64  return false;
66  error = _("The avalanche proof has invalid stake signatures.");
67  return false;
69  error = strprintf(
70  _("The avalanche proof has too many utxos (max: %u)."),
72  return false;
73  default:
74  error = _("The avalanche proof is invalid.");
75  return false;
76  }
77  }
78 
79  return true;
80 }
81 
82 static bool VerifyDelegation(const Delegation &dg,
83  const CPubKey &expectedPubKey,
85  DelegationState dg_state;
86 
87  CPubKey auth;
88  if (!dg.verify(dg_state, auth)) {
89  switch (dg_state.GetResult()) {
91  error = _("The avalanche delegation has invalid signatures.");
92  return false;
93  default:
94  error = _("The avalanche delegation is invalid.");
95  return false;
96  }
97  }
98 
99  if (auth != expectedPubKey) {
100  error = _(
101  "The avalanche delegation does not match the expected public key.");
102  return false;
103  }
104 
105  return true;
106 }
107 
111 };
112 
116 
117 public:
119 
120  void updatedBlockTip() override {
122 
123  if (m_processor->peerData && m_processor->peerData->proof) {
124  m_processor->peerManager->registerProof(
125  m_processor->peerData->proof);
126  }
127 
128  m_processor->peerManager->updatedBlockTip();
129  }
130 };
131 
133  std::unique_ptr<PeerData> peerDataIn, CKey sessionKeyIn)
134  : connman(connmanIn), queryTimeoutDuration(AVALANCHE_DEFAULT_QUERY_TIMEOUT),
135  round(0), peerManager(std::make_unique<PeerManager>()),
136  peerData(std::move(peerDataIn)), sessionKey(std::move(sessionKeyIn)) {
137  // Make sure we get notified of chain state changes.
139  chain.handleNotifications(std::make_shared<NotificationsHandler>(this));
140 }
141 
144  stopEventLoop();
145 }
146 
147 std::unique_ptr<Processor> Processor::MakeProcessor(const ArgsManager &argsman,
148  interfaces::Chain &chain,
149  CConnman *connman,
150  bilingual_str &error) {
151  std::unique_ptr<PeerData> peerData;
152  CKey masterKey;
154 
155  if (argsman.IsArgSet("-avasessionkey")) {
156  sessionKey = DecodeSecret(argsman.GetArg("-avasessionkey", ""));
157  if (!sessionKey.IsValid()) {
158  error = _("The avalanche session key is invalid.");
159  return nullptr;
160  }
161  } else {
162  // Pick a random key for the session.
163  sessionKey.MakeNewKey(true);
164  }
165 
166  if (argsman.IsArgSet("-avaproof")) {
167  if (!argsman.IsArgSet("-avamasterkey")) {
168  error = _(
169  "The avalanche master key is missing for the avalanche proof.");
170  return nullptr;
171  }
172 
173  masterKey = DecodeSecret(argsman.GetArg("-avamasterkey", ""));
174  if (!masterKey.IsValid()) {
175  error = _("The avalanche master key is invalid.");
176  return nullptr;
177  }
178 
179  peerData = std::make_unique<PeerData>();
180  Proof proof;
181  if (!Proof::FromHex(proof, argsman.GetArg("-avaproof", ""), error)) {
182  // error is set by FromHex
183  return nullptr;
184  }
185  peerData->proof = std::make_shared<Proof>(std::move(proof));
186 
187  if (!VerifyProof(*peerData->proof, error)) {
188  // error is set by VerifyProof
189  return nullptr;
190  }
191 
192  std::unique_ptr<DelegationBuilder> dgb;
193  const CPubKey &masterPubKey = masterKey.GetPubKey();
194 
195  if (argsman.IsArgSet("-avadelegation")) {
196  Delegation dg;
197  if (!Delegation::FromHex(dg, argsman.GetArg("-avadelegation", ""),
198  error)) {
199  // error is set by FromHex()
200  return nullptr;
201  }
202 
203  if (dg.getProofId() != peerData->proof->getId()) {
204  error = _("The delegation does not match the proof.");
205  return nullptr;
206  }
207 
208  if (masterPubKey != dg.getDelegatedPubkey()) {
209  error = _(
210  "The master key does not match the delegation public key.");
211  return nullptr;
212  }
213 
214  dgb = std::make_unique<DelegationBuilder>(dg);
215  } else {
216  if (masterPubKey != peerData->proof->getMaster()) {
217  error =
218  _("The master key does not match the proof public key.");
219  return nullptr;
220  }
221 
222  dgb = std::make_unique<DelegationBuilder>(*peerData->proof);
223  }
224 
225  // Generate the delegation to the session key.
226  const CPubKey sessionPubKey = sessionKey.GetPubKey();
227  if (sessionPubKey != masterPubKey) {
228  if (!dgb->addLevel(masterKey, sessionPubKey)) {
229  error = _("Failed to generate a delegation for this session.");
230  return nullptr;
231  }
232  }
233  peerData->delegation = dgb->build();
234 
235  if (!VerifyDelegation(peerData->delegation, sessionPubKey, error)) {
236  // error is set by VerifyDelegation
237  return nullptr;
238  }
239  }
240 
241  // We can't use std::make_unique with a private constructor
242  return std::unique_ptr<Processor>(new Processor(
243  chain, connman, std::move(peerData), std::move(sessionKey)));
244 }
245 
247  bool isAccepted;
248 
249  {
250  LOCK(cs_main);
251  if (!IsWorthPolling(pindex)) {
252  // There is no point polling this block.
253  return false;
254  }
255 
256  isAccepted = ::ChainActive().Contains(pindex);
257  }
258 
260  ->insert(std::make_pair(pindex, VoteRecord(isAccepted)))
261  .second;
262 }
263 
265  // TODO We don't want to accept an infinite number of conflicting proofs.
266  // They should be some rules to make them expensive and/or limited by
267  // design.
268  const bool isAccepted = WITH_LOCK(
269  cs_peerManager, return peerManager->isBoundToPeer(proof->getId()));
270 
271  proofVoteRecords.getWriteView()->insert(
272  std::make_pair(proof, VoteRecord(isAccepted)));
273 }
274 
275 bool Processor::isAccepted(const CBlockIndex *pindex) const {
276  auto r = blockVoteRecords.getReadView();
277  auto it = r->find(pindex);
278  if (it == r.end()) {
279  return false;
280  }
281 
282  return it->second.isAccepted();
283 }
284 
285 bool Processor::isAccepted(const ProofRef &proof) const {
286  auto r = proofVoteRecords.getReadView();
287  auto it = r->find(proof);
288  if (it == r.end()) {
289  return false;
290  }
291 
292  return it->second.isAccepted();
293 }
294 
295 int Processor::getConfidence(const CBlockIndex *pindex) const {
296  auto r = blockVoteRecords.getReadView();
297  auto it = r->find(pindex);
298  if (it == r.end()) {
299  return -1;
300  }
301 
302  return it->second.getConfidence();
303 }
304 
305 int Processor::getConfidence(const ProofRef &proof) const {
306  auto r = proofVoteRecords.getReadView();
307  auto it = r->find(proof);
308  if (it == r.end()) {
309  return -1;
310  }
311 
312  return it->second.getConfidence();
313 }
314 
315 namespace {
320  class TCPResponse {
321  Response response;
323 
324  public:
325  TCPResponse(Response responseIn, const CKey &key)
326  : response(std::move(responseIn)) {
327  CHashWriter hasher(SER_GETHASH, 0);
328  hasher << response;
329  const uint256 hash = hasher.GetHash();
330 
331  // Now let's sign!
332  if (!key.SignSchnorr(hash, sig)) {
333  sig.fill(0);
334  }
335  }
336 
337  // serialization support
338  SERIALIZE_METHODS(TCPResponse, obj) {
339  READWRITE(obj.response, obj.sig);
340  }
341  };
342 } // namespace
343 
346  pfrom, CNetMsgMaker(pfrom->GetCommonVersion())
348  TCPResponse(std::move(response), sessionKey)));
349 }
350 
352  std::vector<BlockUpdate> &blockUpdates,
353  std::vector<ProofUpdate> &proofUpdates,
354  int &banscore, std::string &error) {
355  {
356  // Save the time at which we can query again.
358 
359  // FIXME: This will override the time even when we received an old stale
360  // message. This should check that the message is indeed the most up to
361  // date one before updating the time.
362  peerManager->updateNextRequestTime(
363  nodeid, std::chrono::steady_clock::now() +
364  std::chrono::milliseconds(response.getCooldown()));
365  }
366 
367  std::vector<CInv> invs;
368 
369  {
370  // Check that the query exists.
371  auto w = queries.getWriteView();
372  auto it = w->find(std::make_tuple(nodeid, response.getRound()));
373  if (it == w.end()) {
374  banscore = 2;
375  error = "unexpected-ava-response";
376  return false;
377  }
378 
379  invs = std::move(it->invs);
380  w->erase(it);
381  }
382 
383  // Verify that the request and the vote are consistent.
384  const std::vector<Vote> &votes = response.GetVotes();
385  size_t size = invs.size();
386  if (votes.size() != size) {
387  banscore = 100;
388  error = "invalid-ava-response-size";
389  return false;
390  }
391 
392  for (size_t i = 0; i < size; i++) {
393  if (invs[i].hash != votes[i].GetHash()) {
394  banscore = 100;
395  error = "invalid-ava-response-content";
396  return false;
397  }
398  }
399 
400  std::map<CBlockIndex *, Vote> responseIndex;
401  std::map<ProofRef, Vote> responseProof;
402 
403  // At this stage we are certain that invs[i] matches votes[i], so we can use
404  // the inv type to retrieve what is being voted on.
405  for (size_t i = 0; i < size; i++) {
406  if (invs[i].IsMsgBlk()) {
407  CBlockIndex *pindex;
408  {
409  LOCK(cs_main);
410  pindex = LookupBlockIndex(BlockHash(votes[i].GetHash()));
411  if (!pindex) {
412  // This should not happen, but just in case...
413  continue;
414  }
415 
416  if (!IsWorthPolling(pindex)) {
417  // There is no point polling this block.
418  continue;
419  }
420  }
421 
422  responseIndex.insert(std::make_pair(pindex, votes[i]));
423  }
424 
425  if (invs[i].IsMsgProof()) {
426  const ProofId proofid(votes[i].GetHash());
427 
428  const ProofRef proof = WITH_LOCK(
429  cs_peerManager, return peerManager->getProof(proofid));
430  if (!proof) {
431  continue;
432  }
433 
434  responseProof.insert(std::make_pair(proof, votes[i]));
435  }
436  }
437 
438  // Thanks to C++14 generic lambdas, we can apply the same logic to various
439  // parameter types sharing the same interface.
440  auto registerVoteItems = [&](auto voteRecordsWriteView, auto &updates,
441  auto responseItems) {
442  // Register votes.
443  for (const auto &p : responseItems) {
444  auto item = p.first;
445  const Vote &v = p.second;
446 
447  auto it = voteRecordsWriteView->find(item);
448  if (it == voteRecordsWriteView.end()) {
449  // We are not voting on that item anymore.
450  continue;
451  }
452 
453  auto &vr = it->second;
454  if (!vr.registerVote(nodeid, v.GetError())) {
455  // This vote did not provide any extra information, move on.
456  continue;
457  }
458 
459  if (!vr.hasFinalized()) {
460  // This item has note been finalized, so we have nothing more to
461  // do.
462  updates.emplace_back(item, vr.isAccepted()
465  continue;
466  }
467 
468  // We just finalized a vote. If it is valid, then let the caller
469  // know. Either way, remove the item from the map.
470  updates.emplace_back(item, vr.isAccepted() ? VoteStatus::Finalized
472  voteRecordsWriteView->erase(it);
473  }
474  };
475 
476  registerVoteItems(blockVoteRecords.getWriteView(), blockUpdates,
477  responseIndex);
478  registerVoteItems(proofVoteRecords.getWriteView(), proofUpdates,
479  responseProof);
480 
481  return true;
482 }
483 
485  return sessionKey.GetPubKey();
486 }
487 
489  CHashWriter hasher(SER_GETHASH, 0);
490  hasher << peerData->delegation.getId();
491  hasher << pfrom->GetLocalNonce();
492  hasher << pfrom->nRemoteHostNonce;
493  hasher << pfrom->GetLocalExtraEntropy();
494  hasher << pfrom->nRemoteExtraEntropy;
495  return hasher.GetHash();
496 }
497 
498 bool Processor::sendHello(CNode *pfrom) const {
499  if (!peerData) {
500  // We do not have a delegation to advertise.
501  return false;
502  }
503 
504  // Now let's sign!
505  SchnorrSig sig;
506 
507  {
508  const uint256 hash = buildLocalSighash(pfrom);
509 
510  if (!sessionKey.SignSchnorr(hash, sig)) {
511  return false;
512  }
513  }
514 
517  Hello(peerData->delegation, sig)));
518 
519  pfrom->AddKnownProof(peerData->delegation.getProofId());
520 
521  return true;
522 }
523 
525  return peerData ? peerData->proof : nullptr;
526 }
527 
529  return eventLoop.startEventLoop(
530  scheduler, [this]() { this->runEventLoop(); }, AVALANCHE_TIME_STEP);
531 }
532 
534  return eventLoop.stopEventLoop();
535 }
536 
537 std::vector<CInv> Processor::getInvsForNextPoll(bool forPoll) {
538  std::vector<CInv> invs;
539 
540  auto extractVoteRecordsToInvs = [&](const auto &itemVoteRecordRange,
541  auto buildInvFromVoteItem) {
542  for (const auto &[item, voteRecord] : itemVoteRecordRange) {
543  if (invs.size() >= AVALANCHE_MAX_ELEMENT_POLL) {
544  // Make sure we do not produce more invs than specified by the
545  // protocol.
546  return true;
547  }
548 
549  const bool shouldPoll =
550  forPoll ? voteRecord.registerPoll() : voteRecord.shouldPoll();
551 
552  if (!shouldPoll) {
553  continue;
554  }
555 
556  invs.emplace_back(buildInvFromVoteItem(item));
557  }
558 
559  return invs.size() >= AVALANCHE_MAX_ELEMENT_POLL;
560  };
561 
562  if (extractVoteRecordsToInvs(proofVoteRecords.getReadView(),
563  [](const ProofRef &proof) {
564  return CInv(MSG_AVA_PROOF, proof->getId());
565  })) {
566  // The inventory vector is full, we're done
567  return invs;
568  }
569 
570  // First remove all blocks that are not worth polling.
571  {
572  LOCK(cs_main);
573  auto w = blockVoteRecords.getWriteView();
574  for (auto it = w->begin(); it != w->end();) {
575  const CBlockIndex *pindex = it->first;
576  if (!IsWorthPolling(pindex)) {
577  w->erase(it++);
578  } else {
579  ++it;
580  }
581  }
582  }
583 
584  auto r = blockVoteRecords.getReadView();
585  extractVoteRecordsToInvs(reverse_iterate(r), [](const CBlockIndex *pindex) {
586  return CInv(MSG_BLOCK, pindex->GetBlockHash());
587  });
588 
589  return invs;
590 }
591 
594  return peerManager->selectNode();
595 }
596 
598  auto now = std::chrono::steady_clock::now();
599  std::map<CInv, uint8_t> timedout_items{};
600 
601  {
602  // Clear expired requests.
603  auto w = queries.getWriteView();
604  auto it = w->get<query_timeout>().begin();
605  while (it != w->get<query_timeout>().end() && it->timeout < now) {
606  for (const auto &i : it->invs) {
607  timedout_items[i]++;
608  }
609 
610  w->get<query_timeout>().erase(it++);
611  }
612  }
613 
614  if (timedout_items.empty()) {
615  return;
616  }
617 
618  auto clearInflightRequest = [&](auto &voteRecords, const auto &voteItem,
619  uint8_t count) {
620  if (!voteItem) {
621  return false;
622  }
623 
624  auto voteRecordsWriteView = voteRecords.getWriteView();
625  auto it = voteRecordsWriteView->find(voteItem);
626  if (it == voteRecordsWriteView.end()) {
627  return false;
628  }
629 
630  it->second.clearInflightRequest(count);
631 
632  return true;
633  };
634 
635  // In flight request accounting.
636  for (const auto &p : timedout_items) {
637  const CInv &inv = p.first;
638  if (inv.IsMsgBlk()) {
639  const CBlockIndex *pindex = WITH_LOCK(
640  cs_main, return LookupBlockIndex(BlockHash(inv.hash)));
641 
642  if (!clearInflightRequest(blockVoteRecords, pindex, p.second)) {
643  continue;
644  }
645  }
646 
647  if (inv.IsMsgProof()) {
648  const ProofRef proof =
650  return peerManager->getProof(ProofId(inv.hash)));
651 
652  if (!clearInflightRequest(proofVoteRecords, proof, p.second)) {
653  continue;
654  }
655  }
656  }
657 }
658 
660  // Don't do Avalanche while node is IBD'ing
661  if (::ChainstateActive().IsInitialBlockDownload()) {
662  return;
663  }
664 
665  // First things first, check if we have requests that timed out and clear
666  // them.
668 
669  // Make sure there is at least one suitable node to query before gathering
670  // invs.
671  NodeId nodeid = getSuitableNodeToQuery();
672  if (nodeid == NO_NODE) {
673  return;
674  }
675  std::vector<CInv> invs = getInvsForNextPoll();
676  if (invs.empty()) {
677  return;
678  }
679 
680  do {
686  bool hasSent = connman->ForNode(nodeid, [this, &invs](CNode *pnode) {
687  uint64_t current_round = round++;
688 
689  {
690  // Compute the time at which this requests times out.
691  auto timeout =
692  std::chrono::steady_clock::now() + queryTimeoutDuration;
693  // Register the query.
694  queries.getWriteView()->insert(
695  {pnode->GetId(), current_round, timeout, invs});
696  // Set the timeout.
698  peerManager->updateNextRequestTime(pnode->GetId(), timeout);
699  }
700 
701  pnode->m_avalanche_state->invsPolled(invs.size());
702 
703  // Send the query to the node.
705  pnode, CNetMsgMaker(pnode->GetCommonVersion())
707  Poll(current_round, std::move(invs))));
708  return true;
709  });
710 
711  // Success!
712  if (hasSent) {
713  return;
714  }
715 
716  {
717  // This node is obsolete, delete it.
719  peerManager->removeNode(nodeid);
720  }
721 
722  // Get next suitable node to try again
723  nodeid = getSuitableNodeToQuery();
724  } while (nodeid != NO_NODE);
725 }
726 
727 } // namespace avalanche
avalanche::VoteStatus::Rejected
@ Rejected
bitmanip.h
CScheduler
Simple class for background tasks that should be run periodically or once "after a while".
Definition: scheduler.h:35
avalanche::Processor::sendHello
bool sendHello(CNode *pfrom) const
Definition: processor.cpp:498
avalanche::Processor::NotificationsHandler
Definition: processor.cpp:113
CKey::SignSchnorr
bool SignSchnorr(const uint256 &hash, SchnorrSig &sig, uint32_t test_case=0) const
Create a Schnorr signature.
Definition: key.cpp:288
_
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:55
avalanche::Delegation
Definition: delegation.h:23
SERIALIZE_METHODS
#define SERIALIZE_METHODS(cls, obj)
Implement the Serialize and Unserialize methods by delegating to a single templated static method tha...
Definition: serialize.h:226
avalanche::VoteRecord
Vote history.
Definition: voterecord.h:29
count
static int count
Definition: tests.c:41
avalanche::VerifyDelegation
static bool VerifyDelegation(const Delegation &dg, const CPubKey &expectedPubKey, bilingual_str &error)
Definition: processor.cpp:82
avalanche::Processor::chainNotificationsHandler
std::unique_ptr< interfaces::Handler > chainNotificationsHandler
Definition: processor.h:155
CNode::GetId
NodeId GetId() const
Definition: net.h:1283
CKey::MakeNewKey
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition: key.cpp:183
avalanche::ProofValidationResult::NO_STAKE
@ NO_STAKE
ChainActive
CChain & ChainActive()
Please prefer the identical ChainstateManager::ActiveChain.
Definition: validation.cpp:86
avalanche::Processor::MakeProcessor
static std::unique_ptr< Processor > MakeProcessor(const ArgsManager &argsman, interfaces::Chain &chain, CConnman *connman, bilingual_str &error)
Definition: processor.cpp:147
key_io.h
avalanche
Definition: avalanche.h:11
avalanche::VerifyProof
static bool VerifyProof(const Proof &proof, bilingual_str &error)
Definition: processor.cpp:51
avalanche::Processor::getInvsForNextPoll
std::vector< CInv > getInvsForNextPoll(bool forPoll=true)
Definition: processor.cpp:537
avalanche::Processor::addBlockToReconcile
bool addBlockToReconcile(const CBlockIndex *pindex)
Definition: processor.cpp:246
bilingual_str
Bilingual messages:
Definition: translation.h:17
avalanche::Processor::getConfidence
int getConfidence(const CBlockIndex *pindex) const
Definition: processor.cpp:295
avalanche::Processor::getSuitableNodeToQuery
NodeId getSuitableNodeToQuery()
Definition: processor.cpp:592
avalanche::Delegation::getProofId
ProofId getProofId() const
Definition: delegation.cpp:56
delegationbuilder.h
ArgsManager::IsArgSet
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:400
CNode
Information about a peer.
Definition: net.h:926
avalanche::Processor::NotificationsHandler::m_processor
Processor * m_processor
Definition: processor.cpp:115
avalanche::Processor::peerData
std::unique_ptr< PeerData > peerData
Definition: processor.h:147
avalanche::Processor::registerVotes
bool registerVotes(NodeId nodeid, const Response &response, std::vector< BlockUpdate > &blockUpdates, std::vector< ProofUpdate > &proofUpdates, int &banscore, std::string &error)
Definition: processor.cpp:351
avalanche::Processor::sessionKey
CKey sessionKey
Definition: processor.h:149
AVALANCHE_DEFAULT_QUERY_TIMEOUT
static constexpr std::chrono::milliseconds AVALANCHE_DEFAULT_QUERY_TIMEOUT
How long before we consider that a query timed out.
Definition: processor.h:47
avalanche::Processor
Definition: processor.h:91
interfaces::Chain::handleNotifications
virtual std::unique_ptr< Handler > handleNotifications(std::shared_ptr< Notifications > notifications)=0
Register handler for notifications.
AVALANCHE_MAX_ELEMENT_POLL
static constexpr size_t AVALANCHE_MAX_ELEMENT_POLL
Maximum item that can be polled at once.
Definition: processor.h:42
avalanche::Processor::sendResponse
void sendResponse(CNode *pfrom, Response response) const
Definition: processor.cpp:344
avalanche::ProofId
Definition: proofid.h:17
WITH_LOCK
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:272
ChainstateActive
CChainState & ChainstateActive()
Please prefer the identical ChainstateManager::ActiveChainstate.
Definition: validation.cpp:80
avalanche::Processor::NotificationsHandler::updatedBlockTip
void updatedBlockTip() override
Definition: processor.cpp:120
avalanche::Processor::PeerData::delegation
Delegation delegation
Definition: processor.cpp:110
avalanche::DelegationResult::INVALID_SIGNATURE
@ INVALID_SIGNATURE
avalanche::ProofValidationResult::INVALID_STAKE_SIGNATURE
@ INVALID_STAKE_SIGNATURE
CInv
Inv(ventory) message data.
Definition: protocol.h:492
NetMsgType::AVAHELLO
const char * AVAHELLO
Contains a delegation and a signature.
Definition: protocol.cpp:51
scheduler.h
CBlockIndex::GetBlockHash
BlockHash GetBlockHash() const
Definition: blockindex.h:133
avalanche::Processor::blockVoteRecords
RWCollection< BlockVoteMap > blockVoteRecords
Blocks to run avalanche on.
Definition: processor.h:98
avalanche::ProofValidationResult::DUST_THRESOLD
@ DUST_THRESOLD
validation.h
avalanche::Processor::getLocalProof
ProofRef getLocalProof() const
Definition: processor.cpp:524
CNode::GetLocalExtraEntropy
uint64_t GetLocalExtraEntropy() const
Definition: net.h:1286
EventLoop::startEventLoop
bool startEventLoop(CScheduler &scheduler, std::function< void()> runEventLoop, std::chrono::milliseconds delta)
Definition: eventloop.cpp:13
avalanche::Vote::GetError
uint32_t GetError() const
Definition: protocol.h:27
sig
SchnorrSig sig
Definition: processor.cpp:322
interfaces::Chain
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
Definition: chain.h:108
avalanche::DelegationState
Definition: validation.h:40
CNode::AddKnownProof
void AddKnownProof(const avalanche::ProofId &proofid)
Definition: net.h:1359
cs_main
RecursiveMutex cs_main
Global state.
Definition: validation.cpp:103
EventLoop::stopEventLoop
bool stopEventLoop()
Definition: eventloop.cpp:45
CNode::GetCommonVersion
int GetCommonVersion() const
Definition: net.h:1302
response
Response response
Definition: processor.cpp:321
avalanche::query_timeout
Definition: processor.h:85
avalanche::ProofValidationState
Definition: validation.h:33
avalanche::Poll
Definition: protocol.h:53
avalanche::Response
Definition: protocol.h:33
avalanche::Delegation::FromHex
static bool FromHex(Delegation &dg, const std::string &dgHex, bilingual_str &errorOut)
Definition: delegation.cpp:16
reverse_iterator.h
avalanche::VoteStatus::Finalized
@ Finalized
avalanche::PeerManager
Definition: peermanager.h:107
avalanche::Processor::eventLoop
EventLoop eventLoop
Event loop machinery.
Definition: processor.h:152
CNode::m_avalanche_state
std::unique_ptr< AvalancheState > m_avalanche_state
Definition: net.h:1191
RWCollection::getWriteView
WriteView getWriteView()
Definition: rwcollection.h:82
CInv::IsMsgProof
bool IsMsgProof() const
Definition: protocol.h:515
CConnman::ForNode
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
Definition: net.cpp:3372
CKey::IsValid
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:94
avalanche::Processor::isAccepted
bool isAccepted(const CBlockIndex *pindex) const
Definition: processor.cpp:275
processor.h
SchnorrSig
std::array< uint8_t, CPubKey::SCHNORR_SIZE > SchnorrSig
a Schnorr signature
Definition: key.h:25
ArgsManager::GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:498
avalanche::Delegation::verify
bool verify(DelegationState &state, CPubKey &auth) const
Definition: delegation.cpp:73
avalanche::Processor::buildLocalSighash
uint256 buildLocalSighash(CNode *pfrom) const
Build and return the challenge whose signature is included in the AVAHELLO message that we send to a ...
Definition: processor.cpp:488
CNode::nRemoteHostNonce
uint64_t nRemoteHostNonce
Definition: net.h:965
g_avalanche
std::unique_ptr< avalanche::Processor > g_avalanche
Global avalanche instance.
Definition: processor.cpp:31
CNetMsgMaker
Definition: netmessagemaker.h:14
AVALANCHE_MAX_PROOF_STAKES
static constexpr int AVALANCHE_MAX_PROOF_STAKES
How many UTXOs can be used for a single proof.
Definition: proof.h:27
DecodeSecret
CKey DecodeSecret(const std::string &str)
Definition: key_io.cpp:80
avalanche::Processor::proofVoteRecords
RWCollection< ProofVoteMap > proofVoteRecords
Proofs to run avalanche on.
Definition: processor.h:103
avalanche::ProofValidationResult::DUPLICATE_STAKE
@ DUPLICATE_STAKE
uint256
256-bit opaque blob.
Definition: uint256.h:127
READWRITE
#define READWRITE(...)
Definition: serialize.h:179
CKey::GetPubKey
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:210
avalanche::Processor::connman
CConnman * connman
Definition: processor.h:92
NO_NODE
static constexpr NodeId NO_NODE
Special NodeId that represent no node.
Definition: nodeid.h:15
voterecord.h
ValidationState::GetResult
Result GetResult() const
Definition: validation.h:121
avalanche::Proof
Definition: proof.h:102
BlockHash
A BlockHash is a unqiue identifier for a block.
Definition: blockhash.h:13
avalanche::Processor::runEventLoop
void runEventLoop()
Definition: processor.cpp:659
avalanche::Proof::FromHex
static bool FromHex(Proof &proof, const std::string &hexProof, bilingual_str &errorOut)
Definition: proof.cpp:62
avalanche::Vote
Definition: protocol.h:18
RWCollection::getReadView
ReadView getReadView() const
Definition: rwcollection.h:76
avalanche::Processor::addProofToReconcile
void addProofToReconcile(const ProofRef &proof)
Definition: processor.cpp:264
avalanche::Delegation::getDelegatedPubkey
const CPubKey & getDelegatedPubkey() const
Definition: delegation.cpp:60
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1201
peermanager.h
CConnman
Definition: net.h:221
SER_GETHASH
@ SER_GETHASH
Definition: serialize.h:167
avalanche::Processor::queries
RWCollection< QuerySet > queries
Definition: processor.h:144
avalanche::Processor::queryTimeoutDuration
std::chrono::milliseconds queryTimeoutDuration
Definition: processor.h:93
avalanche::Processor::Processor
Processor(interfaces::Chain &chain, CConnman *connmanIn, std::unique_ptr< PeerData > peerDataIn, CKey sessionKeyIn)
Definition: processor.cpp:132
CPubKey
An encapsulated public key.
Definition: pubkey.h:31
CInv::hash
uint256 hash
Definition: protocol.h:495
CNode::nRemoteExtraEntropy
uint64_t nRemoteExtraEntropy
Definition: net.h:967
CKey
An encapsulated secp256k1 private key.
Definition: key.h:28
netmessagemaker.h
ArgsManager
Definition: system.h:152
translation.h
avalanche::Processor::NotificationsHandler::NotificationsHandler
NotificationsHandler(Processor *p)
Definition: processor.cpp:118
EXCLUSIVE_LOCKS_REQUIRED
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56
avalanche::Processor::cs_peerManager
Mutex cs_peerManager
Keep track of the peers and associated infos.
Definition: processor.h:113
NetMsgType::AVARESPONSE
const char * AVARESPONSE
Contains an avalanche::Response.
Definition: protocol.cpp:53
LOCK
#define LOCK(cs)
Definition: sync.h:241
interfaces::Chain::Notifications
Chain notifications.
Definition: chain.h:273
avalanche::Processor::startEventLoop
bool startEventLoop(CScheduler &scheduler)
Definition: processor.cpp:528
CHashWriter
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:99
CNode::GetLocalNonce
uint64_t GetLocalNonce() const
Definition: net.h:1285
avalanche::ProofValidationResult::TOO_MANY_UTXOS
@ TOO_MANY_UTXOS
CChain::Contains
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
Definition: chain.h:184
LookupBlockIndex
CBlockIndex * LookupBlockIndex(const BlockHash &hash)
Definition: validation.cpp:150
avalanche::Processor::getSessionPubKey
CPubKey getSessionPubKey() const
Definition: processor.cpp:484
avalanche::Processor::PeerData::proof
ProofRef proof
Definition: processor.cpp:109
CInv::IsMsgBlk
bool IsMsgBlk() const
Definition: protocol.h:519
NodeId
int64_t NodeId
Definition: nodeid.h:10
avalanche::Processor::PeerData
Definition: processor.cpp:108
avalanche::Processor::round
std::atomic< uint64_t > round
Keep track of peers and queries sent.
Definition: processor.h:108
CNetMsgMaker::Make
CSerializedNetMsg Make(int nFlags, std::string msg_type, Args &&... args) const
Definition: netmessagemaker.h:19
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
avalanche::ProofRef
std::shared_ptr< const Proof > ProofRef
Definition: proof.h:163
avalanche::VoteStatus::Accepted
@ Accepted
avalanche::Processor::clearTimedoutRequests
void clearTimedoutRequests()
Definition: processor.cpp:597
CHashWriter::GetHash
uint256 GetHash()
Definition: hash.h:118
avalanche::Proof::verify
bool verify(ProofValidationState &state) const
Definition: proof.cpp:107
avalanche::VoteStatus::Invalid
@ Invalid
net.h
CBlockIndex
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: blockindex.h:23
avalanche::Processor::stopEventLoop
bool stopEventLoop()
Definition: processor.cpp:533
avalanche::IsWorthPolling
static bool IsWorthPolling(const CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: processor.cpp:34
reverse_iterate
reverse_range< T > reverse_iterate(T &x)
Definition: reverse_iterator.h:25
MSG_BLOCK
@ MSG_BLOCK
Definition: protocol.h:478
avalanche::Processor::~Processor
~Processor()
Definition: processor.cpp:142
AssertLockHeld
AssertLockHeld(g_cs_orphans)
CConnman::PushMessage
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
Definition: net.cpp:3335
AVALANCHE_TIME_STEP
static constexpr std::chrono::milliseconds AVALANCHE_TIME_STEP
Run the avalanche event loop every 10ms.
Definition: processor.cpp:27
NetMsgType::AVAPOLL
const char * AVAPOLL
Contains an avalanche::Poll.
Definition: protocol.cpp:52
avalanche::Hello
Definition: protocol.h:68