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