18 #include <ripple/app/paths/Flow.h>
19 #include <ripple/app/paths/RippleCalc.h>
20 #include <ripple/app/paths/impl/Steps.h>
21 #include <ripple/basics/contract.h>
22 #include <ripple/basics/safe_cast.h>
23 #include <ripple/core/Config.h>
24 #include <ripple/ledger/ApplyViewImpl.h>
25 #include <ripple/ledger/PaymentSandbox.h>
26 #include <ripple/ledger/Sandbox.h>
27 #include <ripple/protocol/Feature.h>
28 #include <ripple/protocol/jss.h>
30 #include <test/jtx/PathSet.h>
79 auto const useHigh = src.
id() > dst.
id();
80 return sle->isFlag(
trustFlag(flag, useHigh));
82 Throw<std::runtime_error>(
"No line in getTrustFlag");
110 template <
class Iter>
118 template <
class Iter,
class StepInfo,
class... Args>
122 if (!
equal(*i, std::forward<StepInfo>(si)))
127 template <
class... Args>
129 equal(Strand
const& strand, Args&&... args)
131 if (strand.size() !=
sizeof...(Args))
205 static_assert(safe_cast<size_t>(
SB::last) <=
sizeof(decltype(
state_)) * 8,
"");
213 return state_ & (1 << safe_cast<int>(s));
219 for (
auto const s : sb)
230 for (
auto const s : sb)
272 class CurrencyFactory>
278 CurrencyFactory&& currencyF,
279 boost::optional<AccountID>
const& existingAcc,
280 boost::optional<Currency>
const& existingCur,
281 boost::optional<AccountID>
const& existingIss)
285 auto const acc = [&]() -> boost::optional<AccountID> {
294 auto const iss = [&]() -> boost::optional<AccountID> {
305 auto const cur = [&]() -> boost::optional<Currency> {
315 col.emplace_back(acc, cur, iss);
318 STPathElement::Type::typeBoundary,
387 boost::optional<size_t>
const& offererIndex)
391 assert(!offererIndex || offererIndex < numAct);
400 constexpr
size_t bufSize = 32;
403 for (
size_t id = 0;
id < numAct; ++id)
405 snprintf(buf, bufSize,
"A%zu",
id);
409 for (
size_t id = 0;
id < numCur; ++id)
412 snprintf(buf, bufSize,
"CC%zu",
id);
414 snprintf(buf, bufSize,
"C%zu",
id);
416 snprintf(buf, bufSize,
"%zu",
id);
428 for (
auto ai2 =
accounts.begin(); ai2 != aie; ++ai2)
434 env.
trust((*ai1)[cn](1
'000'000), *ai2);
440 auto const& src = *ai1;
441 auto const& dst = *ai2;
442 env(
pay(src, dst, src[cn](500000)));
456 for (
auto takerPays = ious.
begin(), ie = ious.
end(); takerPays != ie;
459 for (
auto takerGets = ious.
begin(); takerGets != ie; ++takerGets)
461 if (takerPays == takerGets)
464 offererIndex ?
accounts[*offererIndex] : takerGets->account;
465 if (owner.id() != takerGets->account.id())
466 env(
pay(takerGets->account, owner, (*takerGets)(1000)));
468 env(
offer(owner, (*takerPays)(1000), (*takerGets)(1000)),
475 for (
auto const& iou : ious)
478 offererIndex ?
accounts[*offererIndex] : iou.account;
489 auto add = [&](
auto const& a) {
512 auto const sle = v.
read(k);
518 auto const sle = v.
read(k);
530 auto const b1 = xrpBalance(v1, ak);
531 auto const b2 = xrpBalance(v2, ak);
537 for (
auto ai2 =
accounts.begin(); ai2 != aie; ++ai2)
545 auto const b1 = lineBalance(v1, lk);
546 auto const b2 = lineBalance(v2, lk);
552 return diffs.
empty();
574 boost::optional<AccountID>
const& existingAcc,
575 boost::optional<Currency>
const& existingCur,
576 boost::optional<AccountID>
const& existingIss,
584 prefix.
empty() ? nullptr : &prefix.
back();
589 auto const resultSize = prefix.
size() + suffix.
size() + 2;
590 outerResult.
reserve(resultSize);
595 outerResult = prefix;
609 result = outerResult;
619 f(sendMax, deliver, result);
630 testcase(
"To Strand");
634 auto const alice =
Account(
"alice");
635 auto const bob =
Account(
"bob");
636 auto const carol =
Account(
"carol");
639 auto const USD = gw[
"USD"];
640 auto const EUR = gw[
"EUR"];
642 auto const eurC = EUR.currency;
643 auto const usdC = USD.currency;
649 auto test = [&,
this](
651 Issue const& deliver,
652 boost::optional<Issue>
const& sendMaxIssue,
655 auto&&... expSteps) {
667 BEAST_EXPECT(
ter == expTer);
668 if (
sizeof...(expSteps) !=0 )
670 strand,
std::forward<decltype(expSteps)>(expSteps)...));
674 Env env(*
this, features);
675 env.
fund(
XRP(10000), alice, bob, gw);
676 env.
trust(USD(1000), alice, bob);
677 env.
trust(EUR(1000), alice, bob);
678 env(
pay(gw, alice, EUR(100)));
719 Env env(*
this, features);
720 env.
fund(
XRP(10000), alice, bob, carol, gw);
724 env.
trust(USD(1000), alice, bob, carol);
727 env(
pay(gw, alice, USD(100)));
728 env(
pay(gw, carol, USD(100)));
739 env.
trust(EUR(1000), alice, bob);
764 env.
trust(carol[
"USD"](1000), bob);
772 B{USD, carol[
"USD"]},
773 D{carol, bob, usdC});
902 Env env(*
this, features);
904 env.
fund(
XRP(10000), alice, bob, carol, gw);
905 env.
trust(USD(10000), alice, bob, carol);
906 env.
trust(EUR(10000), alice, bob, carol);
908 env(
pay(gw, bob, USD(100)));
909 env(
pay(gw, bob, EUR(100)));
911 env(
offer(bob,
XRP(100), USD(100)));
916 env(
pay(alice, carol, USD(100)),
917 path(~USD, ~EUR, ~USD),
924 Env env(*
this, features);
926 env.
trust(USD(1000), alice, bob);
927 env(
pay(gw, alice, USD(100)));
933 Env env(*
this, features);
934 env.
fund(
XRP(10000), alice, bob, gw);
935 env.
trust(USD(1000), alice, bob);
936 env(
pay(gw, alice, USD(100)));
958 Env env(*
this, features);
959 env.
fund(
XRP(10000), alice, bob, gw);
960 env.
trust(USD(1000), alice, bob);
961 env(
pay(gw, alice, USD(100)));
971 Env env(*
this, features);
972 env.
fund(
XRP(10000), alice, bob, gw);
974 env.
trust(USD(1000), alice, bob);
978 env(
pay(gw, alice, USD(100)));
995 BEAST_EXPECT(
equal(strand, D{alice, gw, usdC}));
999 Env env(*
this, features);
1000 env.
fund(
XRP(10000), alice, bob, gw);
1001 env.
trust(USD(1000), alice, bob);
1002 env.
trust(EUR(1000), alice, bob);
1003 env(
pay(gw, alice, EUR(100)));
1014 Env env(*
this, features);
1015 env.
fund(
XRP(10000), alice, bob, gw);
1016 env.
trust(USD(1000), alice, bob);
1017 env(
pay(gw, alice, USD(100)));
1021 path.emplace_back(boost::none, USD.currency, USD.account.id());
1036 BEAST_EXPECT(
equal(strand, D{alice, gw, usdC}, B{USD.issue(),
xrpIssue()}, XRPS{bob}));
1043 using namespace jtx;
1044 testcase(
"RIPD1373");
1046 auto const alice =
Account(
"alice");
1047 auto const bob =
Account(
"bob");
1048 auto const carol =
Account(
"carol");
1049 auto const gw =
Account(
"gw");
1050 auto const USD = gw[
"USD"];
1051 auto const EUR = gw[
"EUR"];
1054 Env env(*
this, features);
1055 env.
fund(
XRP(10000), alice, bob, gw);
1057 env.
trust(USD(1000), alice, bob);
1058 env.
trust(EUR(1000), alice, bob);
1059 env.
trust(bob[
"USD"](1000), alice, gw);
1060 env.
trust(bob[
"EUR"](1000), alice, gw);
1065 env(
offer(bob, bob[
"USD"](100), bob[
"EUR"](100)),
1069 Path const p = [&] {
1078 env(
pay(alice, alice, EUR(1)),
1086 Env env(*
this, features);
1088 env.
fund(
XRP(10000), alice, bob, carol, gw);
1089 env.
trust(USD(10000), alice, bob, carol);
1091 env(
pay(gw, bob, USD(100)));
1097 env(
pay(alice, carol,
XRP(100)),
1104 Env env(*
this, features);
1106 env.
fund(
XRP(10000), alice, bob, carol, gw);
1107 env.
trust(USD(10000), alice, bob, carol);
1109 env(
pay(gw, bob, USD(100)));
1115 env(
pay(alice, carol,
XRP(100)),
1126 testcase(
"test loop");
1127 using namespace jtx;
1129 auto const alice =
Account(
"alice");
1130 auto const bob =
Account(
"bob");
1131 auto const carol =
Account(
"carol");
1132 auto const gw =
Account(
"gw");
1133 auto const USD = gw[
"USD"];
1134 auto const EUR = gw[
"EUR"];
1135 auto const CNY = gw[
"CNY"];
1138 Env env(*
this, features);
1140 env.
fund(
XRP(10000), alice, bob, carol, gw);
1141 env.
trust(USD(10000), alice, bob, carol);
1143 env(
pay(gw, bob, USD(100)));
1144 env(
pay(gw, alice, USD(100)));
1150 env(
pay(alice, carol, USD(100)),
1157 Env env(*
this, features);
1159 env.
fund(
XRP(10000), alice, bob, carol, gw);
1160 env.
trust(USD(10000), alice, bob, carol);
1161 env.
trust(EUR(10000), alice, bob, carol);
1162 env.
trust(CNY(10000), alice, bob, carol);
1164 env(
pay(gw, bob, USD(100)));
1165 env(
pay(gw, bob, EUR(100)));
1166 env(
pay(gw, bob, CNY(100)));
1173 env(
pay(alice, carol, CNY(100)),
1175 path(~USD, ~EUR, ~USD, ~CNY),
1184 testcase(
"test no account");
1185 using namespace jtx;
1187 auto const alice =
Account(
"alice");
1188 auto const bob =
Account(
"bob");
1189 auto const gw =
Account(
"gw");
1190 auto const USD = gw[
"USD"];
1192 Env env(*
this, features);
1193 env.
fund(
XRP(10000), alice, bob, gw);
1208 sb, sendMax, deliver, dstAcc,
noAccount(), pathSet,
1214 sb, sendMax, deliver,
noAccount(), srcAcc, pathSet,
1220 sb, noAccountAmount, deliver, dstAcc, srcAcc, pathSet,
1226 sb, sendMax, noAccountAmount, dstAcc, srcAcc, pathSet,
1240 using namespace jtx;