Bitcoin ABC  0.26.3
P2P Digital Currency
proofpool.cpp
Go to the documentation of this file.
1 // Copyright (c) 2021 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/proofpool.h>
6 
9 
10 namespace avalanche {
11 
14  ConflictingProofSet &conflictingProofs) {
15  const ProofId &proofid = proof->getId();
16 
17  // Make sure the set is empty before we add items
18  conflictingProofs.clear();
19 
20  auto &poolView = pool.get<by_proofid>();
21  if (poolView.find(proofid) != poolView.end()) {
22  return AddProofStatus::DUPLICATED;
23  }
24 
25  // Attach UTXOs to this proof.
26  for (size_t i = 0; i < proof->getStakes().size(); i++) {
27  auto p = pool.emplace(i, proof);
28  if (!p.second) {
29  // We have a collision with an existing proof.
30  conflictingProofs.insert(p.first->proof);
31  }
32  }
33 
34  // If there is a conflict, just cleanup the mess.
35  if (conflictingProofs.size() > 0) {
36  for (const auto &s : proof->getStakes()) {
37  auto it = pool.find(s.getStake().getUTXO());
38  assert(it != pool.end());
39 
40  // We need to delete that one.
41  if (it->proof->getId() == proofid) {
42  pool.erase(it);
43  }
44  }
45 
46  return AddProofStatus::REJECTED;
47  }
48 
49  cacheClean = false;
50  return AddProofStatus::SUCCEED;
51 }
52 
55  ConflictingProofSet &conflictingProofs) {
56  auto status = addProofIfNoConflict(proof, conflictingProofs);
57 
58  // In case the proof was rejected due to conflict and it is the best
59  // candidate, override the conflicting ones and add it again
60  if (status != AddProofStatus::REJECTED ||
61  ConflictingProofComparator()(*conflictingProofs.begin(), proof)) {
62  return status;
63  }
64 
65  for (auto &conflictingProof : conflictingProofs) {
66  removeProof(conflictingProof->getId());
67  }
68 
69  status = addProofIfNoConflict(proof);
70  assert(status == AddProofStatus::SUCCEED);
71 
72  cacheClean = false;
73  return AddProofStatus::SUCCEED;
74 }
75 
76 // Having the ProofId passed by reference is risky because it is usually a
77 // reference to a proof member. This proof will be deleted during the erasure
78 // loop so we pass it by value.
80  cacheClean = false;
81  auto &poolView = pool.get<by_proofid>();
82  return poolView.erase(proofid);
83 }
84 
85 std::unordered_set<ProofRef, SaltedProofHasher>
87  auto previousPool = std::move(pool);
88  pool.clear();
89  cacheClean = false;
90 
91  std::unordered_set<ProofRef, SaltedProofHasher> registeredProofs;
92  for (auto &entry : previousPool) {
93  if (registeredProofs.insert(entry.proof).second) {
94  peerManager.registerProof(entry.proof);
95  }
96  }
97 
98  return registeredProofs;
99 }
100 
102  ProofIdSet proofIds;
103 
104  auto &poolView = pool.get<by_proofid>();
105  for (auto it = poolView.begin(); it != poolView.end(); it++) {
106  proofIds.insert(it->proof->getId());
107  }
108 
109  return proofIds;
110 }
111 
112 ProofRef ProofPool::getProof(const ProofId &proofid) const {
113  auto &poolView = pool.get<by_proofid>();
114  auto it = poolView.find(proofid);
115  return it == poolView.end() ? ProofRef() : it->proof;
116 }
117 
118 ProofRef ProofPool::getProof(const COutPoint &outpoint) const {
119  auto it = pool.find(outpoint);
120  return it == pool.end() ? ProofRef() : it->proof;
121 }
122 
124  auto &poolView = pool.get<by_proof_score>();
125  return poolView.rbegin() == poolView.rend() ? ProofRef()
126  : poolView.rbegin()->proof;
127 }
128 
129 size_t ProofPool::countProofs() const {
130  if (cacheClean) {
131  return cacheProofCount;
132  }
133 
134  size_t count = 0;
135  forEachProof([&](const ProofRef &proof) { count++; });
136 
138  cacheClean = true;
139  return cacheProofCount;
140 }
141 
142 } // namespace avalanche
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:22
bool registerProof(const ProofRef &proof, ProofRegistrationState &registrationState, RegistrationMode mode=RegistrationMode::DEFAULT)
AddProofStatus addProofIfPreferred(const ProofRef &proof, ConflictingProofSet &conflictingProofs)
Attempt to add a proof to the pool.
Definition: proofpool.cpp:54
AddProofStatus addProofIfNoConflict(const ProofRef &proof, ConflictingProofSet &conflictingProofs)
Attempt to add a proof to the pool, and fail if there is a conflict on any UTXO.
Definition: proofpool.cpp:13
size_t countProofs() const
Definition: proofpool.cpp:129
bool removeProof(ProofId proofid)
Definition: proofpool.cpp:79
size_t cacheProofCount
Definition: proofpool.h:79
void forEachProof(Callable &&func) const
Definition: proofpool.h:118
ProofRef getProof(const ProofId &proofid) const
Definition: proofpool.cpp:112
std::set< ProofRef, ConflictingProofComparator > ConflictingProofSet
Definition: proofpool.h:88
ProofRef getLowestScoreProof() const
Definition: proofpool.cpp:123
boost::multi_index_container< ProofPoolEntry, bmi::indexed_by< bmi::hashed_unique< bmi::tag< by_utxo >, bmi::const_mem_fun< ProofPoolEntry, const COutPoint &, &ProofPoolEntry::getUTXO >, SaltedOutpointHasher >, bmi::hashed_non_unique< bmi::tag< by_proofid >, ProofPoolEntryProofIdKeyExtractor, SaltedProofIdHasher >, bmi::ordered_non_unique< bmi::tag< by_proof_score >, bmi::member< ProofPoolEntry, ProofRef, &ProofPoolEntry::proof >, ProofComparatorByScore > > > pool
Definition: proofpool.h:76
std::unordered_set< ProofRef, SaltedProofHasher > rescan(PeerManager &peerManager)
Definition: proofpool.cpp:86
ProofIdSet getProofIds() const
Definition: proofpool.cpp:101
std::unordered_set< ProofId, SaltedProofIdHasher > ProofIdSet
Definition: proofpool.h:52
RCUPtr< const Proof > ProofRef
Definition: proof.h:185
Compare conflicting proofs.
static int count
Definition: tests.c:31
assert(!tx.IsCoinBase())