xrpld
Loading...
Searching...
No Matches
DistributedValidatorsSim_test.cpp
1#include <test/csf/PeerGroup.h>
2#include <test/csf/Sim.h>
3#include <test/csf/collectors.h>
4#include <test/csf/random.h>
5#include <test/csf/submitters.h>
6#include <test/csf/timers.h>
7
8#include <xrpl/beast/unit_test/suite.h>
9
10#include <algorithm>
11#include <chrono>
12#include <cstddef>
13#include <fstream>
14#include <iomanip>
15#include <ios>
16#include <ostream>
17#include <random>
18#include <sstream>
19#include <string>
20#include <vector>
21
22namespace xrpl::test {
23
27{
28 void
30 std::size_t numPeers,
32 bool printHeaders = false)
33 {
34 using namespace csf;
35 using namespace std::chrono;
36
37 // Initialize persistent collector logs specific to this method
38 std::string const prefix =
39 "DistributedValidators_"
40 "completeTrustCompleteConnectFixedDelay";
41 std::fstream txLog(prefix + "_tx.csv", std::ofstream::app),
42 ledgerLog(prefix + "_ledger.csv", std::ofstream::app);
43
44 // title
45 log << prefix << "(" << numPeers << "," << delay.count() << ")" << std::endl;
46
47 // number of peers, UNLs, connections
48 BEAST_EXPECT(numPeers >= 1);
49
50 Sim sim;
51 PeerGroup peers = sim.createGroup(numPeers);
52
53 // complete trust graph
54 peers.trust(peers);
55
56 // complete connect graph with fixed delay
57 peers.connect(peers, delay);
58
59 // Initialize collectors to track statistics to report
60 TxCollector txCollector;
61 LedgerCollector ledgerCollector;
62 auto colls = makeCollectors(txCollector, ledgerCollector);
63 sim.collectors.add(colls);
64
65 // Initial round to set prior state
66 sim.run(1);
67
68 // Run for 10 minutes, submitting 100 tx/second
69 std::chrono::nanoseconds const simDuration = 10min;
70 std::chrono::nanoseconds const quiet = 10s;
71 Rate const rate{.count = 100, .duration = 1000ms};
72
73 // Initialize timers
74 HeartbeatTimer heart(sim.scheduler);
75
76 // txs, start/stop/step, target
77 auto peerSelector =
78 makeSelector(peers.begin(), peers.end(), std::vector<double>(numPeers, 1.), sim.rng);
79 auto txSubmitter = makeSubmitter(
80 ConstantDistribution{rate.inv()},
81 sim.scheduler.now() + quiet,
82 sim.scheduler.now() + simDuration - quiet,
83 peerSelector,
84 sim.scheduler,
85 sim.rng);
86
87 // run simulation for given duration
88 heart.start();
89 sim.run(simDuration);
90
91 // BEAST_EXPECT(sim.branches() == 1);
92 // BEAST_EXPECT(sim.synchronized());
93
94 log << std::right;
95 log << "| Peers: " << std::setw(2) << peers.size();
96 log << " | Duration: " << std::setw(6) << duration_cast<milliseconds>(simDuration).count()
97 << " ms";
98 log << " | Branches: " << std::setw(1) << sim.branches();
99 log << " | Synchronized: " << std::setw(1) << (sim.synchronized() ? "Y" : "N");
100 log << " |" << std::endl;
101
102 txCollector.report(simDuration, log, true);
103 ledgerCollector.report(simDuration, log, false);
104
105 std::string const tag = std::to_string(numPeers);
106 txCollector.csv(simDuration, txLog, tag, printHeaders);
107 ledgerCollector.csv(simDuration, ledgerLog, tag, printHeaders);
108
109 log << std::endl;
110 }
111
112 void
114 std::size_t numPeers,
116 bool printHeaders = false)
117 {
118 using namespace csf;
119 using namespace std::chrono;
120
121 // Initialize persistent collector logs specific to this method
122 std::string const prefix =
123 "DistributedValidators__"
124 "completeTrustScaleFreeConnectFixedDelay";
125 std::fstream txLog(prefix + "_tx.csv", std::ofstream::app),
126 ledgerLog(prefix + "_ledger.csv", std::ofstream::app);
127
128 // title
129 log << prefix << "(" << numPeers << "," << delay.count() << ")" << std::endl;
130
131 // number of peers, UNLs, connections
132 int const numCNLs = std::max(int(1.00 * numPeers), 1);
133 int const minCNLSize = std::max(int(0.25 * numCNLs), 1);
134 int const maxCNLSize = std::max(int(0.50 * numCNLs), 1);
135 BEAST_EXPECT(numPeers >= 1);
136 BEAST_EXPECT(numCNLs >= 1);
137 BEAST_EXPECT(1 <= minCNLSize && minCNLSize <= maxCNLSize && maxCNLSize <= numPeers);
138
139 Sim sim;
140 PeerGroup peers = sim.createGroup(numPeers);
141
142 // complete trust graph
143 peers.trust(peers);
144
145 // scale-free connect graph with fixed delay
146 std::vector<double> const ranks = sample(peers.size(), PowerLawDistribution{1, 3}, sim.rng);
147 randomRankedConnect(
148 peers,
149 ranks,
150 numCNLs,
151 std::uniform_int_distribution<>{minCNLSize, maxCNLSize},
152 sim.rng,
153 delay);
154
155 // Initialize collectors to track statistics to report
156 TxCollector txCollector;
157 LedgerCollector ledgerCollector;
158 auto colls = makeCollectors(txCollector, ledgerCollector);
159 sim.collectors.add(colls);
160
161 // Initial round to set prior state
162 sim.run(1);
163
164 // Run for 10 minutes, submitting 100 tx/second
165 std::chrono::nanoseconds const simDuration = 10min;
166 std::chrono::nanoseconds const quiet = 10s;
167 Rate const rate{.count = 100, .duration = 1000ms};
168
169 // Initialize timers
170 HeartbeatTimer heart(sim.scheduler);
171
172 // txs, start/stop/step, target
173 auto peerSelector =
174 makeSelector(peers.begin(), peers.end(), std::vector<double>(numPeers, 1.), sim.rng);
175 auto txSubmitter = makeSubmitter(
176 ConstantDistribution{rate.inv()},
177 sim.scheduler.now() + quiet,
178 sim.scheduler.now() + simDuration - quiet,
179 peerSelector,
180 sim.scheduler,
181 sim.rng);
182
183 // run simulation for given duration
184 heart.start();
185 sim.run(simDuration);
186
187 // BEAST_EXPECT(sim.branches() == 1);
188 // BEAST_EXPECT(sim.synchronized());
189
190 log << std::right;
191 log << "| Peers: " << std::setw(2) << peers.size();
192 log << " | Duration: " << std::setw(6) << duration_cast<milliseconds>(simDuration).count()
193 << " ms";
194 log << " | Branches: " << std::setw(1) << sim.branches();
195 log << " | Synchronized: " << std::setw(1) << (sim.synchronized() ? "Y" : "N");
196 log << " |" << std::endl;
197
198 txCollector.report(simDuration, log, true);
199 ledgerCollector.report(simDuration, log, false);
200
201 std::string const tag = std::to_string(numPeers);
202 txCollector.csv(simDuration, txLog, tag, printHeaders);
203 ledgerCollector.csv(simDuration, ledgerLog, tag, printHeaders);
204
205 log << std::endl;
206 }
207
208 void
209 run() override
210 {
211 std::string const defaultArgs = "5 200";
212 std::string const args = arg().empty() ? defaultArgs : arg();
213 std::stringstream argStream(args);
214
215 int maxNumValidators = 0;
216 int delayCount(200);
217 argStream >> maxNumValidators;
218 argStream >> delayCount;
219
220 std::chrono::milliseconds const delay(delayCount);
221
222 log << "DistributedValidators: 1 to " << maxNumValidators << " Peers" << std::endl;
223
231 for (int i = 2; i <= maxNumValidators; i++)
232 {
234 }
235
243 for (int i = 2; i <= maxNumValidators; i++)
244 {
246 }
247 }
248};
249
250BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(DistributedValidators, consensus, xrpl, 2);
251
252} // namespace xrpl::test
A testsuite class.
Definition suite.h:50
LogOs< char > log
Logging output stream.
Definition suite.h:146
std::string const & arg() const
Return the argument associated with the runner.
Definition suite.h:278
In progress simulations for diversifying and distributing validators.
void completeTrustCompleteConnectFixedDelay(std::size_t numPeers, std::chrono::milliseconds delay=std::chrono::milliseconds(200), bool printHeaders=false)
void completeTrustScaleFreeConnectFixedDelay(std::size_t numPeers, std::chrono::milliseconds delay=std::chrono::milliseconds(200), bool printHeaders=false)
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)
json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
Definition rate.cpp:15
BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(CrossingLimits, app, xrpl, 10)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
T sample(T... args)
T setw(T... args)
Represents a transfer rate.
Definition Rate.h:20
T to_string(T... args)