xrpld
Loading...
Searching...
No Matches
TrustGraph.h
1#pragma once
2
3#include <test/csf/Digraph.h>
4#include <test/csf/random.h>
5
6#include <boost/container/flat_set.hpp>
7
8#include <chrono>
9#include <numeric>
10#include <random>
11#include <vector>
12
13namespace xrpl::test::csf {
14
22template <class Peer>
24{
26
28
29public:
32 TrustGraph() = default;
33
34 Graph const&
36 {
37 return graph_;
38 }
39
49 void
50 trust(Peer const& from, Peer const& to)
51 {
52 graph_.connect(from, to);
53 }
54
63 void
64 untrust(Peer const& from, Peer const& to)
65 {
66 graph_.disconnect(from, to);
67 }
68
69 //< Whether from trusts to
70 [[nodiscard]] bool
71 trusts(Peer const& from, Peer const& to) const
72 {
73 return graph_.connected(from, to);
74 }
75
82 [[nodiscard]] auto
83 trustedPeers(Peer const& a) const
84 {
85 return graph_.outVertices(a);
86 }
87
97
98 //< Return nodes that fail the white-paper no-forking condition
99 [[nodiscard]] std::vector<ForkInfo>
100 forkablePairs(double quorum) const
101 {
102 // Check the forking condition by looking at intersection
103 // of UNL between all pairs of nodes.
104
105 // TODO: Use the improved bound instead of the whitepaper bound.
106
107 using UNL = std::set<Peer>;
108 std::set<UNL> unique;
109 for (Peer const peer : graph_.outVertices())
110 {
111 unique.emplace(std::begin(trustedPeers(peer)), std::end(trustedPeers(peer)));
112 }
113
114 std::vector<UNL> uniqueUNLs(unique.begin(), unique.end());
116
117 // Loop over all pairs of uniqueUNLs
118 for (int i = 0; i < uniqueUNLs.size(); ++i)
119 {
120 for (int j = (i + 1); j < uniqueUNLs.size(); ++j)
121 {
122 auto const& unlA = uniqueUNLs[i];
123 auto const& unlB = uniqueUNLs[j];
124 double const rhs = 2.0 * (1. - quorum) * std::max(unlA.size(), unlB.size());
125
126 int const intersectionSize = std::count_if(
127 unlA.begin(), unlA.end(), [&](Peer p) { return unlB.find(p) != unlB.end(); });
128
129 if (intersectionSize < rhs)
130 {
131 res.emplace_back(ForkInfo{unlA, unlB, intersectionSize, rhs});
132 }
133 }
134 }
135 return res;
136 }
137
141 [[nodiscard]] bool
142 canFork(double quorum) const
143 {
144 return !forkablePairs(quorum).empty();
145 }
146};
147
148} // namespace xrpl::test::csf
T begin(T... args)
Directed graph.
Definition Digraph.h:35
auto trustedPeers(Peer const &a) const
Range over trusted peers.
Definition TrustGraph.h:83
bool trusts(Peer const &from, Peer const &to) const
Definition TrustGraph.h:71
std::vector< ForkInfo > forkablePairs(double quorum) const
Definition TrustGraph.h:100
void trust(Peer const &from, Peer const &to)
Create trust.
Definition TrustGraph.h:50
TrustGraph()=default
Create an empty trust graph.
bool canFork(double quorum) const
Check whether this trust graph satisfies the whitepaper no-forking condition.
Definition TrustGraph.h:142
void untrust(Peer const &from, Peer const &to)
Remove trust.
Definition TrustGraph.h:64
T count_if(T... args)
T emplace_back(T... args)
T end(T... args)
T max(T... args)
T size(T... args)
A single peer in the simulation.
An example of nodes that fail the whitepaper no-forking condition.
Definition TrustGraph.h:91