rippled
Loading...
Searching...
No Matches
TrustGraph.h
1#ifndef XRPL_TEST_CSF_UNL_H_INCLUDED
2#define XRPL_TEST_CSF_UNL_H_INCLUDED
3
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 ripple {
14namespace test {
15namespace csf {
16
24template <class Peer>
26{
28
30
31public:
34 TrustGraph() = default;
35
36 Graph const&
38 {
39 return graph_;
40 }
41
51 void
52 trust(Peer const& from, Peer const& to)
53 {
54 graph_.connect(from, to);
55 }
56
65 void
66 untrust(Peer const& from, Peer const& to)
67 {
68 graph_.disconnect(from, to);
69 }
70
71 //< Whether from trusts to
72 bool
73 trusts(Peer const& from, Peer const& to) const
74 {
75 return graph_.connected(from, to);
76 }
77
84 auto
85 trustedPeers(Peer const& a) const
86 {
87 return graph_.outVertices(a);
88 }
89
99
100 //< Return nodes that fail the white-paper no-forking condition
102 forkablePairs(double quorum) const
103 {
104 // Check the forking condition by looking at intersection
105 // of UNL between all pairs of nodes.
106
107 // TODO: Use the improved bound instead of the whitepaper bound.
108
109 using UNL = std::set<Peer>;
110 std::set<UNL> unique;
111 for (Peer const peer : graph_.outVertices())
112 {
113 unique.emplace(
115 }
116
117 std::vector<UNL> uniqueUNLs(unique.begin(), unique.end());
119
120 // Loop over all pairs of uniqueUNLs
121 for (int i = 0; i < uniqueUNLs.size(); ++i)
122 {
123 for (int j = (i + 1); j < uniqueUNLs.size(); ++j)
124 {
125 auto const& unlA = uniqueUNLs[i];
126 auto const& unlB = uniqueUNLs[j];
127 double rhs =
128 2.0 * (1. - quorum) * std::max(unlA.size(), unlB.size());
129
130 int intersectionSize =
131 std::count_if(unlA.begin(), unlA.end(), [&](Peer p) {
132 return unlB.find(p) != unlB.end();
133 });
134
135 if (intersectionSize < rhs)
136 {
137 res.emplace_back(
138 ForkInfo{unlA, unlB, intersectionSize, rhs});
139 }
140 }
141 }
142 return res;
143 }
144
148 bool
149 canFork(double quorum) const
150 {
151 return !forkablePairs(quorum).empty();
152 }
153};
154
155} // namespace csf
156} // namespace test
157} // namespace ripple
158
159#endif
T begin(T... args)
bool connected(Vertex source, Vertex target) const
Check if two vertices are connected.
Definition Digraph.h:119
auto outVertices() const
Range over vertices in the graph.
Definition Digraph.h:130
bool disconnect(Vertex source, Vertex target)
Disconnect two vertices.
Definition Digraph.h:82
bool connect(Vertex source, Vertex target, EdgeData e)
Connect two vertices.
Definition Digraph.h:55
void trust(Peer const &from, Peer const &to)
Create trust.
Definition TrustGraph.h:52
bool canFork(double quorum) const
Check whether this trust graph satisfies the whitepaper no-forking condition.
Definition TrustGraph.h:149
void untrust(Peer const &from, Peer const &to)
Remove trust.
Definition TrustGraph.h:66
std::vector< ForkInfo > forkablePairs(double quorum) const
Definition TrustGraph.h:102
auto trustedPeers(Peer const &a) const
Range over trusted peers.
Definition TrustGraph.h:85
bool trusts(Peer const &from, Peer const &to) const
Definition TrustGraph.h:73
TrustGraph()=default
Create an empty trust graph.
T count_if(T... args)
T emplace_back(T... args)
T end(T... args)
T max(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
T size(T... args)
A single peer in the simulation.
An example of nodes that fail the whitepaper no-forking condition.
Definition TrustGraph.h:93