Bitcoin ABC  0.24.7 P2P Digital Currency
voterecord.cpp
Go to the documentation of this file.
1 // Copyright (c) 2021 The Bitcoin developers
2 // Distributed under the MIT software license, see the accompanying
4
5 #include <avalanche/voterecord.h>
6
7 #include <util/bitmanip.h>
8
9 #include <cstddef>
10
11 namespace avalanche {
12
13 bool VoteRecord::registerVote(NodeId nodeid, uint32_t error) {
14  // We just got a new vote, so there is one less inflight request.
16
17  // We want to avoid having the same node voting twice in a quorum.
18  if (!addNodeToQuorum(nodeid)) {
19  return false;
20  }
21
29  votes = (votes << 1) | (error == 0);
30  consider = (consider << 1) | (int32_t(error) >= 0);
31
41  bool yes = countBits(votes & consider & 0xff) > 6;
42  if (!yes) {
43  bool no = countBits(~votes & consider & 0xff) > 6;
44  if (!no) {
45  // The round is inconclusive.
46  return false;
47  }
48  }
49
50  // If the round is in agreement with previous rounds, increase confidence.
51  if (isAccepted() == yes) {
52  confidence += 2;
54  }
55
56  // The round changed our state. We reset the confidence.
57  confidence = yes;
58  return true;
59 }
60
62  if (nodeid == NO_NODE) {
63  // Helpful for testing.
64  return true;
65  }
66
67  // MMIX Linear Congruent Generator.
68  const uint64_t r1 =
69  6364136223846793005 * uint64_t(nodeid) + 1442695040888963407;
70  // Fibonacci hashing.
71  const uint64_t r2 = 11400714819323198485ull * (nodeid ^ seed);
72  // Combine and extract hash.
73  const uint16_t h = (r1 + r2) >> 48;
74
78  for (size_t i = 1; i < nodeFilter.size(); i++) {
79  if (nodeFilter[(successfulVotes + i) % nodeFilter.size()] == h) {
80  return false;
81  }
82  }
83
89  return true;
90 }
91
93  uint8_t count = inflight.load();
95  if (inflight.compare_exchange_weak(count, count + 1)) {
96  return true;
97  }
98  }
99
100  return false;
101 }
102
103 } // namespace avalanche
bitmanip.h
count
static int count
Definition: tests.c:41
avalanche::VoteRecord::confidence
uint16_t confidence
Definition: voterecord.h:33
avalanche::VoteRecord::nodeFilter
std::array< uint16_t, 8 > nodeFilter
Definition: voterecord.h:49
AVALANCHE_MAX_INFLIGHT_POLL
static constexpr int AVALANCHE_MAX_INFLIGHT_POLL
How many inflight requests can exist for one item.
Definition: voterecord.h:22
Add the node to the quorum.
Definition: voterecord.cpp:61
avalanche
Definition: avalanche.h:11
avalanche::VoteRecord::seed
const uint32_t seed
Definition: voterecord.h:43
avalanche::VoteRecord::registerPoll
bool registerPoll() const
Register that a request is being made regarding that item.
Definition: voterecord.cpp:92
avalanche::VoteRecord::getConfidence
uint16_t getConfidence() const
Definition: voterecord.h:68
avalanche::VoteRecord::isAccepted
bool isAccepted() const
Vote accounting facilities.
Definition: voterecord.h:66
avalanche::VoteRecord::clearInflightRequest
void clearInflightRequest(uint8_t count=1)
Clear count inflight requests.
Definition: voterecord.h:94
AVALANCHE_FINALIZATION_SCORE
static constexpr int AVALANCHE_FINALIZATION_SCORE
Finalization score.
Definition: voterecord.h:17
countBits
uint32_t countBits(uint32_t v)
Definition: bitmanip.h:12
NO_NODE
static constexpr NodeId NO_NODE
Special NodeId that represent no node.
Definition: nodeid.h:15
voterecord.h
Definition: voterecord.h:46
avalanche::VoteRecord::inflight
std::atomic< uint8_t > inflight
Definition: voterecord.h:40
Definition: voterecord.h:36
avalanche::VoteRecord::consider
uint8_t consider
Definition: voterecord.h:38
NodeId
int64_t NodeId
Definition: nodeid.h:10
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
avalanche::VoteRecord::registerVote
bool registerVote(NodeId nodeid, uint32_t error)
Register a new vote for an item and update confidence accordingly.
Definition: voterecord.cpp:13