rippled
TheoreticalQuality_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2019 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 <ripple/app/paths/Flow.h>
21 #include <ripple/app/paths/impl/Steps.h>
22 #include <ripple/app/paths/impl/StrandFlow.h>
23 #include <ripple/basics/contract.h>
24 #include <ripple/basics/random.h>
25 #include <ripple/core/Config.h>
26 #include <ripple/ledger/ApplyViewImpl.h>
27 #include <ripple/ledger/PaymentSandbox.h>
28 #include <ripple/ledger/Sandbox.h>
29 #include <ripple/protocol/Feature.h>
30 #include <ripple/protocol/jss.h>
31 #include <test/jtx.h>
32 #include <test/jtx/PathSet.h>
33 
34 namespace ripple {
35 namespace test {
36 
38 {
41 
44 
46 
47  explicit RippleCalcTestParams(Json::Value const& jv)
48  : srcAccount{*parseBase58<AccountID>(jv[jss::Account].asString())}
49  , dstAccount{*parseBase58<AccountID>(jv[jss::Destination].asString())}
50  , dstAmt{amountFromJson(sfAmount, jv[jss::Amount])}
51  {
52  if (jv.isMember(jss::SendMax))
53  sendMax = amountFromJson(sfSendMax, jv[jss::SendMax]);
54 
55  if (jv.isMember(jss::Paths))
56  {
57  // paths is an array of arrays
58  // each leaf element will be of the form
59  for (auto const& path : jv[jss::Paths])
60  {
61  STPath p;
62  for (auto const& pe : path)
63  {
64  if (pe.isMember(jss::account))
65  {
66  assert(
67  !pe.isMember(jss::currency) &&
68  !pe.isMember(jss::issuer));
69  p.emplace_back(
70  *parseBase58<AccountID>(
71  pe[jss::account].asString()),
72  std::nullopt,
73  std::nullopt);
74  }
75  else if (
76  pe.isMember(jss::currency) && pe.isMember(jss::issuer))
77  {
78  auto const currency =
79  to_currency(pe[jss::currency].asString());
81  if (!isXRP(currency))
82  issuer = *parseBase58<AccountID>(
83  pe[jss::issuer].asString());
84  else
85  assert(isXRP(*parseBase58<AccountID>(
86  pe[jss::issuer].asString())));
87  p.emplace_back(std::nullopt, currency, issuer);
88  }
89  else
90  {
91  assert(0);
92  }
93  }
94  paths.emplace_back(std::move(p));
95  }
96  }
97  }
98 };
99 
100 // Class to randomly set an account's transfer rate, quality in, quality out,
101 // and initial balance
103 {
106  // Balance to set if an account redeems into another account. Otherwise
107  // the balance will be zero. Since we are testing quality measures, the
108  // payment should not use multiple qualities, so the initialBalance
109  // needs to be able to handle an entire payment (otherwise an account
110  // will go from redeeming to issuing and the fees/qualities can change)
112 
113  // probability of changing a value from its default
114  constexpr static double probChangeDefault_ = 0.75;
115  // probability that an account redeems into another account
116  constexpr static double probRedeem_ = 0.5;
120 
121  bool
123  {
125  };
126 
127  void
129  {
130  if (!shouldSet())
131  return;
132 
133  auto const percent = qualityPercentDist_(engine_);
134  auto const& field =
136  auto const value =
137  static_cast<std::uint32_t>((percent / 100) * QUALITY_ONE);
138  jv[field.jsonName] = value;
139  };
140 
141  // Setup the trust amounts and in/out qualities (but not the balances)
142  void
144  jtx::Env& env,
145  jtx::Account const& acc,
146  jtx::Account const& peer,
147  Currency const& currency)
148  {
149  using namespace jtx;
150  IOU const iou{peer, currency};
151  Json::Value jv = trust(acc, iou(trustAmount_));
154  env(jv);
155  env.close();
156  };
157 
158 public:
160  std::uint32_t trustAmount = 100,
161  std::uint32_t initialBalance = 50)
162  // Use a deterministic seed so the unit tests run in a reproducible way
163  : engine_{1977u}
164  , trustAmount_{trustAmount}
165  , initialBalance_{initialBalance} {};
166 
167  void
169  {
170  if (shouldSet())
171  env(rate(acc, transferRateDist_(engine_)));
172  }
173 
174  // Set the initial balance, taking into account the qualities
175  void
177  jtx::Env& env,
178  jtx::Account const& acc,
179  jtx::Account const& peer,
180  Currency const& currency)
181  {
182  using namespace jtx;
183  IOU const iou{acc, currency};
184  // This payment sets the acc's balance to `initialBalance`.
185  // Since input qualities complicate this payment, use `sendMax` with
186  // `initialBalance` to make sure the balance is set correctly.
187  env(pay(peer, acc, iou(trustAmount_)),
188  sendmax(iou(initialBalance_)),
190  env.close();
191  }
192 
193  void
195  jtx::Env& env,
196  jtx::Account const& acc,
197  jtx::Account const& peer,
198  Currency const& currency)
199  {
200  using namespace jtx;
202  return;
203  setInitialBalance(env, acc, peer, currency);
204  }
205 
206  // Setup the trust amounts and in/out qualities (but not the balances) on
207  // both sides of the trust line
208  void
210  jtx::Env& env,
211  jtx::Account const& acc1,
212  jtx::Account const& acc2,
213  Currency const& currency)
214  {
215  setupTrustLine(env, acc1, acc2, currency);
216  setupTrustLine(env, acc2, acc1, currency);
217  };
218 };
219 
220 class TheoreticalQuality_test : public beast::unit_test::suite
221 {
222  static std::string
223  prettyQuality(Quality const& q)
224  {
225  std::stringstream sstr;
226  STAmount rate = q.rate();
227  sstr << rate << " (" << q << ")";
228  return sstr.str();
229  };
230 
231  template <class Stream>
232  static void
233  logStrand(Stream& stream, Strand const& strand)
234  {
235  stream << "Strand:\n";
236  for (auto const& step : strand)
237  stream << "\n" << *step;
238  stream << "\n\n";
239  };
240 
241  void
243  RippleCalcTestParams const& rcp,
245  std::optional<Quality> const& expectedQ = {})
246  {
247  PaymentSandbox sb(closed.get(), tapNONE);
248 
249  auto const sendMaxIssue = [&rcp]() -> std::optional<Issue> {
250  if (rcp.sendMax)
251  return rcp.sendMax->issue();
252  return std::nullopt;
253  }();
254 
256 
257  auto sr = toStrands(
258  sb,
259  rcp.srcAccount,
260  rcp.dstAccount,
261  rcp.dstAmt.issue(),
262  /*limitQuality*/ std::nullopt,
263  sendMaxIssue,
264  rcp.paths,
265  /*defaultPaths*/ rcp.paths.empty(),
266  sb.rules().enabled(featureOwnerPaysFee),
267  /*offerCrossing*/ false,
268  dummyJ);
269 
270  BEAST_EXPECT(sr.first == tesSUCCESS);
271 
272  if (sr.first != tesSUCCESS)
273  return;
274 
275  // Due to the floating point calculations, theoretical and actual
276  // qualities are not expected to always be exactly equal. However, they
277  // should always be very close. This function checks that that two
278  // qualities are "close enough".
279  auto compareClose = [](Quality const& q1, Quality const& q2) {
280  // relative diff is fabs(a-b)/min(a,b)
281  // can't get access to internal value. Use the rate
282  constexpr double tolerance = 0.0000001;
283  return relativeDistance(q1, q2) <= tolerance;
284  };
285 
286  for (auto const& strand : sr.second)
287  {
288  Quality const theoreticalQ = *qualityUpperBound(sb, strand);
289  auto const f = flow<IOUAmount, IOUAmount>(
290  sb, strand, IOUAmount(10, 0), IOUAmount(5, 0), dummyJ);
291  BEAST_EXPECT(f.success);
292  Quality const actualQ(f.out, f.in);
293  if (actualQ != theoreticalQ && !compareClose(actualQ, theoreticalQ))
294  {
295  BEAST_EXPECT(actualQ == theoreticalQ); // get the failure
296  log << "\nAcutal != Theoretical\n";
297  log << "\nTQ: " << prettyQuality(theoreticalQ) << "\n";
298  log << "AQ: " << prettyQuality(actualQ) << "\n";
299  logStrand(log, strand);
300  }
301  if (expectedQ && expectedQ != theoreticalQ &&
302  !compareClose(*expectedQ, theoreticalQ))
303  {
304  BEAST_EXPECT(expectedQ == theoreticalQ); // get the failure
305  log << "\nExpected != Theoretical\n";
306  log << "\nTQ: " << prettyQuality(theoreticalQ) << "\n";
307  log << "EQ: " << prettyQuality(*expectedQ) << "\n";
308  logStrand(log, strand);
309  }
310  };
311  }
312 
313 public:
314  void
315  testDirectStep(std::optional<int> const& reqNumIterations)
316  {
317  testcase("Direct Step");
318 
319  // clang-format off
320 
321  // Set up a payment through four accounts: alice -> bob -> carol -> dan
322  // For each relevant trust line on the path, there are three things that can vary:
323  // 1) input quality
324  // 2) output quality
325  // 3) debt direction
326  // For each account, there is one thing that can vary:
327  // 1) transfer rate
328 
329  // clang-format on
330 
331  using namespace jtx;
332 
333  auto const currency = to_currency("USD");
334 
335  constexpr std::size_t const numAccounts = 4;
336 
337  // There are three relevant trust lines: `alice->bob`, `bob->carol`, and
338  // `carol->dan`. There are four accounts. If we count the number of
339  // combinations of parameters where a parameter is changed from its
340  // default value, there are
341  // 2^(num_trust_lines*num_trust_qualities+numAccounts) combinations of
342  // values to test, or 2^13 combinations. Use this value to set the
343  // number of iterations. Note however that many of these parameter
344  // combinations run essentially the same test. For example, changing the
345  // quality values for bob and carol test almost the same thing.
346  // Similarly, changing the transfer rates on bob and carol test almost
347  // the same thing. Instead of systematically running these 8k tests,
348  // randomly sample the test space.
349  int const numTestIterations = reqNumIterations.value_or(250);
350 
351  constexpr std::uint32_t paymentAmount = 1;
352 
353  // Class to randomly set account transfer rates, qualities, and other
354  // params.
355  RandomAccountParams rndAccParams;
356 
357  // Tests are sped up by a factor of 2 if a new environment isn't created
358  // on every iteration.
359  Env env(*this, supported_amendments());
360  for (int i = 0; i < numTestIterations; ++i)
361  {
362  auto const iterAsStr = std::to_string(i);
363  // New set of accounts on every iteration so the environment doesn't
364  // need to be recreated (2x speedup)
365  auto const alice = Account("alice" + iterAsStr);
366  auto const bob = Account("bob" + iterAsStr);
367  auto const carol = Account("carol" + iterAsStr);
368  auto const dan = Account("dan" + iterAsStr);
369  std::array<Account, numAccounts> accounts{{alice, bob, carol, dan}};
370  static_assert(
371  numAccounts == 4, "Path is only correct for four accounts");
372  path const accountsPath(accounts[1], accounts[2]);
373  env.fund(XRP(10000), alice, bob, carol, dan);
374  env.close();
375 
376  // iterate through all pairs of accounts, randomly set the transfer
377  // rate, qIn, qOut, and if the account issues or redeems
378  for (std::size_t ii = 0; ii < numAccounts; ++ii)
379  {
380  rndAccParams.maybeSetTransferRate(env, accounts[ii]);
381  // The payment is from:
382  // account[0] -> account[1] -> account[2] -> account[3]
383  // set the trust lines and initial balances for each pair of
384  // neighboring accounts
385  std::size_t const j = ii + 1;
386  if (j == numAccounts)
387  continue;
388 
389  rndAccParams.setupTrustLines(
390  env, accounts[ii], accounts[j], currency);
391  rndAccParams.maybeSetInitialBalance(
392  env, accounts[ii], accounts[j], currency);
393  }
394 
395  // Accounts are set up, make the payment
396  IOU const iou{accounts.back(), currency};
397  RippleCalcTestParams rcp{env.json(
398  pay(accounts.front(), accounts.back(), iou(paymentAmount)),
399  accountsPath,
401 
402  testCase(rcp, env.closed());
403  }
404  }
405 
406  void
407  testBookStep(std::optional<int> const& reqNumIterations)
408  {
409  testcase("Book Step");
410  using namespace jtx;
411 
412  // clang-format off
413 
414  // Setup a payment through an offer: alice (USD/bob) -> bob -> (USD/bob)|(EUR/carol) -> carol -> dan
415  // For each relevant trust line, vary input quality, output quality, debt direction.
416  // For each account, vary transfer rate.
417  // The USD/bob|EUR/carol offer owner is "Oscar"
418 
419  // clang-format on
420 
421  int const numTestIterations = reqNumIterations.value_or(100);
422 
423  constexpr std::uint32_t paymentAmount = 1;
424 
425  Currency const eurCurrency = to_currency("EUR");
426  Currency const usdCurrency = to_currency("USD");
427 
428  // Class to randomly set account transfer rates, qualities, and other
429  // params.
430  RandomAccountParams rndAccParams;
431 
432  // Speed up tests by creating the environment outside the loop
433  // (factor of 2 speedup on the DirectStep tests)
434  Env env(*this, supported_amendments());
435  for (int i = 0; i < numTestIterations; ++i)
436  {
437  auto const iterAsStr = std::to_string(i);
438  auto const alice = Account("alice" + iterAsStr);
439  auto const bob = Account("bob" + iterAsStr);
440  auto const carol = Account("carol" + iterAsStr);
441  auto const dan = Account("dan" + iterAsStr);
442  auto const oscar = Account("oscar" + iterAsStr); // offer owner
443  auto const USDB = bob["USD"];
444  auto const EURC = carol["EUR"];
445  constexpr std::size_t const numAccounts = 5;
447  {alice, bob, carol, dan, oscar}};
448 
449  // sendmax should be in USDB and delivered amount should be in EURC
450  // normalized path should be:
451  // alice -> bob -> (USD/bob)|(EUR/carol) -> carol -> dan
452  path const bookPath(~EURC);
453 
454  env.fund(XRP(10000), alice, bob, carol, dan, oscar);
455  env.close();
456 
457  for (auto const& acc : accounts)
458  rndAccParams.maybeSetTransferRate(env, acc);
459 
460  for (auto const& currency : {usdCurrency, eurCurrency})
461  {
462  rndAccParams.setupTrustLines(
463  env, alice, bob, currency); // first step in payment
464  rndAccParams.setupTrustLines(
465  env, carol, dan, currency); // last step in payment
466  rndAccParams.setupTrustLines(
467  env, oscar, bob, currency); // offer owner
468  rndAccParams.setupTrustLines(
469  env, oscar, carol, currency); // offer owner
470  }
471 
472  rndAccParams.maybeSetInitialBalance(env, alice, bob, usdCurrency);
473  rndAccParams.maybeSetInitialBalance(env, carol, dan, eurCurrency);
474  rndAccParams.setInitialBalance(env, oscar, bob, usdCurrency);
475  rndAccParams.setInitialBalance(env, oscar, carol, eurCurrency);
476 
477  env(offer(oscar, USDB(50), EURC(50)));
478  env.close();
479 
480  // Accounts are set up, make the payment
481  IOU const srcIOU{bob, usdCurrency};
482  IOU const dstIOU{carol, eurCurrency};
483  RippleCalcTestParams rcp{env.json(
484  pay(alice, dan, dstIOU(paymentAmount)),
485  sendmax(srcIOU(100 * paymentAmount)),
486  bookPath,
488 
489  testCase(rcp, env.closed());
490  }
491  }
492 
493  void
495  {
496  testcase("Relative quality distance");
497 
498  auto toQuality = [](std::uint64_t mantissa,
499  int exponent = 0) -> Quality {
500  // The only way to construct a Quality from an STAmount is to take
501  // their ratio. Set the denominator STAmount to `one` to easily
502  // create a quality from a single amount
503  STAmount const one{noIssue(), 1};
504  STAmount const v{noIssue(), mantissa, exponent};
505  return Quality{one, v};
506  };
507 
508  BEAST_EXPECT(relativeDistance(toQuality(100), toQuality(100)) == 0);
509  BEAST_EXPECT(relativeDistance(toQuality(100), toQuality(100, 1)) == 9);
510  BEAST_EXPECT(relativeDistance(toQuality(100), toQuality(110)) == .1);
511  BEAST_EXPECT(
512  relativeDistance(toQuality(100, 90), toQuality(110, 90)) == .1);
513  BEAST_EXPECT(
514  relativeDistance(toQuality(100, 90), toQuality(110, 91)) == 10);
515  BEAST_EXPECT(
516  relativeDistance(toQuality(100, 0), toQuality(100, 90)) == 1e90);
517  // Make the mantissa in the smaller value bigger than the mantissa in
518  // the larger value. Instead of checking the exact result, we check that
519  // it's large. If the values did not compare correctly in
520  // `relativeDistance`, then the returned value would be negative.
521  BEAST_EXPECT(
522  relativeDistance(toQuality(102, 0), toQuality(101, 90)) >= 1e89);
523  }
524 
525  void
526  run() override
527  {
528  // Use the command line argument `--unittest-arg=500 ` to change the
529  // number of iterations to 500
530  auto const numIterations = [s = arg()]() -> std::optional<int> {
531  if (s.empty())
532  return std::nullopt;
533  try
534  {
535  std::size_t pos;
536  auto const r = stoi(s, &pos);
537  if (pos != s.size())
538  return std::nullopt;
539  return r;
540  }
541  catch (...)
542  {
543  return std::nullopt;
544  }
545  }();
546  testRelativeQDistance();
547  testDirectStep(numIterations);
548  testBookStep(numIterations);
549  }
550 };
551 
552 BEAST_DEFINE_TESTSUITE_PRIO(TheoreticalQuality, app, ripple, 3);
553 
554 } // namespace test
555 } // namespace ripple
ripple::test::RandomAccountParams::engine_
beast::xor_shift_engine engine_
Definition: TheoreticalQuality_test.cpp:104
ripple::to_currency
bool to_currency(Currency &currency, std::string const &code)
Tries to convert a string to a Currency, returns true on success.
Definition: UintTypes.cpp:80
ripple::test::RandomAccountParams::transferRateDist_
std::uniform_real_distribution transferRateDist_
Definition: TheoreticalQuality_test.cpp:118
ripple::test::jtx::XRP
const XRP_t XRP
Converts to XRP Issue or STAmount.
Definition: amount.cpp:105
ripple::sfSendMax
const SF_AMOUNT sfSendMax
std::string
STL class.
std::shared_ptr
STL class.
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:347
ripple::sfAmount
const SF_AMOUNT sfAmount
ripple::PaymentSandbox
A wrapper which makes credits unavailable to balances.
Definition: PaymentSandbox.h:112
ripple::test::TheoreticalQuality_test::logStrand
static void logStrand(Stream &stream, Strand const &strand)
Definition: TheoreticalQuality_test.cpp:233
ripple::test::jtx::Env::closed
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
Definition: Env.cpp:115
ripple::sfQualityOut
const SF_UINT32 sfQualityOut
ripple::test::RippleCalcTestParams
Definition: TheoreticalQuality_test.cpp:37
ripple::test::RandomAccountParams::setInitialBalance
void setInitialBalance(jtx::Env &env, jtx::Account const &acc, jtx::Account const &peer, Currency const &currency)
Definition: TheoreticalQuality_test.cpp:176
ripple::test::RandomAccountParams::setupTrustLines
void setupTrustLines(jtx::Env &env, jtx::Account const &acc1, jtx::Account const &acc2, Currency const &currency)
Definition: TheoreticalQuality_test.cpp:209
ripple::test::jtx::trust
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
Definition: trust.cpp:30
std::optional::value_or
T value_or(T... args)
std::stringstream
STL class.
ripple::sfQualityIn
const SF_UINT32 sfQualityIn
std::shared_ptr::get
T get(T... args)
ripple::STPathSet::emplace_back
void emplace_back(Args &&... args)
Definition: STPathSet.h:516
ripple::QualityDirection::in
@ in
ripple::noIssue
Issue const & noIssue()
Returns an asset specifier that represents no account and currency.
Definition: Issue.h:103
ripple::test::RandomAccountParams::maybeSetInitialBalance
void maybeSetInitialBalance(jtx::Env &env, jtx::Account const &acc, jtx::Account const &peer, Currency const &currency)
Definition: TheoreticalQuality_test.cpp:194
ripple::tapNONE
@ tapNONE
Definition: ApplyView.h:30
beast::Journal::getNullSink
static Sink & getNullSink()
Returns a Sink which does nothing.
Definition: beast_Journal.cpp:72
ripple::test::RippleCalcTestParams::RippleCalcTestParams
RippleCalcTestParams(Json::Value const &jv)
Definition: TheoreticalQuality_test.cpp:47
ripple::STPathSet
Definition: STPathSet.h:176
ripple::test::BEAST_DEFINE_TESTSUITE_PRIO
BEAST_DEFINE_TESTSUITE_PRIO(AccountDelete, app, ripple, 2)
ripple::STPathSet::empty
bool empty() const
Definition: STPathSet.h:503
std::uniform_real_distribution
ripple::toStrands
std::pair< TER, std::vector< Strand > > toStrands(ReadView const &view, AccountID const &src, AccountID const &dst, Issue const &deliver, std::optional< Quality > const &limitQuality, std::optional< Issue > const &sendMax, STPathSet const &paths, bool addDefaultPath, bool ownerPaysTransferFee, bool offerCrossing, beast::Journal j)
Create a Strand for each specified path (including the default path, if indicated)
Definition: PaySteps.cpp:466
ripple::base_uint< 160, detail::AccountIDTag >
ripple::test::RandomAccountParams::qualityPercentDist_
std::uniform_real_distribution qualityPercentDist_
Definition: TheoreticalQuality_test.cpp:119
ripple::test::RandomAccountParams::trustAmount_
const std::uint32_t trustAmount_
Definition: TheoreticalQuality_test.cpp:105
ripple::QualityDirection::out
@ out
std::log
T log(T... args)
ripple::tfPartialPayment
constexpr std::uint32_t tfPartialPayment
Definition: TxFlags.h:102
ripple::test::RandomAccountParams::shouldSet
bool shouldSet()
Definition: TheoreticalQuality_test.cpp:122
ripple::test::RandomAccountParams::initialBalance_
const std::uint32_t initialBalance_
Definition: TheoreticalQuality_test.cpp:111
ripple::test::RandomAccountParams::zeroOneDist_
std::uniform_real_distribution zeroOneDist_
Definition: TheoreticalQuality_test.cpp:117
ripple::test::RandomAccountParams::probRedeem_
constexpr static double probRedeem_
Definition: TheoreticalQuality_test.cpp:116
ripple::test::TheoreticalQuality_test::prettyQuality
static std::string prettyQuality(Quality const &q)
Definition: TheoreticalQuality_test.cpp:223
ripple::test::TheoreticalQuality_test::testRelativeQDistance
void testRelativeQDistance()
Definition: TheoreticalQuality_test.cpp:494
ripple::test::jtx::sendmax
Sets the SendMax on a JTx.
Definition: sendmax.h:31
ripple::test::RandomAccountParams::maybeSetTransferRate
void maybeSetTransferRate(jtx::Env &env, jtx::Account const &acc)
Definition: TheoreticalQuality_test.cpp:168
std::to_string
T to_string(T... args)
ripple::test::TheoreticalQuality_test::testCase
void testCase(RippleCalcTestParams const &rcp, std::shared_ptr< ReadView const > closed, std::optional< Quality > const &expectedQ={})
Definition: TheoreticalQuality_test.cpp:242
std::array
STL class.
ripple::test::jtx::txflags
Set the flags on a JTx.
Definition: txflags.h:30
ripple::test::jtx::Env::close
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition: Env.cpp:121
ripple::STAmount
Definition: STAmount.h:45
ripple::test::RippleCalcTestParams::sendMax
std::optional< STAmount > sendMax
Definition: TheoreticalQuality_test.cpp:43
ripple::amountFromJson
STAmount amountFromJson(SField const &name, Json::Value const &v)
Definition: STAmount.cpp:929
ripple::isXRP
bool isXRP(AccountID const &c)
Definition: AccountID.h:89
ripple::test::jtx::path
Add a path.
Definition: paths.h:55
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::test::jtx::supported_amendments
FeatureBitset supported_amendments()
Definition: Env.h:70
std::uint32_t
ripple::test::RandomAccountParams
Definition: TheoreticalQuality_test.cpp:102
ripple::test::RippleCalcTestParams::srcAccount
AccountID srcAccount
Definition: TheoreticalQuality_test.cpp:39
ripple::test::RippleCalcTestParams::paths
STPathSet paths
Definition: TheoreticalQuality_test.cpp:45
ripple::test::RippleCalcTestParams::dstAccount
AccountID dstAccount
Definition: TheoreticalQuality_test.cpp:40
ripple::one
constexpr Number one
Definition: Number.cpp:169
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::RandomAccountParams::RandomAccountParams
RandomAccountParams(std::uint32_t trustAmount=100, std::uint32_t initialBalance=50)
Definition: TheoreticalQuality_test.cpp:159
ripple::test::jtx::IOU
Converts to IOU Issue or STAmount.
Definition: amount.h:291
ripple::test::jtx::pay
Json::Value pay(Account const &account, Account const &to, AnyAmount amount)
Create a payment.
Definition: pay.cpp:29
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:228
ripple::test::TheoreticalQuality_test::run
void run() override
Definition: TheoreticalQuality_test.cpp:526
ripple::test::TheoreticalQuality_test
Definition: TheoreticalQuality_test.cpp:220
ripple::test::TheoreticalQuality_test::testDirectStep
void testDirectStep(std::optional< int > const &reqNumIterations)
Definition: TheoreticalQuality_test.cpp:315
ripple::test::RippleCalcTestParams::dstAmt
STAmount dstAmt
Definition: TheoreticalQuality_test.cpp:42
ripple::test::RandomAccountParams::probChangeDefault_
constexpr static double probChangeDefault_
Definition: TheoreticalQuality_test.cpp:114
std::optional< STAmount >
ripple::QualityDirection
QualityDirection
Definition: Steps.h:38
std::stringstream::str
T str(T... args)
std::size_t
ripple::test::jtx::Account
Immutable cryptographic account descriptor.
Definition: Account.h:37
beast::detail::xor_shift_engine
Definition: xor_shift_engine.h:32
ripple::featureOwnerPaysFee
const uint256 featureOwnerPaysFee
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:222
ripple::test::TheoreticalQuality_test::testBookStep
void testBookStep(std::optional< int > const &reqNumIterations)
Definition: TheoreticalQuality_test.cpp:407
ripple::test::RandomAccountParams::setupTrustLine
void setupTrustLine(jtx::Env &env, jtx::Account const &acc, jtx::Account const &peer, Currency const &currency)
Definition: TheoreticalQuality_test.cpp:143
ripple::test::jtx::Env::json
Json::Value json(JsonValue &&jv, FN const &... fN)
Create JSON from parameters.
Definition: Env.h:453
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:116
ripple::tfNoRippleDirect
constexpr std::uint32_t tfNoRippleDirect
Definition: TxFlags.h:101
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::test::RandomAccountParams::maybeInsertQuality
void maybeInsertQuality(Json::Value &jv, QualityDirection qDir)
Definition: TheoreticalQuality_test.cpp:128
ripple::test::jtx::rate
Json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
Definition: rate.cpp:30