Bitcoin ABC 0.26.3
P2P Digital Currency
Loading...
Searching...
No Matches
processor.h
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#ifndef BITCOIN_AVALANCHE_PROCESSOR_H
6#define BITCOIN_AVALANCHE_PROCESSOR_H
7
8#include <avalanche/config.h>
9#include <avalanche/node.h>
10#include <avalanche/proof.h>
12#include <avalanche/protocol.h>
14#include <avalanche/voterecord.h> // For AVALANCHE_MAX_INFLIGHT_POLL
15#include <blockindex.h>
17#include <common/bloom.h>
18#include <eventloop.h>
19#include <interfaces/chain.h>
20#include <interfaces/handler.h>
21#include <key.h>
22#include <net.h>
24#include <rwcollection.h>
25#include <util/variant.h>
26#include <validationinterface.h>
27
28#include <boost/multi_index/composite_key.hpp>
29#include <boost/multi_index/hashed_index.hpp>
30#include <boost/multi_index/member.hpp>
31#include <boost/multi_index/ordered_index.hpp>
32#include <boost/multi_index_container.hpp>
33
34#include <atomic>
35#include <chrono>
36#include <cstdint>
37#include <memory>
38#include <unordered_map>
39#include <variant>
40#include <vector>
41
42class ArgsManager;
43class CConnman;
44class CNode;
45class CScheduler;
46class Config;
47class PeerManager;
48struct bilingual_str;
49
53static constexpr size_t AVALANCHE_MAX_ELEMENT_POLL = 16;
54
58static constexpr std::chrono::milliseconds AVALANCHE_DEFAULT_QUERY_TIMEOUT{
59 10000};
60
71
72namespace avalanche {
73
74class Delegation;
75class PeerManager;
76class ProofRegistrationState;
77struct VoteRecord;
78
79enum struct VoteStatus : uint8_t {
80 Invalid,
84 Stale,
85};
86
88 std::variant<const ProofRef, const CBlockIndex *, const CTransactionRef>;
89
101
103 bool operator()(const AnyVoteItem &lhs, const AnyVoteItem &rhs) const {
104 // If the variants are of different types, sort them by variant index
105 if (lhs.index() != rhs.index()) {
106 return lhs.index() < rhs.index();
107 }
108
109 return std::visit(
111 [](const ProofRef &lhs, const ProofRef &rhs) {
112 return ProofComparatorByScore()(lhs, rhs);
113 },
114 [](const CBlockIndex *lhs, const CBlockIndex *rhs) {
115 // Reverse ordering so we get the highest work first
117 },
118 [](const CTransactionRef &lhs, const CTransactionRef &rhs) {
119 return lhs->GetId() < rhs->GetId();
120 },
121 [](const auto &lhs, const auto &rhs) {
122 // This serves 2 purposes:
123 // - This makes sure that we don't forget to implement a
124 // comparison case when adding a new variant type.
125 // - This avoids having to write all the cross type cases
126 // which are already handled by the index sort above.
127 // Because the compiler has no way to determine that, we
128 // cannot use static assertions here without having to
129 // define the whole type matrix also.
130 assert(false);
131 // Return any bool, it's only there to make the compiler
132 // happy.
133 return false;
134 },
135 },
136 lhs, rhs);
137 }
138};
139using VoteMap = std::map<AnyVoteItem, VoteRecord, VoteMapComparator>;
140
142
143namespace {
144 struct AvalancheTest;
145}
146
147// FIXME Implement a proper notification handler for node disconnection instead
148// of implementing the whole NetEventsInterface for a single interesting event.
154
159
163 std::atomic<uint64_t> round;
164
169 std::unique_ptr<PeerManager> peerManager GUARDED_BY(cs_peerManager);
170
171 struct Query {
175
182 mutable std::vector<CInv> invs;
183 };
184
185 using QuerySet = boost::multi_index_container<
186 Query,
187 boost::multi_index::indexed_by<
188 // index by nodeid/round
189 boost::multi_index::hashed_unique<boost::multi_index::composite_key<
190 Query,
191 boost::multi_index::member<Query, NodeId, &Query::nodeid>,
192 boost::multi_index::member<Query, uint64_t, &Query::round>>>,
193 // sorted by timeout
194 boost::multi_index::ordered_non_unique<
195 boost::multi_index::tag<query_timeout>,
196 boost::multi_index::member<Query, SteadyMilliseconds,
197 &Query::timeout>>>>;
198
200
202 struct PeerData;
203 std::unique_ptr<PeerData> peerData;
205
208
214 std::atomic<bool> quorumIsEstablished{false};
215 std::atomic<bool> m_canShareLocalProof{false};
217 std::atomic<int64_t> avaproofsNodeCounter{0};
218
222
225 std::unique_ptr<interfaces::Handler> chainNotificationsHandler;
226
229
235 std::unordered_set<NodeId>
237
240 // Ordered list of acceptable winners, only the first is used for mining
241 std::vector<std::pair<ProofId, CScript>> winners;
242 };
243
245 std::unordered_map<BlockHash, StakingReward, SaltedUint256Hasher>
247
250
253 CScheduler &scheduler, std::unique_ptr<PeerData> peerDataIn,
259
260public:
261 const bool m_preConsensus{false};
262 const bool m_stakingPreConsensus{false};
263
264 ~Processor();
265
266 static std::unique_ptr<Processor>
269 CTxMemPool *mempoolIn, CScheduler &scheduler,
271
272 bool addToReconcile(const AnyVoteItem &item)
279 bool reconcileOrFinalize(const ProofRef &proof)
281 bool isAccepted(const AnyVoteItem &item) const;
282 int getConfidence(const AnyVoteItem &item) const;
283
284 bool isRecentlyFinalized(const uint256 &itemId) const
287
288 // TODO: Refactor the API to remove the dependency on avalanche/protocol.h
290 bool registerVotes(NodeId nodeid, const Response &response,
291 std::vector<VoteItemUpdate> &updates, int &banscore,
292 std::string &error)
295
302
310 bool sendHello(CNode *pfrom)
314
315 ProofRef getLocalProof() const;
317
318 /*
319 * Return whether the avalanche service flag should be set.
320 */
322
328
329 bool startEventLoop(CScheduler &scheduler);
330 bool stopEventLoop();
331
335 return avaproofsNodeCounter.load();
336 }
340 bool canShareLocalProof();
341
342 bool computeStakingReward(const CBlockIndex *pindex)
347 void cleanupStakingRewards(const int minHeight)
351 std::vector<std::pair<ProofId, CScript>> &winners) const
354 std::vector<CScript> &payouts) const
356 bool setStakingRewardWinners(const CBlockIndex *pprev,
357 const std::vector<CScript> &payouts)
359
360 // Implement NetEventInterface. Only FinalizeNode is of interest.
361 void InitializeNode(const ::Config &config, CNode &pnode,
362 ServiceFlags our_services) override {}
363 bool ProcessMessages(const ::Config &config, CNode *pnode,
364 std::atomic<bool> &interrupt) override {
365 return false;
366 }
367 bool SendMessages(const ::Config &config, CNode *pnode) override {
368 return false;
369 }
370
372 void FinalizeNode(const ::Config &config,
373 const CNode &node) override LOCKS_EXCLUDED(cs_main)
375
377 void addStakeContender(const ProofRef &proof)
381
386
387private:
388 void updatedBlockTip()
394 void runEventLoop()
404
408
418
431
434
436
437 bool operator()(const CBlockIndex *pindex) const
439 bool operator()(const ProofRef &proof) const
441 bool operator()(const CTransactionRef &tx) const;
442 };
443 bool isWorthPolling(const AnyVoteItem &item) const
445
448
451
452 bool operator()(const CBlockIndex *pindex) const
454 bool operator()(const ProofRef &proof) const
456 bool operator()(const CTransactionRef &tx) const;
457 };
458 bool getLocalAcceptance(const AnyVoteItem &item) const {
459 return std::visit(GetLocalAcceptance(*this), item);
460 }
461
462 friend struct ::avalanche::AvalancheTest;
463};
464
465} // namespace avalanche
466
467#endif // BITCOIN_AVALANCHE_PROCESSOR_H
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition blockindex.h:25
Inv(ventory) message data.
Definition protocol.h:581
An encapsulated secp256k1 private key.
Definition key.h:28
Information about a peer.
Definition net.h:460
An encapsulated public key.
Definition pubkey.h:31
RollingBloomFilter is a probabilistic "keep track of most recently inserted" set.
Definition bloom.h:115
Simple class for background tasks that should be run periodically or once "after a while".
Definition scheduler.h:41
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition txmempool.h:212
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Interface for message handling.
Definition net.h:805
void sendResponse(CNode *pfrom, Response response) const
const uint32_t staleVoteThreshold
Voting parameters.
Definition processor.h:220
std::atomic< bool > quorumIsEstablished
Definition processor.h:214
boost::multi_index_container< Query, boost::multi_index::indexed_by< boost::multi_index::hashed_unique< boost::multi_index::composite_key< Query, boost::multi_index::member< Query, NodeId, &Query::nodeid >, boost::multi_index::member< Query, uint64_t, &Query::round > > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< query_timeout >, boost::multi_index::member< Query, SteadyMilliseconds, &Query::timeout > > > > QuerySet
Definition processor.h:197
AnyVoteItem getVoteItemFromInv(const CInv &inv) const EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager)
Mutex cs_finalizedItems
Rolling bloom filter to track recently finalized inventory items of any type.
Definition processor.h:428
bool sendHelloInternal(CNode *pfrom) EXCLUSIVE_LOCKS_REQUIRED(cs_delayedAvahelloNodeIds)
int getConfidence(const AnyVoteItem &item) const
bool addToReconcile(const AnyVoteItem &item) EXCLUSIVE_LOCKS_REQUIRED(!cs_finalizedItems)
std::vector< CInv > getInvsForNextPoll(bool forPoll=true) EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager
int64_t getAvaproofsNodeCounter() const
Definition processor.h:334
RWCollection< QuerySet > queries
Definition processor.h:199
bool hasFinalizedTip() const EXCLUSIVE_LOCKS_REQUIRED(!cs_finalizationTip)
Whether there is a finalized tip.
Definition processor.h:324
bool ProcessMessages(const ::Config &config, CNode *pnode, std::atomic< bool > &interrupt) override
Definition processor.h:363
bool registerVotes(NodeId nodeid, const Response &response, std::vector< VoteItemUpdate > &updates, int &banscore, std::string &error) EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager
void transactionAddedToMempool(const CTransactionRef &tx) EXCLUSIVE_LOCKS_REQUIRED(!cs_finalizedItems)
const CBlockIndex *finalizationTip GUARDED_BY(cs_finalizationTip)
Definition processor.h:228
bool sendHello(CNode *pfrom) EXCLUSIVE_LOCKS_REQUIRED(!cs_delayedAvahelloNodeIds)
Send a avahello message.
bool isRecentlyFinalized(const uint256 &itemId) const EXCLUSIVE_LOCKS_REQUIRED(!cs_finalizedItems)
bool startEventLoop(CScheduler &scheduler)
bool isQuorumEstablished() LOCKS_EXCLUDED(cs_main) EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager
void promoteStakeContendersToTip() EXCLUSIVE_LOCKS_REQUIRED(!cs_stakeContenderCache
Promote stake contender cache entries to the latest chain tip.
std::atomic< uint64_t > round
Keep track of peers and queries sent.
Definition processor.h:163
static std::unique_ptr< Processor > MakeProcessor(const ArgsManager &argsman, interfaces::Chain &chain, CConnman *connman, ChainstateManager &chainman, CTxMemPool *mempoolIn, CScheduler &scheduler, bilingual_str &error)
EventLoop eventLoop
Event loop machinery.
Definition processor.h:207
CTxMemPool * mempool
Definition processor.h:153
int64_t minAvaproofsNodeCount
Definition processor.h:216
const bool m_preConsensus
Definition processor.h:261
Mutex cs_delayedAvahelloNodeIds
Definition processor.h:230
bool setStakingRewardWinners(const CBlockIndex *pprev, const std::vector< CScript > &payouts) EXCLUSIVE_LOCKS_REQUIRED(!cs_stakingRewards
void runEventLoop() EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager
bool isAvalancheServiceAvailable()
Definition processor.h:321
Mutex cs_invalidatedBlocks
We don't need many blocks but a low false positive rate.
Definition processor.h:415
void updatedBlockTip() EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager
RWCollection< VoteMap > voteRecords
Items to run avalanche on.
Definition processor.h:158
void setContenderStatusForLocalWinner(const CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs_stakeContenderCache
Helper to set the local winner in the contender cache.
std::unique_ptr< interfaces::Handler > chainNotificationsHandler
Definition processor.h:225
uint32_t minQuorumScore
Quorum management.
Definition processor.h:212
void FinalizeNode(const ::Config &config, const CNode &node) override LOCKS_EXCLUDED(cs_main) EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager
Handle removal of a node.
bool getStakingRewardWinners(const BlockHash &prevBlockHash, std::vector< std::pair< ProofId, CScript > > &winners) const EXCLUSIVE_LOCKS_REQUIRED(!cs_stakingRewards)
std::atomic< bool > m_canShareLocalProof
Definition processor.h:215
void cleanupStakingRewards(const int minHeight) EXCLUSIVE_LOCKS_REQUIRED(!cs_stakingRewards
bool isAccepted(const AnyVoteItem &item) const
ProofRef getLocalProof() const
void addStakeContender(const ProofRef &proof) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Track votes on stake contenders.
void InitializeNode(const ::Config &config, CNode &pnode, ServiceFlags our_services) override
Definition processor.h:361
bool reconcileOrFinalize(const ProofRef &proof) EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager
Wrapper around the addToReconcile for proofs that adds back the finalization flag to the peer if it i...
const uint32_t staleVoteFactor
Definition processor.h:221
void sendDelayedAvahello() EXCLUSIVE_LOCKS_REQUIRED(!cs_delayedAvahelloNodeIds)
std::unique_ptr< PeerData > peerData
Definition processor.h:203
bool eraseStakingRewardWinner(const BlockHash &prevBlockHash) EXCLUSIVE_LOCKS_REQUIRED(!cs_stakingRewards)
const bool m_stakingPreConsensus
Definition processor.h:262
bool isWorthPolling(const AnyVoteItem &item) const EXCLUSIVE_LOCKS_REQUIRED(!cs_finalizedItems)
CPubKey getSessionPubKey() const
auto withPeerManager(Callable &&func) const EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager)
Definition processor.h:297
std::unique_ptr< PeerManager > peerManager GUARDED_BY(cs_peerManager)
ChainstateManager & chainman
Definition processor.h:152
std::atomic< int64_t > avaproofsNodeCounter
Definition processor.h:217
bool SendMessages(const ::Config &config, CNode *pnode) override
Definition processor.h:367
bool computeStakingReward(const CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager
ProofRegistrationState getLocalProofRegistrationState() const
CRollingBloomFilter finalizedItems GUARDED_BY(cs_finalizedItems)
Definition processor.h:429
int getStakeContenderStatus(const StakeContenderId &contenderId) const EXCLUSIVE_LOCKS_REQUIRED(!cs_stakeContenderCache
StakeContenderCache stakeContenderCache GUARDED_BY(cs_stakeContenderCache)
void clearTimedoutRequests() EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager)
std::unordered_map< BlockHash, StakingReward, SaltedUint256Hasher > stakingRewards GUARDED_BY(cs_stakingRewards)
Mutex cs_peerManager
Keep track of the peers and associated infos.
Definition processor.h:168
bool getLocalAcceptance(const AnyVoteItem &item) const
Definition processor.h:458
std::unordered_set< NodeId > delayedAvahelloNodeIds GUARDED_BY(cs_delayedAvahelloNodeIds)
A list of the nodes that did not get our proof announced via avahello yet because we had no inbound c...
void avaproofsSent(NodeId nodeid) LOCKS_EXCLUDED(cs_main) EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager)
double minQuorumConnectedScoreRatio
Definition processor.h:213
void clearFinalizedItems() EXCLUSIVE_LOCKS_REQUIRED(!cs_finalizedItems)
Cache to track stake contenders for recent blocks.
const AnyVoteItem & getVoteItem() const
Definition processor.h:99
VoteItemUpdate(AnyVoteItem itemIn, VoteStatus statusIn)
Definition processor.h:95
const VoteStatus & getStatus() const
Definition processor.h:98
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
Definition chain.h:123
256-bit opaque blob.
Definition uint256.h:129
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition cs_main.cpp:7
bool error(const char *fmt, const Args &...args)
Definition logging.h:263
std::map< AnyVoteItem, VoteRecord, VoteMapComparator > VoteMap
Definition processor.h:139
std::variant< const ProofRef, const CBlockIndex *, const CTransactionRef > AnyVoteItem
Definition processor.h:88
Definition init.h:28
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition rcu.h:259
int64_t NodeId
Definition nodeid.h:10
std::shared_ptr< const CTransaction > CTransactionRef
Response response
static constexpr std::chrono::milliseconds AVALANCHE_DEFAULT_QUERY_TIMEOUT
How long before we consider that a query timed out.
Definition processor.h:58
static constexpr size_t AVALANCHE_MAX_ELEMENT_POLL
Maximum item that can be polled at once.
Definition processor.h:53
static constexpr uint32_t AVALANCHE_FINALIZED_ITEMS_FILTER_NUM_ELEMENTS
The size of the finalized items filter.
Definition processor.h:69
ServiceFlags
nServices flags.
Definition protocol.h:335
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
bool operator()(const CBlockIndex *pindex) const LOCKS_EXCLUDED(cs_main)
GetLocalAcceptance(const Processor &_processor)
Definition processor.h:449
IsWorthPolling(const Processor &_processor)
Definition processor.h:435
bool operator()(const CBlockIndex *pindex) const LOCKS_EXCLUDED(cs_main)
SteadyMilliseconds timeout
Definition processor.h:174
std::vector< CInv > invs
We declare this as mutable so it can be modified in the multi_index.
Definition processor.h:182
std::vector< std::pair< ProofId, CScript > > winners
Definition processor.h:241
Compare proofs by score, then by id in case of equality.
StakeContenderIds are unique for each block to ensure that the peer polling for their acceptance has ...
bool operator()(const AnyVoteItem &lhs, const AnyVoteItem &rhs) const
Definition processor.h:103
Bilingual messages:
Definition translation.h:17
#define LOCK(cs)
Definition sync.h:306
#define EXCLUSIVE_LOCKS_REQUIRED(...)
#define GUARDED_BY(x)
#define LOCKS_EXCLUDED(...)
std::chrono::time_point< std::chrono::steady_clock, std::chrono::milliseconds > SteadyMilliseconds
Definition time.h:31
assert(!tx.IsCoinBase())
static constexpr int AVALANCHE_MAX_INFLIGHT_POLL
How many inflight requests can exist for one item.
Definition voterecord.h:40