xrpld
Loading...
Searching...
No Matches
TrustGraph.h
1#pragma once
2
3#include <boost/container/flat_set.hpp>
4
5#include <csf/Digraph.h>
6
7#include <algorithm>
8#include <set>
9#include <vector>
10
11namespace xrpl::test::csf {
12
21template <class Peer>
23{
25
27
28public:
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
64 void
65 untrust(Peer const& from, Peer const& to)
66 {
67 graph_.disconnect(from, to);
68 }
69
70 //< Whether from trusts to
71 [[nodiscard]] bool
72 trusts(Peer const& from, Peer const& to) const
73 {
74 return graph_.connected(from, to);
75 }
76
84 [[nodiscard]] auto
85 trustedPeers(Peer const& a) const
86 {
87 return graph_.outVertices(a);
88 }
89
100
101 //< Return nodes that fail the white-paper no-forking condition
102 [[nodiscard]] std::vector<ForkInfo>
103 forkablePairs(double quorum) const
104 {
105 // Check the forking condition by looking at intersection
106 // of UNL between all pairs of nodes.
107
108 // TODO: Use the improved bound instead of the whitepaper bound.
109
110 using UNL = std::set<Peer>;
111 std::set<UNL> unique;
112 for (Peer const peer : graph_.outVertices())
113 {
114 unique.emplace(std::begin(trustedPeers(peer)), std::end(trustedPeers(peer)));
115 }
116
117 std::vector<UNL> uniqueUNLs(unique.begin(), unique.end());
119
120 // Loop over all pairs of uniqueUNLs
121 for (auto i = 0uz; i < uniqueUNLs.size(); ++i)
122 {
123 for (auto j = i + 1; j < uniqueUNLs.size(); ++j)
124 {
125 auto const& unlA = uniqueUNLs[i];
126 auto const& unlB = uniqueUNLs[j];
127 double const rhs = 2.0 * (1. - quorum) * std::max(unlA.size(), unlB.size());
128
129 int const intersectionSize = std::count_if(
130 unlA.begin(), unlA.end(), [&](Peer p) { return unlB.find(p) != unlB.end(); });
131
132 if (intersectionSize < rhs)
133 {
134 res.emplace_back(ForkInfo{unlA, unlB, intersectionSize, rhs});
135 }
136 }
137 }
138 return res;
139 }
140
145 [[nodiscard]] bool
146 canFork(double quorum) const
147 {
148 return !forkablePairs(quorum).empty();
149 }
150};
151
152} // namespace xrpl::test::csf
T begin(T... args)
Directed graph.
Definition Digraph.h:36
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:72
std::vector< ForkInfo > forkablePairs(double quorum) const
Definition TrustGraph.h:103
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:146
void untrust(Peer const &from, Peer const &to)
Remove trust.
Definition TrustGraph.h:65
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:94