Bitcoin ABC  0.26.2
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
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
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  // MMIX Linear Congruent Generator.
63  const uint64_t r1 =
64  6364136223846793005 * uint64_t(nodeid) + 1442695040888963407;
65  // Fibonacci hashing.
66  const uint64_t r2 = 11400714819323198485ull * (nodeid ^ seed);
67  // Combine and extract hash.
68  const uint16_t h = (r1 + r2) >> 48;
69 
73  for (size_t i = 1; i < nodeFilter.size(); i++) {
74  if (nodeFilter[(successfulVotes + i) % nodeFilter.size()] == h) {
75  return false;
76  }
77  }
78 
84  return true;
85 }
86 
88  uint8_t count = inflight.load();
90  if (inflight.compare_exchange_weak(count, count + 1)) {
91  return true;
92  }
93  }
94 
95  return false;
96 }
97 
98 } // namespace avalanche
uint32_t countBits(uint32_t v)
Definition: bitmanip.h:12
int64_t NodeId
Definition: nodeid.h:10
uint16_t getConfidence() const
Definition: voterecord.h:86
const uint32_t seed
Definition: voterecord.h:61
void clearInflightRequest(uint8_t count=1)
Clear count inflight requests.
Definition: voterecord.h:118
std::atomic< uint8_t > inflight
Definition: voterecord.h:58
uint32_t successfulVotes
Definition: voterecord.h:64
bool registerVote(NodeId nodeid, uint32_t error)
Register a new vote for an item and update confidence accordingly.
Definition: voterecord.cpp:13
std::array< uint16_t, 8 > nodeFilter
Definition: voterecord.h:67
bool addNodeToQuorum(NodeId nodeid)
Add the node to the quorum.
Definition: voterecord.cpp:61
bool registerPoll() const
Register that a request is being made regarding that item.
Definition: voterecord.cpp:87
bool isAccepted() const
Vote accounting facilities.
Definition: voterecord.h:84
bool error(const char *fmt, const Args &...args)
Definition: system.h:47
static int count
Definition: tests.c:31
static constexpr int AVALANCHE_MAX_INFLIGHT_POLL
How many inflight requests can exist for one item.
Definition: voterecord.h:40
static constexpr int AVALANCHE_FINALIZATION_SCORE
Finalization score.
Definition: voterecord.h:17