5#ifndef BITCOIN_AVALANCHE_PROCESSOR_H
6#define BITCOIN_AVALANCHE_PROCESSOR_H
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>
38#include <unordered_map>
76class ProofRegistrationState;
88 std::variant<const ProofRef, const CBlockIndex *, const CTransactionRef>;
105 if (lhs.index() != rhs.index()) {
106 return lhs.index() < rhs.index();
119 return lhs->GetId() < rhs->GetId();
121 [](
const auto &lhs,
const auto &rhs) {
139using VoteMap = std::map<AnyVoteItem, VoteRecord, VoteMapComparator>;
144 struct AvalancheTest;
182 mutable std::vector<CInv>
invs;
187 boost::multi_index::indexed_by<
189 boost::multi_index::hashed_unique<boost::multi_index::composite_key<
191 boost::multi_index::member<Query, NodeId, &Query::nodeid>,
192 boost::multi_index::member<Query, uint64_t, &Query::round>>>,
194 boost::multi_index::ordered_non_unique<
195 boost::multi_index::tag<query_timeout>,
235 std::unordered_set<NodeId>
241 std::vector<std::pair<ProofId, CScript>>
winners;
245 std::unordered_map<BlockHash, StakingReward, SaltedUint256Hasher>
253 CScheduler &scheduler, std::unique_ptr<PeerData> peerDataIn,
254 CKey sessionKeyIn, uint32_t minQuorumTotalScoreIn,
255 double minQuorumConnectedScoreRatioIn,
256 int64_t minAvaproofsNodeCountIn, uint32_t staleVoteThresholdIn,
257 uint32_t staleVoteFactorIn,
Amount stakeUtxoDustThresholdIn,
258 bool preConsensus,
bool stakingPreConsensus);
266 static std::unique_ptr<Processor>
296 template <typename Callable>
300 return func(*peerManager);
326 return finalizationTip !=
nullptr;
354 std::vector<CScript> &payouts) const
357 const
std::vector<CScript> &payouts)
364 std::atomic<bool> &interrupt)
override {
462 friend struct ::avalanche::AvalancheTest;
The block chain is a tree shaped structure starting with the genesis block at the root,...
Inv(ventory) message data.
An encapsulated secp256k1 private key.
Information about a peer.
An encapsulated public key.
RollingBloomFilter is a probabilistic "keep track of most recently inserted" set.
Simple class for background tasks that should be run periodically or once "after a while".
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Interface for message handling.
void sendResponse(CNode *pfrom, Response response) const
const uint32_t staleVoteThreshold
Voting parameters.
std::atomic< bool > quorumIsEstablished
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
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.
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
RWCollection< QuerySet > queries
bool hasFinalizedTip() const EXCLUSIVE_LOCKS_REQUIRED(!cs_finalizationTip)
Whether there is a finalized tip.
bool ProcessMessages(const ::Config &config, CNode *pnode, std::atomic< bool > &interrupt) override
Mutex cs_stakeContenderCache
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)
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.
bool canShareLocalProof()
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.
int64_t minAvaproofsNodeCount
const bool m_preConsensus
Mutex cs_delayedAvahelloNodeIds
bool setStakingRewardWinners(const CBlockIndex *pprev, const std::vector< CScript > &payouts) EXCLUSIVE_LOCKS_REQUIRED(!cs_stakingRewards
void runEventLoop() EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager
bool isAvalancheServiceAvailable()
Mutex cs_invalidatedBlocks
We don't need many blocks but a low false positive rate.
void updatedBlockTip() EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager
RWCollection< VoteMap > voteRecords
Items to run avalanche on.
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
uint32_t minQuorumScore
Quorum management.
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
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
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
void sendDelayedAvahello() EXCLUSIVE_LOCKS_REQUIRED(!cs_delayedAvahelloNodeIds)
std::unique_ptr< PeerData > peerData
bool eraseStakingRewardWinner(const BlockHash &prevBlockHash) EXCLUSIVE_LOCKS_REQUIRED(!cs_stakingRewards)
const bool m_stakingPreConsensus
bool isWorthPolling(const AnyVoteItem &item) const EXCLUSIVE_LOCKS_REQUIRED(!cs_finalizedItems)
CPubKey getSessionPubKey() const
auto withPeerManager(Callable &&func) const EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager)
std::unique_ptr< PeerManager > peerManager GUARDED_BY(cs_peerManager)
Processor(Config avaconfig, interfaces::Chain &chain, CConnman *connmanIn, ChainstateManager &chainman, CTxMemPool *mempoolIn, CScheduler &scheduler, std::unique_ptr< PeerData > peerDataIn, CKey sessionKeyIn, uint32_t minQuorumTotalScoreIn, double minQuorumConnectedScoreRatioIn, int64_t minAvaproofsNodeCountIn, uint32_t staleVoteThresholdIn, uint32_t staleVoteFactorIn, Amount stakeUtxoDustThresholdIn, bool preConsensus, bool stakingPreConsensus)
ChainstateManager & chainman
std::atomic< int64_t > avaproofsNodeCounter
bool SendMessages(const ::Config &config, CNode *pnode) override
bool computeStakingReward(const CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager
ProofRegistrationState getLocalProofRegistrationState() const
CRollingBloomFilter finalizedItems GUARDED_BY(cs_finalizedItems)
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.
bool getLocalAcceptance(const AnyVoteItem &item) const
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
void clearFinalizedItems() EXCLUSIVE_LOCKS_REQUIRED(!cs_finalizedItems)
Cache to track stake contenders for recent blocks.
const AnyVoteItem & getVoteItem() const
VoteItemUpdate(AnyVoteItem itemIn, VoteStatus statusIn)
const VoteStatus & getStatus() const
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
bool error(const char *fmt, const Args &...args)
std::map< AnyVoteItem, VoteRecord, VoteMapComparator > VoteMap
std::variant< const ProofRef, const CBlockIndex *, const CTransactionRef > AnyVoteItem
Implement std::hash so RCUPtr can be used as a key for maps or sets.
std::shared_ptr< const CTransaction > CTransactionRef
static constexpr std::chrono::milliseconds AVALANCHE_DEFAULT_QUERY_TIMEOUT
How long before we consider that a query timed out.
static constexpr size_t AVALANCHE_MAX_ELEMENT_POLL
Maximum item that can be polled at once.
static constexpr uint32_t AVALANCHE_FINALIZED_ITEMS_FILTER_NUM_ELEMENTS
The size of the finalized items filter.
ServiceFlags
nServices flags.
A BlockHash is a unqiue identifier for a block.
bool operator()(const CBlockIndex *pindex) const LOCKS_EXCLUDED(cs_main)
const Processor & processor
GetLocalAcceptance(const Processor &_processor)
IsWorthPolling(const Processor &_processor)
const Processor & processor
bool operator()(const CBlockIndex *pindex) const LOCKS_EXCLUDED(cs_main)
SteadyMilliseconds timeout
std::vector< CInv > invs
We declare this as mutable so it can be modified in the multi_index.
std::vector< std::pair< ProofId, CScript > > winners
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
#define EXCLUSIVE_LOCKS_REQUIRED(...)
#define LOCKS_EXCLUDED(...)
std::chrono::time_point< std::chrono::steady_clock, std::chrono::milliseconds > SteadyMilliseconds
static constexpr int AVALANCHE_MAX_INFLIGHT_POLL
How many inflight requests can exist for one item.