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>
80 auto const useHigh = src.
id() > dst.
id();
81 return sle->isFlag(
trustFlag(flag, useHigh));
83 Throw<std::runtime_error>(
"No line in getTrustFlag");
111 template <
class Iter>
119 template <
class Iter,
class StepInfo,
class... Args>
123 if (!
equal(*i, std::forward<StepInfo>(si)))
128 template <
class... Args>
130 equal(Strand
const& strand, Args&&... args)
132 if (strand.size() !=
sizeof...(Args))
218 return state_ & (1 << safe_cast<int>(s));
224 for (
auto const s : sb)
235 for (
auto const s : sb)
282 class CurrencyFactory>
288 CurrencyFactory&& currencyF,
289 boost::optional<AccountID>
const& existingAcc,
290 boost::optional<Currency>
const& existingCur,
291 boost::optional<AccountID>
const& existingIss)
295 auto const acc = [&]() -> boost::optional<AccountID> {
304 auto const iss = [&]() -> boost::optional<AccountID> {
315 auto const cur = [&]() -> boost::optional<Currency> {
325 col.emplace_back(acc, cur, iss);
328 STPathElement::Type::typeBoundary,
398 boost::optional<size_t>
const& offererIndex)
402 assert(!offererIndex || offererIndex < numAct);
411 constexpr
size_t bufSize = 32;
414 for (
size_t id = 0;
id < numAct; ++id)
416 snprintf(buf, bufSize,
"A%zu",
id);
420 for (
size_t id = 0;
id < numCur; ++id)
423 snprintf(buf, bufSize,
"CC%zu",
id);
425 snprintf(buf, bufSize,
"C%zu",
id);
427 snprintf(buf, bufSize,
"%zu",
id);
439 for (
auto ai2 =
accounts.begin(); ai2 != aie; ++ai2)
445 env.
trust((*ai1)[cn](1
'000'000), *ai2);
451 auto const& src = *ai1;
452 auto const& dst = *ai2;
453 env(
pay(src, dst, src[cn](500000)));
467 for (
auto takerPays = ious.
begin(), ie = ious.
end(); takerPays != ie;
470 for (
auto takerGets = ious.
begin(); takerGets != ie; ++takerGets)
472 if (takerPays == takerGets)
475 offererIndex ?
accounts[*offererIndex] : takerGets->account;
476 if (owner.id() != takerGets->account.id())
477 env(
pay(takerGets->account, owner, (*takerGets)(1000)));
479 env(offer(owner, (*takerPays)(1000), (*takerGets)(1000)),
486 for (
auto const& iou : ious)
489 offererIndex ?
accounts[*offererIndex] : iou.account;
500 auto add = [&](
auto const& a) {
523 auto const sle = v.
read(k);
529 auto const sle = v.
read(k);
541 auto const b1 = xrpBalance(v1, ak);
542 auto const b2 = xrpBalance(v2, ak);
548 for (
auto ai2 =
accounts.begin(); ai2 != aie; ++ai2)
556 auto const b1 = lineBalance(v1, lk);
557 auto const b2 = lineBalance(v2, lk);
563 return diffs.
empty();
585 boost::optional<AccountID>
const& existingAcc,
586 boost::optional<Currency>
const& existingCur,
587 boost::optional<AccountID>
const& existingIss,
595 prefix.
empty() ? nullptr : &prefix.
back();
600 auto const resultSize = prefix.
size() + suffix.
size() + 2;
601 outerResult.
reserve(resultSize);
606 outerResult = prefix;
620 result = outerResult;
630 f(sendMax, deliver, result);
641 testcase(
"To Strand");
645 auto const alice =
Account(
"alice");
646 auto const bob =
Account(
"bob");
647 auto const carol =
Account(
"carol");
650 auto const USD = gw[
"USD"];
651 auto const EUR = gw[
"EUR"];
653 auto const eurC = EUR.currency;
654 auto const usdC = USD.currency;
660 auto test = [&,
this](
662 Issue const& deliver,
663 boost::optional<Issue>
const& sendMaxIssue,
666 auto&&... expSteps) {
678 BEAST_EXPECT(
ter == expTer);
679 if (
sizeof...(expSteps) != 0)
681 strand,
std::forward<decltype(expSteps)>(expSteps)...));
685 Env env(*
this, features);
686 env.
fund(
XRP(10000), alice, bob, gw);
687 env.
trust(USD(1000), alice, bob);
688 env.
trust(EUR(1000), alice, bob);
689 env(
pay(gw, alice, EUR(100)));
730 Env env(*
this, features);
731 env.
fund(
XRP(10000), alice, bob, carol, gw);
735 env.
trust(USD(1000), alice, bob, carol);
738 env(
pay(gw, alice, USD(100)));
739 env(
pay(gw, carol, USD(100)));
750 env.
trust(EUR(1000), alice, bob);
775 env.
trust(carol[
"USD"](1000), bob);
783 B{USD, carol[
"USD"]},
784 D{carol, bob, usdC});
913 Env env(*
this, features);
915 env.
fund(
XRP(10000), alice, bob, carol, gw);
916 env.
trust(USD(10000), alice, bob, carol);
917 env.
trust(EUR(10000), alice, bob, carol);
919 env(
pay(gw, bob, USD(100)));
920 env(
pay(gw, bob, EUR(100)));
922 env(offer(bob,
XRP(100), USD(100)));
927 env(
pay(alice, carol, USD(100)),
928 path(~USD, ~EUR, ~USD),
935 Env env(*
this, features);
937 env.
trust(USD(1000), alice, bob);
938 env(
pay(gw, alice, USD(100)));
944 Env env(*
this, features);
945 env.
fund(
XRP(10000), alice, bob, gw);
946 env.
trust(USD(1000), alice, bob);
947 env(
pay(gw, alice, USD(100)));
969 Env env(*
this, features);
970 env.
fund(
XRP(10000), alice, bob, gw);
971 env.
trust(USD(1000), alice, bob);
972 env(
pay(gw, alice, USD(100)));
982 Env env(*
this, features);
983 env.
fund(
XRP(10000), alice, bob, gw);
985 env.
trust(USD(1000), alice, bob);
989 env(
pay(gw, alice, USD(100)));
1006 BEAST_EXPECT(
equal(strand, D{alice, gw, usdC}));
1010 Env env(*
this, features);
1011 env.
fund(
XRP(10000), alice, bob, gw);
1012 env.
trust(USD(1000), alice, bob);
1013 env.
trust(EUR(1000), alice, bob);
1014 env(
pay(gw, alice, EUR(100)));
1025 Env env(*
this, features);
1026 env.
fund(
XRP(10000), alice, bob, gw);
1027 env.
trust(USD(1000), alice, bob);
1028 env(
pay(gw, alice, USD(100)));
1032 path.emplace_back(boost::none, USD.currency, USD.account.id());
1058 using namespace jtx;
1059 testcase(
"RIPD1373");
1061 auto const alice =
Account(
"alice");
1062 auto const bob =
Account(
"bob");
1063 auto const carol =
Account(
"carol");
1064 auto const gw =
Account(
"gw");
1065 auto const USD = gw[
"USD"];
1066 auto const EUR = gw[
"EUR"];
1069 Env env(*
this, features);
1070 env.
fund(
XRP(10000), alice, bob, gw);
1072 env.
trust(USD(1000), alice, bob);
1073 env.
trust(EUR(1000), alice, bob);
1074 env.
trust(bob[
"USD"](1000), alice, gw);
1075 env.
trust(bob[
"EUR"](1000), alice, gw);
1080 env(offer(bob, bob[
"USD"](100), bob[
"EUR"](100)),
1084 Path const p = [&] {
1093 env(
pay(alice, alice, EUR(1)),
1101 Env env(*
this, features);
1103 env.
fund(
XRP(10000), alice, bob, carol, gw);
1104 env.
trust(USD(10000), alice, bob, carol);
1106 env(
pay(gw, bob, USD(100)));
1112 env(
pay(alice, carol,
XRP(100)),
1119 Env env(*
this, features);
1121 env.
fund(
XRP(10000), alice, bob, carol, gw);
1122 env.
trust(USD(10000), alice, bob, carol);
1124 env(
pay(gw, bob, USD(100)));
1130 env(
pay(alice, carol,
XRP(100)),
1141 testcase(
"test loop");
1142 using namespace jtx;
1144 auto const alice =
Account(
"alice");
1145 auto const bob =
Account(
"bob");
1146 auto const carol =
Account(
"carol");
1147 auto const gw =
Account(
"gw");
1148 auto const USD = gw[
"USD"];
1149 auto const EUR = gw[
"EUR"];
1150 auto const CNY = gw[
"CNY"];
1153 Env env(*
this, features);
1155 env.
fund(
XRP(10000), alice, bob, carol, gw);
1156 env.
trust(USD(10000), alice, bob, carol);
1158 env(
pay(gw, bob, USD(100)));
1159 env(
pay(gw, alice, USD(100)));
1165 env(
pay(alice, carol, USD(100)),
1172 Env env(*
this, features);
1174 env.
fund(
XRP(10000), alice, bob, carol, gw);
1175 env.
trust(USD(10000), alice, bob, carol);
1176 env.
trust(EUR(10000), alice, bob, carol);
1177 env.
trust(CNY(10000), alice, bob, carol);
1179 env(
pay(gw, bob, USD(100)));
1180 env(
pay(gw, bob, EUR(100)));
1181 env(
pay(gw, bob, CNY(100)));
1188 env(
pay(alice, carol, CNY(100)),
1190 path(~USD, ~EUR, ~USD, ~CNY),
1199 testcase(
"test no account");
1200 using namespace jtx;
1202 auto const alice =
Account(
"alice");
1203 auto const bob =
Account(
"bob");
1204 auto const gw =
Account(
"gw");
1205 auto const USD = gw[
"USD"];
1207 Env env(*
this, features);
1208 env.
fund(
XRP(10000), alice, bob, gw);
1279 using namespace jtx;