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 CBlockIndex *pindex, const std::vector<CScript> &payoutScripts) {
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 return manualWinners
49 .emplace(prevblockhash, pindex->nHeight, payoutScripts)
50 .second;
51 }
52 return manualWinners.replace(
53 it, ManualWinners(prevblockhash, pindex->nHeight, payoutScripts));
54}
55
57 auto &view = contenders.get<by_stakecontenderid>();
58 auto it = view.find(contenderId);
59 if (it == view.end()) {
60 return false;
61 }
62
63 return contenders.modify(it, [&](StakeContenderCacheEntry &entry) {
65 });
66}
67
69 auto &view = contenders.get<by_stakecontenderid>();
70 auto it = view.find(contenderId);
71 if (it == view.end()) {
72 return false;
73 }
74
75 return contenders.modify(it, [&](StakeContenderCacheEntry &entry) {
78 });
79}
80
82 auto &view = contenders.get<by_stakecontenderid>();
83 auto it = view.find(contenderId);
84 if (it == view.end()) {
85 return false;
86 }
87
88 return contenders.modify(it, [&](StakeContenderCacheEntry &entry) {
90 });
91}
92
94 auto &view = contenders.get<by_stakecontenderid>();
95 auto it = view.find(contenderId);
96 if (it == view.end()) {
97 return false;
98 }
99
100 return contenders.modify(it, [&](StakeContenderCacheEntry &entry) {
103 });
104}
105
107 const StakeContenderId &contenderId) const {
108 auto &view = contenders.get<by_stakecontenderid>();
109 auto it = view.find(contenderId);
110 if (it == view.end()) {
111 return -1;
112 }
113
114 // Contender is accepted
115 if (it->isAccepted()) {
116 return 0;
117 }
118
119 // If the contender matches a manual winner, it is accepted.
121 auto manualWinnerIt = manualWinnersView.find(it->prevblockhash);
122 if (manualWinnerIt != manualWinners.end()) {
123 for (auto &payoutScript : manualWinnerIt->payoutScripts) {
124 if (payoutScript == it->payoutScriptPubkey) {
125 return 0;
126 }
127 }
128 }
129
130 // Contender is rejected
131 return 1;
132}
133
135 std::vector<CScript> &payouts) const {
136 // Winners determined by avalanche are sorted by reward rank
137 std::vector<const StakeContenderCacheEntry *> rankedWinners;
138 auto &view = contenders.get<by_prevblockhash>();
139 auto [begin, end] = view.equal_range(prevblockhash);
140 for (auto it = begin; it != end; it++) {
141 if (it->isInWinnerSet()) {
142 rankedWinners.push_back(&(*it));
143 }
144 }
145
146 std::sort(rankedWinners.begin(), rankedWinners.end(),
147 [](const StakeContenderCacheEntry *left,
148 const StakeContenderCacheEntry *right) {
149 return left->computeRewardRank() < right->computeRewardRank();
150 });
151
152 payouts.clear();
153
154 // Add manual winners first, preserving order
156 auto manualWinnerIt = manualWinnersView.find(prevblockhash);
157 if (manualWinnerIt != manualWinners.end()) {
158 payouts.reserve(manualWinnerIt->payoutScripts.size() +
159 rankedWinners.size());
160
161 payouts.insert(payouts.begin(), manualWinnerIt->payoutScripts.begin(),
162 manualWinnerIt->payoutScripts.end());
163 } else {
164 payouts.reserve(rankedWinners.size());
165 }
166
167 // Add ranked winners, preserving reward rank order
168 for (const auto &rankedWinner : rankedWinners) {
169 payouts.push_back(rankedWinner->payoutScriptPubkey);
170 }
171
172 return payouts.size() > 0;
173}
174
175} // 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
bool invalidate(const StakeContenderId &contenderId)
bool accept(const StakeContenderId &contenderId)
Helpers to set avalanche state of a contender.
bool reject(const StakeContenderId &contenderId)
int getVoteStatus(const StakeContenderId &contenderId) const
Get contender acceptance state for avalanche voting.
bool setWinners(const CBlockIndex *pindex, const std::vector< CScript > &payoutScripts)
Set proof(s) that should be treated as winners (already finalized).
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
uint8_t status
StakeContenderIds are unique for each block to ensure that the peer polling for their acceptance has ...