Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche.h
Show All 27 Lines | |||||
class CBlockIndex; | class CBlockIndex; | ||||
class CScheduler; | class CScheduler; | ||||
namespace { | namespace { | ||||
/** | /** | ||||
* Finalization score. | * Finalization score. | ||||
*/ | */ | ||||
static const int AVALANCHE_FINALIZATION_SCORE = 128; | static const int AVALANCHE_FINALIZATION_SCORE = 128; | ||||
/** | /** | ||||
* How long before we consider that a query timed out. | * How long before we consider that a query timed out. | ||||
*/ | */ | ||||
static const int AVALANCHE_DEFAULT_QUERY_TIMEOUT_DURATION_MILLISECONDS = 10000; | static const int AVALANCHE_DEFAULT_QUERY_TIMEOUT_DURATION_MILLISECONDS = 10000; | ||||
/** | |||||
* How many inflight requests can exist for one item. | |||||
*/ | |||||
static const int AVALANCHE_MAX_INFLIGHT_POLL = 10; | |||||
/** | /** | ||||
* Special NodeId that represent no node. | * Special NodeId that represent no node. | ||||
*/ | */ | ||||
static const NodeId NO_NODE = -1; | static const NodeId NO_NODE = -1; | ||||
} | } | ||||
/** | /** | ||||
* Vote history. | * Vote history. | ||||
*/ | */ | ||||
struct VoteRecord { | struct VoteRecord { | ||||
private: | private: | ||||
// Historical record of votes. | // Historical record of votes. | ||||
uint8_t votes = 0; | uint8_t votes = 0; | ||||
// Each bit indicate if the vote is to be considered. | // Each bit indicate if the vote is to be considered. | ||||
uint8_t consider = 0; | uint8_t consider = 0; | ||||
// How many in flight requests exists for this element. | |||||
mutable std::atomic<uint8_t> inflight{0}; | |||||
// confidence's LSB bit is the result. Higher bits are actual confidence | // confidence's LSB bit is the result. Higher bits are actual confidence | ||||
// score. | // score. | ||||
uint16_t confidence = 0; | uint16_t confidence = 0; | ||||
public: | public: | ||||
VoteRecord(bool accepted) : confidence(accepted) {} | VoteRecord(bool accepted) : confidence(accepted) {} | ||||
/** | |||||
* Copy semantic | |||||
*/ | |||||
VoteRecord(const VoteRecord &other) | |||||
: votes(other.votes), consider(other.consider), | |||||
inflight(other.inflight.load()), confidence(other.confidence) {} | |||||
/** | |||||
* Vote accounting facilities. | |||||
*/ | |||||
bool isAccepted() const { return confidence & 0x01; } | bool isAccepted() const { return confidence & 0x01; } | ||||
uint16_t getConfidence() const { return confidence >> 1; } | uint16_t getConfidence() const { return confidence >> 1; } | ||||
bool hasFinalized() const { | bool hasFinalized() const { | ||||
return getConfidence() >= AVALANCHE_FINALIZATION_SCORE; | return getConfidence() >= AVALANCHE_FINALIZATION_SCORE; | ||||
} | } | ||||
/** | /** | ||||
* Register a new vote for an item and update confidence accordingly. | * Register a new vote for an item and update confidence accordingly. | ||||
* Returns true if the acceptance or finalization state changed. | * Returns true if the acceptance or finalization state changed. | ||||
*/ | */ | ||||
bool registerVote(uint32_t error); | bool registerVote(uint32_t error); | ||||
/** | |||||
* Register that a request is being made regarding that item. | |||||
* The method is made const so that it can be accessed via a read only view | |||||
* of vote_records. It's not a problem as it is made thread safe. | |||||
*/ | |||||
bool registerPoll() const; | |||||
/** | |||||
* Return if this item is in condition to be polled at the moment. | |||||
*/ | |||||
bool shouldPoll() const { return inflight < AVALANCHE_MAX_INFLIGHT_POLL; } | |||||
/** | |||||
* Clear `count` inflight requests. | |||||
*/ | |||||
void clearInflightRequest(uint8_t count = 1) { inflight -= count; } | |||||
}; | }; | ||||
class AvalancheVote { | class AvalancheVote { | ||||
uint32_t error; | uint32_t error; | ||||
uint256 hash; | uint256 hash; | ||||
public: | public: | ||||
AvalancheVote() : error(-1), hash() {} | AvalancheVote() : error(-1), hash() {} | ||||
▲ Show 20 Lines • Show All 202 Lines • ▼ Show 20 Lines | public: | ||||
bool addPeer(NodeId nodeid, int64_t score); | bool addPeer(NodeId nodeid, int64_t score); | ||||
bool startEventLoop(CScheduler &scheduler); | bool startEventLoop(CScheduler &scheduler); | ||||
bool stopEventLoop(); | bool stopEventLoop(); | ||||
private: | private: | ||||
void runEventLoop(); | void runEventLoop(); | ||||
void clearTimedoutRequests(); | void clearTimedoutRequests(); | ||||
std::vector<CInv> getInvsForNextPoll() const; | std::vector<CInv> getInvsForNextPoll(bool forPoll = true) const; | ||||
NodeId getSuitableNodeToQuery(); | NodeId getSuitableNodeToQuery(); | ||||
friend struct AvalancheTest; | friend struct AvalancheTest; | ||||
}; | }; | ||||
#endif // BITCOIN_AVALANCHE_H | #endif // BITCOIN_AVALANCHE_H |