Bitcoin ABC 0.33.11
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
6
9#include <util/check.h>
10
11namespace avalanche {
12
14ProofPool::getConflicts(const ProofRef &proof) const {
15 ConflictingProofSet conflictingProofs;
16 if (!proof) {
17 return conflictingProofs;
18 }
19
20 for (const auto &s : proof->getStakes()) {
21 const ProofRef conflicting = getProof(s.getStake().getUTXO());
22 if (conflicting && conflicting->getId() != proof->getId()) {
23 conflictingProofs.insert(conflicting);
24 }
25 }
26 return conflictingProofs;
27}
28
31 ConflictingProofSet &conflictingProofs) {
32 // Make sure the set is empty before we add items
33 conflictingProofs.clear();
34
35 auto &poolView = pool.get<by_proofid>();
36 if (poolView.find(proof->getId()) != poolView.end()) {
37 return AddProofStatus::DUPLICATED;
38 }
39
40 conflictingProofs = getConflicts(proof);
41 if (!conflictingProofs.empty()) {
42 return AddProofStatus::REJECTED;
43 }
44
45 // Attach UTXOs to this proof.
46 for (size_t i = 0; i < proof->getStakes().size(); i++) {
47 auto p = pool.emplace(i, proof);
48 // After getConflicts, failure means a duplicate UTXO within the proof
49 // itself (or a logic bug), not a conflict with another pool entry.
50 Assume(p.second);
51 }
52
53 cacheClean = false;
54 return AddProofStatus::SUCCEED;
55}
56
59 ConflictingProofSet &conflictingProofs) {
60 auto status = addProofIfNoConflict(proof, conflictingProofs);
61
62 // In case the proof was rejected due to conflict and it is the best
63 // candidate, override the conflicting ones and add it again
64 if (status != AddProofStatus::REJECTED ||
65 ConflictingProofComparator()(*conflictingProofs.begin(), proof)) {
66 return status;
67 }
68
69 for (auto &conflictingProof : conflictingProofs) {
70 removeProof(conflictingProof->getId());
71 }
72
73 status = addProofIfNoConflict(proof);
74 Assume(status == AddProofStatus::SUCCEED);
75
76 cacheClean = false;
77 return AddProofStatus::SUCCEED;
78}
79
80// Having the ProofId passed by reference is risky because it is usually a
81// reference to a proof member. This proof will be deleted during the erasure
82// loop so we pass it by value.
84 cacheClean = false;
85 auto &poolView = pool.get<by_proofid>();
86 return poolView.erase(proofid);
87}
88
89std::unordered_set<ProofRef, SaltedProofHasher>
91 auto previousPool = std::move(pool);
92 pool.clear();
93 cacheClean = false;
94
95 std::unordered_set<ProofRef, SaltedProofHasher> registeredProofs;
96 for (auto &entry : previousPool) {
97 if (registeredProofs.insert(entry.proof).second) {
98 peerManager.registerProof(entry.proof);
99 }
100 }
101
102 return registeredProofs;
103}
104
106 ProofIdSet proofIds;
107
108 auto &poolView = pool.get<by_proofid>();
109 for (auto it = poolView.begin(); it != poolView.end(); it++) {
110 proofIds.insert(it->proof->getId());
111 }
112
113 return proofIds;
114}
115
116ProofRef ProofPool::getProof(const ProofId &proofid) const {
117 auto &poolView = pool.get<by_proofid>();
118 auto it = poolView.find(proofid);
119 return it == poolView.end() ? ProofRef() : it->proof;
120}
121
122ProofRef ProofPool::getProof(const COutPoint &outpoint) const {
123 auto it = pool.find(outpoint);
124 return it == pool.end() ? ProofRef() : it->proof;
125}
126
128 auto &poolView = pool.get<by_proof_score>();
129 return poolView.rbegin() == poolView.rend() ? ProofRef()
130 : poolView.rbegin()->proof;
131}
132
134 if (cacheClean) {
135 return cacheProofCount;
136 }
137
138 size_t count = 0;
139 forEachProof([&](const ProofRef &proof) { count++; });
140
142 cacheClean = true;
143 return cacheProofCount;
144}
145
146} // namespace avalanche
#define Assume(val)
Assume is the identity function.
Definition: check.h:100
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:58
size_t size() const
Definition: proofpool.h:140
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:30
size_t countProofs() const
Definition: proofpool.cpp:133
bool removeProof(ProofId proofid)
Definition: proofpool.cpp:83
size_t cacheProofCount
Definition: proofpool.h:78
void forEachProof(Callable &&func) const
Definition: proofpool.h:123
ProofRef getProof(const ProofId &proofid) const
Definition: proofpool.cpp:116
std::set< ProofRef, ConflictingProofComparator > ConflictingProofSet
Definition: proofpool.h:87
ProofRef getLowestScoreProof() const
Definition: proofpool.cpp:127
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:75
std::unordered_set< ProofRef, SaltedProofHasher > rescan(PeerManager &peerManager)
Definition: proofpool.cpp:90
ConflictingProofSet getConflicts(const ProofRef &proof) const
Return proofs in this pool that share any UTXO with proof.
Definition: proofpool.cpp:14
ProofIdSet getProofIds() const
Definition: proofpool.cpp:105
std::unordered_set< ProofId, SaltedProofIdHasher > ProofIdSet
Definition: proofpool.h:51
RCUPtr< const Proof > ProofRef
Definition: proof.h:183
Compare conflicting proofs.
static int count