rippled
Loading...
Searching...
No Matches
DistributedValidatorsSim_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012-2016 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <test/csf.h>
21
22#include <xrpl/beast/unit_test.h>
23
24#include <boost/algorithm/string/classification.hpp>
25#include <boost/algorithm/string/split.hpp>
26
27#include <algorithm>
28#include <fstream>
29#include <sstream>
30#include <string>
31#include <utility>
32
33namespace ripple {
34namespace test {
35
39{
40 void
42 std::size_t numPeers,
44 bool printHeaders = false)
45 {
46 using namespace csf;
47 using namespace std::chrono;
48
49 // Initialize persistent collector logs specific to this method
50 std::string const prefix =
51 "DistributedValidators_"
52 "completeTrustCompleteConnectFixedDelay";
53 std::fstream txLog(prefix + "_tx.csv", std::ofstream::app),
54 ledgerLog(prefix + "_ledger.csv", std::ofstream::app);
55
56 // title
57 log << prefix << "(" << numPeers << "," << delay.count() << ")"
58 << std::endl;
59
60 // number of peers, UNLs, connections
61 BEAST_EXPECT(numPeers >= 1);
62
63 Sim sim;
64 PeerGroup peers = sim.createGroup(numPeers);
65
66 // complete trust graph
67 peers.trust(peers);
68
69 // complete connect graph with fixed delay
70 peers.connect(peers, delay);
71
72 // Initialize collectors to track statistics to report
73 TxCollector txCollector;
74 LedgerCollector ledgerCollector;
75 auto colls = makeCollectors(txCollector, ledgerCollector);
76 sim.collectors.add(colls);
77
78 // Initial round to set prior state
79 sim.run(1);
80
81 // Run for 10 minues, submitting 100 tx/second
82 std::chrono::nanoseconds const simDuration = 10min;
83 std::chrono::nanoseconds const quiet = 10s;
84 Rate const rate{100, 1000ms};
85
86 // Initialize timers
87 HeartbeatTimer heart(sim.scheduler);
88
89 // txs, start/stop/step, target
90 auto peerSelector = makeSelector(
91 peers.begin(),
92 peers.end(),
93 std::vector<double>(numPeers, 1.),
94 sim.rng);
95 auto txSubmitter = makeSubmitter(
96 ConstantDistribution{rate.inv()},
97 sim.scheduler.now() + quiet,
98 sim.scheduler.now() + simDuration - quiet,
99 peerSelector,
100 sim.scheduler,
101 sim.rng);
102
103 // run simulation for given duration
104 heart.start();
105 sim.run(simDuration);
106
107 // BEAST_EXPECT(sim.branches() == 1);
108 // BEAST_EXPECT(sim.synchronized());
109
110 log << std::right;
111 log << "| Peers: " << std::setw(2) << peers.size();
112 log << " | Duration: " << std::setw(6)
113 << duration_cast<milliseconds>(simDuration).count() << " ms";
114 log << " | Branches: " << std::setw(1) << sim.branches();
115 log << " | Synchronized: " << std::setw(1)
116 << (sim.synchronized() ? "Y" : "N");
117 log << " |" << std::endl;
118
119 txCollector.report(simDuration, log, true);
120 ledgerCollector.report(simDuration, log, false);
121
122 std::string const tag = std::to_string(numPeers);
123 txCollector.csv(simDuration, txLog, tag, printHeaders);
124 ledgerCollector.csv(simDuration, ledgerLog, tag, printHeaders);
125
126 log << std::endl;
127 }
128
129 void
131 std::size_t numPeers,
133 bool printHeaders = false)
134 {
135 using namespace csf;
136 using namespace std::chrono;
137
138 // Initialize persistent collector logs specific to this method
139 std::string const prefix =
140 "DistributedValidators__"
141 "completeTrustScaleFreeConnectFixedDelay";
142 std::fstream txLog(prefix + "_tx.csv", std::ofstream::app),
143 ledgerLog(prefix + "_ledger.csv", std::ofstream::app);
144
145 // title
146 log << prefix << "(" << numPeers << "," << delay.count() << ")"
147 << std::endl;
148
149 // number of peers, UNLs, connections
150 int const numCNLs = std::max(int(1.00 * numPeers), 1);
151 int const minCNLSize = std::max(int(0.25 * numCNLs), 1);
152 int const maxCNLSize = std::max(int(0.50 * numCNLs), 1);
153 BEAST_EXPECT(numPeers >= 1);
154 BEAST_EXPECT(numCNLs >= 1);
155 BEAST_EXPECT(
156 1 <= minCNLSize && minCNLSize <= maxCNLSize &&
157 maxCNLSize <= numPeers);
158
159 Sim sim;
160 PeerGroup peers = sim.createGroup(numPeers);
161
162 // complete trust graph
163 peers.trust(peers);
164
165 // scale-free connect graph with fixed delay
166 std::vector<double> const ranks =
167 sample(peers.size(), PowerLawDistribution{1, 3}, sim.rng);
168 randomRankedConnect(
169 peers,
170 ranks,
171 numCNLs,
172 std::uniform_int_distribution<>{minCNLSize, maxCNLSize},
173 sim.rng,
174 delay);
175
176 // Initialize collectors to track statistics to report
177 TxCollector txCollector;
178 LedgerCollector ledgerCollector;
179 auto colls = makeCollectors(txCollector, ledgerCollector);
180 sim.collectors.add(colls);
181
182 // Initial round to set prior state
183 sim.run(1);
184
185 // Run for 10 minues, submitting 100 tx/second
186 std::chrono::nanoseconds simDuration = 10min;
187 std::chrono::nanoseconds quiet = 10s;
188 Rate rate{100, 1000ms};
189
190 // Initialize timers
191 HeartbeatTimer heart(sim.scheduler);
192
193 // txs, start/stop/step, target
194 auto peerSelector = makeSelector(
195 peers.begin(),
196 peers.end(),
197 std::vector<double>(numPeers, 1.),
198 sim.rng);
199 auto txSubmitter = makeSubmitter(
200 ConstantDistribution{rate.inv()},
201 sim.scheduler.now() + quiet,
202 sim.scheduler.now() + simDuration - quiet,
203 peerSelector,
204 sim.scheduler,
205 sim.rng);
206
207 // run simulation for given duration
208 heart.start();
209 sim.run(simDuration);
210
211 // BEAST_EXPECT(sim.branches() == 1);
212 // BEAST_EXPECT(sim.synchronized());
213
214 log << std::right;
215 log << "| Peers: " << std::setw(2) << peers.size();
216 log << " | Duration: " << std::setw(6)
217 << duration_cast<milliseconds>(simDuration).count() << " ms";
218 log << " | Branches: " << std::setw(1) << sim.branches();
219 log << " | Synchronized: " << std::setw(1)
220 << (sim.synchronized() ? "Y" : "N");
221 log << " |" << std::endl;
222
223 txCollector.report(simDuration, log, true);
224 ledgerCollector.report(simDuration, log, false);
225
226 std::string const tag = std::to_string(numPeers);
227 txCollector.csv(simDuration, txLog, tag, printHeaders);
228 ledgerCollector.csv(simDuration, ledgerLog, tag, printHeaders);
229
230 log << std::endl;
231 }
232
233 void
234 run() override
235 {
236 std::string const defaultArgs = "5 200";
237 std::string const args = arg().empty() ? defaultArgs : arg();
238 std::stringstream argStream(args);
239
240 int maxNumValidators = 0;
241 int delayCount(200);
242 argStream >> maxNumValidators;
243 argStream >> delayCount;
244
245 std::chrono::milliseconds const delay(delayCount);
246
247 log << "DistributedValidators: 1 to " << maxNumValidators << " Peers"
248 << std::endl;
249
257 for (int i = 2; i <= maxNumValidators; i++)
258 {
260 }
261
269 for (int i = 2; i <= maxNumValidators; i++)
270 {
272 }
273 }
274};
275
276BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(DistributedValidators, consensus, ripple, 2);
277
278} // namespace test
279} // namespace ripple
A testsuite class.
Definition suite.h:55
log_os< char > log
Logging output stream.
Definition suite.h:152
std::string const & arg() const
Return the argument associated with the runner.
Definition suite.h:288
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:32
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
T setw(T... args)
Represents a transfer rate.
Definition Rate.h:40
T to_string(T... args)