Bitcoin ABC 0.26.3
P2P Digital Currency
Loading...
Searching...
No Matches
stakecontendercache.cpp
Go to the documentation of this file.
1// Copyright (c) 2024 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
7namespace avalanche {
8
10 std::set<BlockHash> hashesToErase;
12 for (auto it = mwHeightView.begin();
13 it != mwHeightView.lower_bound(minHeight); it++) {
14 hashesToErase.insert(it->prevblockhash);
15 }
16
18 for (auto it = cHeightView.begin();
19 it != cHeightView.lower_bound(minHeight); it++) {
20 hashesToErase.insert(it->prevblockhash);
21 }
22
23 for (const auto &blockhash : hashesToErase) {
25 auto [mwHashBegin, mwHashEnd] = mwHashView.equal_range(blockhash);
27
29 auto [cHashBegin, cHashEnd] = cHashView.equal_range(blockhash);
31 }
32}
33
34bool StakeContenderCache::add(const CBlockIndex *pindex, const ProofRef &proof,
35 uint8_t status) {
36 return contenders
37 .emplace(pindex->GetBlockHash(), pindex->nHeight, proof->getId(),
38 status, proof->getPayoutScript(), proof->getScore())
39 .second;
40}
41
43 const CScript &payoutScript) {
44 const BlockHash &prevblockhash = pindex->GetBlockHash();
45 auto &view = manualWinners.get<by_prevblockhash>();
46 auto it = view.find(prevblockhash);
47 if (it == view.end()) {
48 std::vector<CScript> payoutScripts{payoutScript};
49 return manualWinners
50 .emplace(prevblockhash, pindex->nHeight, payoutScripts)
51 .second;
52 }
53
54 return manualWinners.modify(it, [&](ManualWinners &entry) {
55 entry.payoutScripts.push_back(payoutScript);
56 });
57}
58
60 auto &view = contenders.get<by_stakecontenderid>();
61 auto it = view.find(contenderId);
62 if (it == view.end()) {
63 return false;
64 }
65
66 return contenders.modify(it, [&](StakeContenderCacheEntry &entry) {
68 });
69}
70
72 auto &view = contenders.get<by_stakecontenderid>();
73 auto it = view.find(contenderId);
74 if (it == view.end()) {
75 return false;
76 }
77
78 return contenders.modify(it, [&](StakeContenderCacheEntry &entry) {
81 });
82}
83
85 auto &view = contenders.get<by_stakecontenderid>();
86 auto it = view.find(contenderId);
87 if (it == view.end()) {
88 return false;
89 }
90
91 return contenders.modify(it, [&](StakeContenderCacheEntry &entry) {
93 });
94}
95
97 auto &view = contenders.get<by_stakecontenderid>();
98 auto it = view.find(contenderId);
99 if (it == view.end()) {
100 return false;
101 }
102
103 return contenders.modify(it, [&](StakeContenderCacheEntry &entry) {
106 });
107}
108
110 const StakeContenderId &contenderId) const {
111 auto &view = contenders.get<by_stakecontenderid>();
112 auto it = view.find(contenderId);
113 if (it == view.end()) {
114 return -1;
115 }
116
117 // Contender is accepted
118 if (it->isAccepted()) {
119 return 0;
120 }
121
122 // If the contender matches a manual winner, it is accepted.
124 auto manualWinnerIt = manualWinnersView.find(it->prevblockhash);
125 if (manualWinnerIt != manualWinners.end()) {
126 for (auto &payoutScript : manualWinnerIt->payoutScripts) {
127 if (payoutScript == it->payoutScriptPubkey) {
128 return 0;
129 }
130 }
131 }
132
133 // Contender is rejected
134 return 1;
135}
136
138 std::vector<CScript> &payouts) const {
139 // Winners determined by avalanche are sorted by reward rank
140 std::vector<const StakeContenderCacheEntry *> rankedWinners;
141 auto &view = contenders.get<by_prevblockhash>();
142 auto [begin, end] = view.equal_range(prevblockhash);
143 for (auto it = begin; it != end; it++) {
144 if (it->isInWinnerSet()) {
145 rankedWinners.push_back(&(*it));
146 }
147 }
148
149 std::sort(rankedWinners.begin(), rankedWinners.end(),
150 [](const StakeContenderCacheEntry *left,
151 const StakeContenderCacheEntry *right) {
152 return left->computeRewardRank() < right->computeRewardRank();
153 });
154
155 payouts.clear();
156
157 // Add manual winners first, preserving order
159 auto manualWinnerIt = manualWinnersView.find(prevblockhash);
160 if (manualWinnerIt != manualWinners.end()) {
161 payouts.reserve(manualWinnerIt->payoutScripts.size() +
162 rankedWinners.size());
163
164 payouts.insert(payouts.begin(), manualWinnerIt->payoutScripts.begin(),
165 manualWinnerIt->payoutScripts.end());
166 } else {
167 payouts.reserve(rankedWinners.size());
168 }
169
170 // Add ranked winners, preserving reward rank order
171 for (const auto &rankedWinner : rankedWinners) {
172 payouts.push_back(rankedWinner->payoutScriptPubkey);
173 }
174
175 return payouts.size() > 0;
176}
177
178} // namespace avalanche
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition blockindex.h:25
BlockHash GetBlockHash() const
Definition blockindex.h:146
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition blockindex.h:38
Serialized script, used inside transaction inputs and outputs.
Definition script.h:431
bool invalidate(const StakeContenderId &contenderId)
bool accept(const StakeContenderId &contenderId)
Helpers to set avalanche state of a contender.
bool reject(const StakeContenderId &contenderId)
bool addWinner(const CBlockIndex *pindex, const CScript &payoutScript)
Add a proof that should be treated as a winner (already finalized).
int getVoteStatus(const StakeContenderId &contenderId) const
Get contender acceptance state for avalanche voting.
void cleanup(const int minHeight)
bool add(const CBlockIndex *pindex, const ProofRef &proof, uint8_t status=StakeContenderStatus::UNKNOWN)
Add a proof to consider in staking rewards pre-consensus.
bool finalize(const StakeContenderId &contenderId)
bool getWinners(const BlockHash &prevblockhash, std::vector< CScript > &payouts) const
Get payout scripts of the winning proofs.
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition random.h:85
A BlockHash is a unqiue identifier for a block.
Definition blockhash.h:13
std::vector< CScript > payoutScripts
uint8_t status
StakeContenderIds are unique for each block to ensure that the peer polling for their acceptance has ...