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