xrpld
Loading...
Searching...
No Matches
DistributedValidatorsSim.cpp
1#include <csf/PeerGroup.h>
2#include <csf/Sim.h>
3#include <csf/collectors.h>
4#include <csf/random.h>
5#include <csf/submitters.h>
6#include <csf/timers.h>
7#include <gtest/gtest.h>
8
9#include <algorithm>
10#include <chrono>
11#include <cstddef>
12#include <fstream>
13#include <iomanip>
14#include <ios>
15#include <iostream>
16#include <ostream>
17#include <random>
18#include <sstream>
19#include <string>
20#include <vector>
21
22namespace xrpl::test {
23
24namespace {
25
26[[nodiscard]] std::string const&
27arg()
28{
29 static std::string const kEMPTY;
30 return kEMPTY;
31}
32
33void
34completeTrustCompleteConnectFixedDelay(
35 std::size_t numPeers,
36 std::chrono::milliseconds delay = std::chrono::milliseconds(200),
37 bool printHeaders = false)
38{
39 using namespace csf;
40 using namespace std::chrono;
41
42 // Initialize persistent collector logs specific to this method
43 std::string const prefix =
44 "DistributedValidators_"
45 "completeTrustCompleteConnectFixedDelay";
46 std::fstream txLog(prefix + "_tx.csv", std::ofstream::app),
47 ledgerLog(prefix + "_ledger.csv", std::ofstream::app);
48
49 // title
50 std::cout << prefix << "(" << numPeers << "," << delay.count() << ")" << std::endl;
51
52 // number of peers, UNLs, connections
53 EXPECT_TRUE(numPeers >= 1);
54
55 Sim sim;
56 PeerGroup peers = sim.createGroup(numPeers);
57
58 // complete trust graph
59 peers.trust(peers);
60
61 // complete connect graph with fixed delay
62 peers.connect(peers, delay);
63
64 // Initialize collectors to track statistics to report
65 TxCollector txCollector;
66 LedgerCollector ledgerCollector;
67 auto colls = makeCollectors(txCollector, ledgerCollector);
68 sim.collectors.add(colls);
69
70 // Initial round to set prior state
71 sim.run(1);
72
73 // Run for 10 minutes, submitting 100 tx/second
74 std::chrono::nanoseconds const simDuration = 10min;
75 std::chrono::nanoseconds const quiet = 10s;
76 Rate const rate{.count = 100, .duration = 1000ms};
77
78 // Initialize timers
79 HeartbeatTimer heart(sim.scheduler);
80
81 // txs, start/stop/step, target
82 auto peerSelector =
83 makeSelector(peers.begin(), peers.end(), std::vector<double>(numPeers, 1.), sim.rng);
84 auto txSubmitter = makeSubmitter(
85 ConstantDistribution{rate.inv()},
86 sim.scheduler.now() + quiet,
87 sim.scheduler.now() + simDuration - quiet,
88 peerSelector,
89 sim.scheduler,
90 sim.rng);
91
92 // run simulation for given duration
93 heart.start();
94 sim.run(simDuration);
95
96 // EXPECT_TRUE(sim.branches() == 1);
97 // EXPECT_TRUE(sim.synchronized());
98
99 std::cout << std::right;
100 std::cout << "| Peers: " << std::setw(2) << peers.size();
101 std::cout << " | Duration: " << std::setw(6) << duration_cast<milliseconds>(simDuration).count()
102 << " ms";
103 std::cout << " | Branches: " << std::setw(1) << sim.branches();
104 std::cout << " | Synchronized: " << std::setw(1) << (sim.synchronized() ? "Y" : "N");
105 std::cout << " |" << std::endl;
106
107 txCollector.report(simDuration, std::cout, true);
108 ledgerCollector.report(simDuration, std::cout, false);
109
110 std::string const tag = std::to_string(numPeers);
111 txCollector.csv(simDuration, txLog, tag, printHeaders);
112 ledgerCollector.csv(simDuration, ledgerLog, tag, printHeaders);
113
114 std::cout << std::endl;
115}
116
117void
118completeTrustScaleFreeConnectFixedDelay(
119 std::size_t numPeers,
120 std::chrono::milliseconds delay = std::chrono::milliseconds(200),
121 bool printHeaders = false)
122{
123 using namespace csf;
124 using namespace std::chrono;
125
126 // Initialize persistent collector logs specific to this method
127 std::string const prefix =
128 "DistributedValidators__"
129 "completeTrustScaleFreeConnectFixedDelay";
130 std::fstream txLog(prefix + "_tx.csv", std::ofstream::app),
131 ledgerLog(prefix + "_ledger.csv", std::ofstream::app);
132
133 // title
134 std::cout << prefix << "(" << numPeers << "," << delay.count() << ")" << std::endl;
135
136 // number of peers, UNLs, connections
137 int const numCNLs = std::max(int(1.00 * numPeers), 1);
138 int const minCNLSize = std::max(int(0.25 * numCNLs), 1);
139 int const maxCNLSize = std::max(int(0.50 * numCNLs), 1);
140 EXPECT_TRUE(numPeers >= 1);
141 EXPECT_TRUE(numCNLs >= 1);
142 EXPECT_TRUE(1 <= minCNLSize && minCNLSize <= maxCNLSize && maxCNLSize <= numPeers);
143
144 Sim sim;
145 PeerGroup peers = sim.createGroup(numPeers);
146
147 // complete trust graph
148 peers.trust(peers);
149
150 // scale-free connect graph with fixed delay
151 std::vector<double> const ranks = sample(peers.size(), PowerLawDistribution{1, 3}, sim.rng);
153 peers,
154 ranks,
155 numCNLs,
156 std::uniform_int_distribution<>{minCNLSize, maxCNLSize},
157 sim.rng,
158 delay);
159
160 // Initialize collectors to track statistics to report
161 TxCollector txCollector;
162 LedgerCollector ledgerCollector;
163 auto colls = makeCollectors(txCollector, ledgerCollector);
164 sim.collectors.add(colls);
165
166 // Initial round to set prior state
167 sim.run(1);
168
169 // Run for 10 minutes, submitting 100 tx/second
170 std::chrono::nanoseconds const simDuration = 10min;
171 std::chrono::nanoseconds const quiet = 10s;
172 Rate const rate{.count = 100, .duration = 1000ms};
173
174 // Initialize timers
175 HeartbeatTimer heart(sim.scheduler);
176
177 // txs, start/stop/step, target
178 auto peerSelector =
179 makeSelector(peers.begin(), peers.end(), std::vector<double>(numPeers, 1.), sim.rng);
180 auto txSubmitter = makeSubmitter(
181 ConstantDistribution{rate.inv()},
182 sim.scheduler.now() + quiet,
183 sim.scheduler.now() + simDuration - quiet,
184 peerSelector,
185 sim.scheduler,
186 sim.rng);
187
188 // run simulation for given duration
189 heart.start();
190 sim.run(simDuration);
191
192 // EXPECT_TRUE(sim.branches() == 1);
193 // EXPECT_TRUE(sim.synchronized());
194
195 std::cout << std::right;
196 std::cout << "| Peers: " << std::setw(2) << peers.size();
197 std::cout << " | Duration: " << std::setw(6) << duration_cast<milliseconds>(simDuration).count()
198 << " ms";
199 std::cout << " | Branches: " << std::setw(1) << sim.branches();
200 std::cout << " | Synchronized: " << std::setw(1) << (sim.synchronized() ? "Y" : "N");
201 std::cout << " |" << std::endl;
202
203 txCollector.report(simDuration, std::cout, true);
204 ledgerCollector.report(simDuration, std::cout, false);
205
206 std::string const tag = std::to_string(numPeers);
207 txCollector.csv(simDuration, txLog, tag, printHeaders);
208 ledgerCollector.csv(simDuration, ledgerLog, tag, printHeaders);
209
210 std::cout << std::endl;
211}
212
213} // namespace
214
215// In progress simulations for diversifying and distributing validators
216TEST(DistributedValidatorsTest, DISABLED_distributed_validators)
217{
218 std::string const defaultArgs = "5 200";
219 std::string const args = arg().empty() ? defaultArgs : arg();
220 std::stringstream argStream(args);
221
222 int maxNumValidators = 0;
223 int delayCount(200);
224 argStream >> maxNumValidators;
225 argStream >> delayCount;
226
227 std::chrono::milliseconds const delay(delayCount);
228
229 std::cout << "DistributedValidators: 1 to " << maxNumValidators << " Peers" << std::endl;
230
231 // Simulate with N = 1 to N
232 // - complete trust graph is complete
233 // - complete network connectivity
234 // - fixed delay for network links
235 completeTrustCompleteConnectFixedDelay(1, delay, true);
236 for (int i = 2; i <= maxNumValidators; i++)
237 {
238 completeTrustCompleteConnectFixedDelay(i, delay);
239 }
240
241 // Simulate with N = 1 to N
242 // - complete trust graph is complete
243 // - scale-free network connectivity
244 // - fixed delay for network links
245 completeTrustScaleFreeConnectFixedDelay(1, delay, true);
246 for (int i = 2; i <= maxNumValidators; i++)
247 {
248 completeTrustScaleFreeConnectFixedDelay(i, delay);
249 }
250}
251
252} // namespace xrpl::test
T duration_cast(T... args)
T empty(T... args)
T endl(T... args)
T right(T... args)
T max(T... args)
T min(T... args)
Submitter< Distribution, Generator, Selector > makeSubmitter(Distribution dist, SimTime start, SimTime end, Selector &sel, Scheduler &s, Generator &g)
Definition submitters.h:100
Selector< Iter, Generator > makeSelector(Iter first, Iter last, std::vector< double > const &w, Generator &g)
void randomRankedConnect(PeerGroup &peers, std::vector< double > const &ranks, int numGroups, RandomNumberDistribution sizeDist, Generator &g, SimDuration delay)
Generate random network groups based on peer rankings.
Definition PeerGroup.h:333
Collectors< Cs... > makeCollectors(Cs &... cs)
Create an instance of Collectors<Cs...>.
Definition collectors.h:85
json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
Definition rate.cpp:15
TEST(UnitsTest, types)
Definition Units.cpp:16
T sample(T... args)
T setw(T... args)
T to_string(T... args)