20 #include <ripple/basics/chrono.h>
21 #include <ripple/ledger/Directory.h>
22 #include <ripple/protocol/Feature.h>
23 #include <ripple/protocol/Indexes.h>
24 #include <ripple/protocol/PayChan.h>
25 #include <ripple/protocol/TxFlags.h>
26 #include <ripple/protocol/jss.h>
27 #include <ripple/rpc/impl/RPCHelpers.h>
47 return {k.key, view.
read(k)};
87 using namespace std::literals::chrono_literals;
88 Env env{*
this, features};
89 auto const alice =
Account(
"alice");
90 auto const bob =
Account(
"bob");
91 auto USDA = alice[
"USD"];
92 env.fund(
XRP(10000), alice, bob);
93 auto const pk = alice.pk();
94 auto const settleDelay = 100s;
95 auto const chan =
channel(alice, bob, env.seq(alice));
96 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
101 auto const preAlice = env.balance(alice);
102 env(
fund(alice, chan,
XRP(1000)));
103 auto const feeDrops = env.current()->fees().base;
104 BEAST_EXPECT(env.balance(alice) == preAlice -
XRP(1000) - feeDrops);
109 BEAST_EXPECT(chanBal ==
XRP(0));
110 BEAST_EXPECT(chanAmt ==
XRP(2000));
114 env(
create(alice, bob, USDA(1000), settleDelay, pk),
117 env(
create(alice, bob,
XRP(-1000), settleDelay, pk),
123 env(
create(alice,
"noAccount",
XRP(1000), settleDelay, pk),
126 env(
create(alice, alice,
XRP(1000), settleDelay, pk),
132 channel(alice,
"noAccount", env.seq(alice) - 1),
140 auto const iou = USDA(100).value();
141 auto const negXRP =
XRP(-100).value();
142 auto const posXRP =
XRP(100).value();
152 auto const delta =
XRP(500);
153 auto const reqBal = chanBal + delta;
154 auto const authAmt = reqBal +
XRP(-100);
155 assert(reqBal <= chanAmt);
160 auto const preBob = env.balance(bob);
161 auto const delta =
XRP(500);
162 auto const reqBal = chanBal + delta;
163 auto const authAmt = reqBal +
XRP(100);
164 assert(reqBal <= chanAmt);
165 env(
claim(alice, chan, reqBal, authAmt));
167 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
168 BEAST_EXPECT(env.balance(bob) == preBob + delta);
173 auto preBob = env.balance(bob);
174 auto const delta =
XRP(500);
175 auto const reqBal = chanBal + delta;
176 auto const authAmt = reqBal +
XRP(100);
177 assert(reqBal <= chanAmt);
180 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
182 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
183 auto const feeDrops = env.current()->fees().base;
184 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
188 preBob = env.balance(bob);
189 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()),
192 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
193 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
197 auto const preBob = env.balance(bob);
200 assert(reqAmt <= chanAmt);
203 env(
claim(bob, chan, reqAmt, authAmt,
Slice(
sig), alice.pk()),
206 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
207 BEAST_EXPECT(env.balance(bob) == preBob);
213 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
227 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
241 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
245 auto const preAlice = env.balance(alice);
246 auto const preBob = env.balance(bob);
249 auto const feeDrops = env.current()->fees().base;
250 auto const delta = chanAmt - chanBal;
251 assert(delta > beast::zero);
252 BEAST_EXPECT(env.balance(alice) == preAlice + delta);
253 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
260 testcase(
"Disallow Incoming Flag");
267 env.fund(
XRP(10000), alice);
270 auto const sle = env.le(alice);
271 uint32_t
flags = sle->getFlags();
275 using namespace std::literals::chrono_literals;
277 auto const alice =
Account(
"alice");
278 auto const bob =
Account(
"bob");
279 auto const cho =
Account(
"cho");
280 env.fund(
XRP(10000), alice, bob, cho);
281 auto const pk = alice.pk();
282 auto const settleDelay = 100s;
290 auto const chan =
channel(alice, bob, env.seq(alice));
291 env(
create(alice, bob,
XRP(1000), settleDelay, pk),
302 auto const chan =
channel(bob, alice, env.seq(bob));
303 env(
create(bob, alice,
XRP(1000), settleDelay, pk),
314 auto const chan =
channel(alice, bob, env.seq(alice));
315 env(
create(alice, bob,
XRP(1000), settleDelay, pk),
322 auto const chan =
channel(cho, alice, env.seq(cho));
323 env(
create(cho, alice,
XRP(1000), settleDelay, pk),
334 auto const chan =
channel(cho, alice, env.seq(cho));
335 env(
create(cho, alice,
XRP(1000), settleDelay, pk),
344 testcase(
"cancel after");
346 using namespace std::literals::chrono_literals;
347 auto const alice =
Account(
"alice");
348 auto const bob =
Account(
"bob");
349 auto const carol =
Account(
"carol");
352 Env env{*
this, features};
353 env.fund(
XRP(10000), alice, bob);
354 auto const pk = alice.pk();
355 auto const settleDelay = 100s;
357 env.current()->info().parentCloseTime + 3600s;
358 auto const channelFunds =
XRP(1000);
359 auto const chan =
channel(alice, bob, env.seq(alice));
360 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
362 env.close(cancelAfter);
367 auto preAlice = env.balance(alice);
368 auto preBob = env.balance(bob);
369 auto const delta =
XRP(500);
370 auto const reqBal = chanBal + delta;
371 auto const authAmt = reqBal +
XRP(100);
372 assert(reqBal <= chanAmt);
375 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
376 auto const feeDrops = env.current()->fees().base;
378 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
379 BEAST_EXPECT(env.balance(alice) == preAlice + channelFunds);
384 Env env{*
this, features};
385 env.fund(
XRP(10000), alice, bob, carol);
386 auto const pk = alice.pk();
387 auto const settleDelay = 100s;
389 env.current()->info().parentCloseTime + 3600s;
390 auto const channelFunds =
XRP(1000);
391 auto const chan =
channel(alice, bob, env.seq(alice));
392 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
397 env.close(cancelAfter);
399 auto const preAlice = env.balance(alice);
402 BEAST_EXPECT(env.balance(alice) == preAlice + channelFunds);
409 testcase(
"expiration");
411 using namespace std::literals::chrono_literals;
412 Env env{*
this, features};
413 auto const alice =
Account(
"alice");
414 auto const bob =
Account(
"bob");
415 auto const carol =
Account(
"carol");
416 env.fund(
XRP(10000), alice, bob, carol);
417 auto const pk = alice.pk();
418 auto const settleDelay = 3600s;
419 auto const closeTime = env.current()->info().parentCloseTime;
420 auto const minExpiration = closeTime + settleDelay;
422 auto const channelFunds =
XRP(1000);
423 auto const chan =
channel(alice, bob, env.seq(alice));
424 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
429 auto counts = [](
auto const& t) {
430 return t.time_since_epoch().count();
439 counts(minExpiration) + 100);
445 counts(minExpiration) + 50);
452 counts(minExpiration) + 50);
456 counts(minExpiration) + 50);
465 env.close(minExpiration);
475 testcase(
"settle delay");
477 using namespace std::literals::chrono_literals;
478 Env env{*
this, features};
479 auto const alice =
Account(
"alice");
480 auto const bob =
Account(
"bob");
481 env.fund(
XRP(10000), alice, bob);
482 auto const pk = alice.pk();
483 auto const settleDelay = 3600s;
485 env.current()->info().parentCloseTime + settleDelay;
486 auto const channelFunds =
XRP(1000);
487 auto const chan =
channel(alice, bob, env.seq(alice));
488 env(
create(alice, bob, channelFunds, settleDelay, pk));
493 env.close(settleTimepoint - settleDelay / 2);
498 auto preBob = env.balance(bob);
499 auto const delta =
XRP(500);
500 auto const reqBal = chanBal + delta;
501 auto const authAmt = reqBal +
XRP(100);
502 assert(reqBal <= chanAmt);
505 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
507 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
508 auto const feeDrops = env.current()->fees().base;
509 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
511 env.close(settleTimepoint);
516 auto const preAlice = env.balance(alice);
517 auto preBob = env.balance(bob);
518 auto const delta =
XRP(500);
519 auto const reqBal = chanBal + delta;
520 auto const authAmt = reqBal +
XRP(100);
521 assert(reqBal <= chanAmt);
524 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
526 auto const feeDrops = env.current()->fees().base;
527 BEAST_EXPECT(env.balance(alice) == preAlice + chanAmt - chanBal);
528 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
535 testcase(
"close dry");
537 using namespace std::literals::chrono_literals;
538 Env env{*
this, features};
539 auto const alice =
Account(
"alice");
540 auto const bob =
Account(
"bob");
541 env.fund(
XRP(10000), alice, bob);
542 auto const pk = alice.pk();
543 auto const settleDelay = 3600s;
544 auto const channelFunds =
XRP(1000);
545 auto const chan =
channel(alice, bob, env.seq(alice));
546 env(
create(alice, bob, channelFunds, settleDelay, pk));
553 auto const preBob = env.balance(bob);
554 env(
claim(alice, chan, channelFunds.value(), channelFunds.value()));
555 BEAST_EXPECT(
channelBalance(*env.current(), chan) == channelFunds);
556 BEAST_EXPECT(env.balance(bob) == preBob + channelFunds);
558 auto const preAlice = env.balance(alice);
562 auto const feeDrops = env.current()->fees().base;
563 BEAST_EXPECT(env.balance(alice) == preAlice - feeDrops);
570 testcase(
"default amount");
572 using namespace std::literals::chrono_literals;
573 Env env{*
this, features};
574 auto const alice =
Account(
"alice");
575 auto const bob =
Account(
"bob");
576 env.fund(
XRP(10000), alice, bob);
577 auto const pk = alice.pk();
578 auto const settleDelay = 3600s;
579 auto const channelFunds =
XRP(1000);
580 auto const chan =
channel(alice, bob, env.seq(alice));
581 env(
create(alice, bob, channelFunds, settleDelay, pk));
589 auto const preBob = env.balance(bob);
591 auto const delta =
XRP(500);
592 auto const reqBal = chanBal + delta;
593 assert(reqBal <= chanAmt);
596 env(
claim(bob, chan, reqBal, std::nullopt,
Slice(
sig), alice.pk()));
598 auto const feeDrops = env.current()->fees().base;
599 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
606 auto const preBob = env.balance(bob);
608 auto const delta =
XRP(500);
609 auto const reqBal = chanBal + delta;
610 assert(reqBal <= chanAmt);
613 env(
claim(bob, chan, reqBal, std::nullopt,
Slice(
sig), alice.pk()));
615 auto const feeDrops = env.current()->fees().base;
616 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
625 testcase(
"Disallow XRP");
627 using namespace std::literals::chrono_literals;
629 auto const alice =
Account(
"alice");
630 auto const bob =
Account(
"bob");
634 env.
fund(
XRP(10000), alice, bob);
636 auto const chan =
channel(alice, bob, env.
seq(alice));
637 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()),
644 Env env{*
this, features};
645 env.fund(
XRP(10000), alice, bob);
647 auto const chan =
channel(alice, bob, env.seq(alice));
648 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
656 env.
fund(
XRP(10000), alice, bob);
657 auto const chan =
channel(alice, bob, env.
seq(alice));
658 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
662 auto const reqBal =
XRP(500).value();
669 Env env{*
this, features};
670 env.fund(
XRP(10000), alice, bob);
671 auto const chan =
channel(alice, bob, env.seq(alice));
672 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
676 auto const reqBal =
XRP(500).value();
677 env(
claim(alice, chan, reqBal, reqBal));
687 using namespace std::literals::chrono_literals;
689 Env env{*
this, features};
690 auto const alice =
Account(
"alice");
691 auto const bob =
Account(
"bob");
692 env.fund(
XRP(10000), alice, bob);
694 auto const pk = alice.pk();
695 auto const settleDelay = 3600s;
696 auto const channelFunds =
XRP(1000);
698 auto const chan =
channel(alice, bob, env.seq(alice));
699 env(
create(alice, bob, channelFunds, settleDelay, pk),
704 auto const chan =
channel(alice, bob, env.seq(alice));
706 alice, bob, channelFunds, settleDelay, pk, std::nullopt, 1));
714 testcase(
"Deposit Authorization");
716 using namespace std::literals::chrono_literals;
718 auto const alice =
Account(
"alice");
719 auto const bob =
Account(
"bob");
720 auto const carol =
Account(
"carol");
721 auto USDA = alice[
"USD"];
723 Env env{*
this, features};
724 env.fund(
XRP(10000), alice, bob, carol);
729 auto const pk = alice.pk();
730 auto const settleDelay = 100s;
731 auto const chan =
channel(alice, bob, env.seq(alice));
732 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
740 env(
fund(alice, chan,
XRP(1000)));
744 env(
claim(alice, chan,
XRP(500).value(),
XRP(500).value()),
749 auto const baseFee = env.current()->fees().base;
750 auto const preBob = env.balance(bob);
752 auto const delta =
XRP(500).value();
760 BEAST_EXPECT(env.balance(bob) == preBob);
772 BEAST_EXPECT(env.balance(bob) == preBob + delta - baseFee);
776 auto const delta =
XRP(600).value();
787 env(deposit::auth(bob, carol));
801 env(deposit::auth(bob, alice));
808 env.balance(bob) == preBob + delta - (3 * baseFee));
813 auto const delta =
XRP(800).value();
815 env(deposit::unauth(bob, alice));
827 env(
claim(alice, chan, delta, delta));
830 env.balance(bob) == preBob +
XRP(800) - (5 * baseFee));
839 testcase(
"Multiple channels to the same account");
841 using namespace std::literals::chrono_literals;
842 Env env{*
this, features};
843 auto const alice =
Account(
"alice");
844 auto const bob =
Account(
"bob");
845 env.fund(
XRP(10000), alice, bob);
846 auto const pk = alice.pk();
847 auto const settleDelay = 3600s;
848 auto const channelFunds =
XRP(1000);
849 auto const chan1 =
channel(alice, bob, env.seq(alice));
850 env(
create(alice, bob, channelFunds, settleDelay, pk));
852 auto const chan2 =
channel(alice, bob, env.seq(alice));
853 env(
create(alice, bob, channelFunds, settleDelay, pk));
855 BEAST_EXPECT(chan1 != chan2);
861 testcase(
"AccountChannels RPC");
864 using namespace std::literals::chrono_literals;
865 Env env{*
this, features};
866 auto const alice =
Account(
"alice");
867 auto const bob =
Account(
"bob");
869 env.fund(
XRP(10000), alice, bob, charlie);
870 auto const pk = alice.pk();
871 auto const settleDelay = 3600s;
872 auto const channelFunds =
XRP(1000);
874 env(
create(alice, bob, channelFunds, settleDelay, pk));
878 env.rpc(
"account_channels", alice.human(), bob.human());
879 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
881 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
882 BEAST_EXPECT(r[jss::result][jss::validated]);
885 auto const r = env.rpc(
"account_channels", alice.human());
886 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
888 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
889 BEAST_EXPECT(r[jss::result][jss::validated]);
893 env.rpc(
"account_channels", bob.human(), alice.human());
894 BEAST_EXPECT(r[jss::result][jss::channels].size() == 0);
895 BEAST_EXPECT(r[jss::result][jss::validated]);
898 env(
create(alice, bob, channelFunds, settleDelay, pk));
902 env.rpc(
"account_channels", alice.human(), bob.human());
903 BEAST_EXPECT(r[jss::result][jss::channels].size() == 2);
904 BEAST_EXPECT(r[jss::result][jss::validated]);
905 BEAST_EXPECT(chan1Str != chan2Str);
906 for (
auto const& c : {chan1Str, chan2Str})
908 r[jss::result][jss::channels][0u][jss::channel_id] == c ||
909 r[jss::result][jss::channels][1u][jss::channel_id] == c);
916 testcase(
"Account channels RPC markers");
918 using namespace test::jtx;
919 using namespace std::literals;
921 auto const alice =
Account(
"alice");
926 for (
int i = 0; i < n; ++i)
933 Env env{*
this, features};
934 env.fund(
XRP(10000), alice);
935 for (
auto const& a : bobs)
937 env.fund(
XRP(10000), a);
943 auto const settleDelay = 3600s;
944 auto const channelFunds =
XRP(1);
945 for (
auto const& b : bobs)
947 env(
create(alice, b, channelFunds, settleDelay, alice.pk()));
958 jvc[jss::account] = src.human();
960 jvc[jss::destination_account] = dst->human();
962 jvc[jss::limit] = *limit;
964 jvc[jss::marker] = marker;
967 "json",
"account_channels",
to_string(jvc))[jss::result];
972 auto const r = testLimit(env, alice);
973 BEAST_EXPECT(r.isMember(jss::channels));
974 BEAST_EXPECT(r[jss::channels].size() == bobs.size());
979 for (
auto const& a : bobs)
984 for (
int limit = 1; limit < bobs.size() + 1; ++limit)
986 auto leftToFind = bobsB58;
987 auto const numFull = bobs.
size() / limit;
988 auto const numNonFull = bobs.size() % limit ? 1 : 0;
992 auto const testIt = [&](
bool expectMarker,
int expectedBatchSize) {
993 auto const r = testLimit(env, alice, limit, marker);
994 BEAST_EXPECT(!expectMarker || r.isMember(jss::marker));
995 if (r.isMember(jss::marker))
996 marker = r[jss::marker];
997 BEAST_EXPECT(r[jss::channels].size() == expectedBatchSize);
998 auto const c = r[jss::channels];
999 auto const s = r[jss::channels].size();
1000 for (
int j = 0; j < s; ++j)
1003 c[j][jss::destination_account].asString();
1004 BEAST_EXPECT(leftToFind.count(dstAcc));
1005 leftToFind.erase(dstAcc);
1009 for (
int i = 0; i < numFull; ++i)
1011 bool const expectMarker = (numNonFull != 0 || i < numFull - 1);
1012 testIt(expectMarker, limit);
1017 testIt(
false, bobs.size() % limit);
1019 BEAST_EXPECT(leftToFind.empty());
1024 auto const r = testLimit(env, alice, 0);
1025 BEAST_EXPECT(r.isMember(jss::error_message));
1034 testcase(
"Account channels RPC owner only");
1036 using namespace test::jtx;
1037 using namespace std::literals;
1039 auto const alice =
Account(
"alice");
1040 auto const bob =
Account(
"bob");
1041 Env env{*
this, features};
1042 env.fund(
XRP(10000), alice, bob);
1047 auto const settleDelay = 3600s;
1048 auto const channelFunds =
XRP(1000);
1049 env(
create(alice, bob, channelFunds, settleDelay, alice.pk()));
1050 env(
create(bob, alice, channelFunds, settleDelay, bob.pk()));
1052 auto const r = [&] {
1054 jvc[jss::account] = alice.human();
1057 "json",
"account_channels",
to_string(jvc))[jss::result];
1059 BEAST_EXPECT(r.isMember(jss::channels));
1060 BEAST_EXPECT(r[jss::channels].size() == 1);
1062 r[jss::channels][0u][jss::destination_account].asString() ==
1069 using namespace jtx;
1070 using namespace std::literals::chrono_literals;
1072 Env env{*
this, features};
1073 auto const alice =
Account(
"alice");
1074 auto const bob =
Account(
"bob");
1076 env.fund(
XRP(10000), alice, bob, charlie);
1077 auto const pk = alice.pk();
1078 auto const settleDelay = 3600s;
1079 auto const channelFunds =
XRP(1000);
1081 env(
create(alice, bob, channelFunds, settleDelay, pk));
1085 args[jss::channel_id] = chan1Str;
1086 args[jss::key_type] =
"ed255191";
1087 args[jss::seed] =
"snHq1rzQoN2qiUkC3XF5RyxBzUtN";
1088 args[jss::amount] = 51110000;
1097 args[jss::api_version] = apiVersion;
1098 auto const rs = env.rpc(
1100 "channel_authorize",
1101 args.toStyledString())[jss::result];
1102 auto const error = apiVersion < 2u ?
"invalidParams" :
"badKeyType";
1103 BEAST_EXPECT(rs[jss::error] == error);
1110 testcase(
"PayChan Auth/Verify RPC");
1111 using namespace jtx;
1112 using namespace std::literals::chrono_literals;
1113 Env env{*
this, features};
1114 auto const alice =
Account(
"alice");
1115 auto const bob =
Account(
"bob");
1117 env.fund(
XRP(10000), alice, bob, charlie);
1118 auto const pk = alice.pk();
1119 auto const settleDelay = 3600s;
1120 auto const channelFunds =
XRP(1000);
1122 env(
create(alice, bob, channelFunds, settleDelay, pk));
1127 env.rpc(
"account_channels", alice.human(), bob.human());
1128 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1130 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1131 BEAST_EXPECT(r[jss::result][jss::validated]);
1133 r[jss::result][jss::channels][0u][jss::public_key].asString();
1136 auto const r = env.rpc(
"account_channels", alice.human());
1137 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1139 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1140 BEAST_EXPECT(r[jss::result][jss::validated]);
1142 r[jss::result][jss::channels][0u][jss::public_key].asString();
1146 env.rpc(
"account_channels", bob.human(), alice.human());
1147 BEAST_EXPECT(r[jss::result][jss::channels].size() == 0);
1148 BEAST_EXPECT(r[jss::result][jss::validated]);
1151 env(
create(alice, bob, channelFunds, settleDelay, pk));
1155 env.rpc(
"account_channels", alice.human(), bob.human());
1156 BEAST_EXPECT(r[jss::result][jss::channels].size() == 2);
1157 BEAST_EXPECT(r[jss::result][jss::validated]);
1158 BEAST_EXPECT(chan1Str != chan2Str);
1159 for (
auto const& c : {chan1Str, chan2Str})
1161 r[jss::result][jss::channels][0u][jss::channel_id] == c ||
1162 r[jss::result][jss::channels][1u][jss::channel_id] == c);
1168 for (
int i = 0; i < slice.size(); ++i)
1170 s +=
"0123456789ABCDEF"[((slice[i] & 0xf0) >> 4)];
1171 s +=
"0123456789ABCDEF"[((slice[i] & 0x0f) >> 0)];
1179 env.rpc(
"channel_authorize",
"alice", chan1Str,
"1000");
1180 auto const sig = rs[jss::result][jss::signature].asString();
1181 BEAST_EXPECT(!
sig.empty());
1183 auto const rv = env.rpc(
1184 "channel_verify", chan1PkStr, chan1Str,
"1000",
sig);
1185 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1192 env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000",
sig);
1193 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1199 env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000x",
sig);
1200 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1201 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000 ",
sig);
1202 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1203 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"x1000",
sig);
1204 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1205 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"x",
sig);
1206 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1207 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
" ",
sig);
1208 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1210 "channel_verify", pkAsHex, chan1Str,
"1000 1000",
sig);
1211 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1212 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1,000",
sig);
1213 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1214 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
" 1000",
sig);
1215 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1216 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"",
sig);
1217 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1222 auto chan1StrBad = chan1Str;
1223 chan1StrBad.pop_back();
1225 "channel_verify", pkAsHex, chan1StrBad,
"1000",
sig);
1226 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1227 rv = env.rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1228 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1230 chan1StrBad = chan1Str;
1231 chan1StrBad.push_back(
'0');
1233 "channel_verify", pkAsHex, chan1StrBad,
"1000",
sig);
1234 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1235 rv = env.rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1236 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1238 chan1StrBad = chan1Str;
1239 chan1StrBad.back() =
'x';
1241 "channel_verify", pkAsHex, chan1StrBad,
"1000",
sig);
1242 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1243 rv = env.rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1244 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1248 auto illFormedPk = chan1PkStr.
substr(0, chan1PkStr.
size() - 1);
1249 auto const rv = env.rpc(
1250 "channel_verify", illFormedPk, chan1Str,
"1000",
sig);
1252 !rv[jss::result][jss::signature_verified].asBool());
1257 auto illFormedPk = pkAsHex.substr(0, chan1PkStr.
size() - 1);
1258 auto const rv = env.rpc(
1259 "channel_verify", illFormedPk, chan1Str,
"1000",
sig);
1261 !rv[jss::result][jss::signature_verified].asBool());
1267 env.rpc(
"channel_authorize",
"alice", chan2Str,
"1000");
1268 auto const sig = rs[jss::result][jss::signature].asString();
1269 BEAST_EXPECT(!
sig.empty());
1271 auto const rv = env.rpc(
1272 "channel_verify", chan1PkStr, chan1Str,
"1000",
sig);
1274 !rv[jss::result][jss::signature_verified].asBool());
1280 env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000",
sig);
1282 !rv[jss::result][jss::signature_verified].asBool());
1290 charlie, alice, channelFunds, settleDelay, charlie.pk()));
1296 env.rpc(
"account_channels", charlie.human(), alice.human());
1297 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1299 r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1300 BEAST_EXPECT(r[jss::result][jss::validated]);
1301 cpk = r[jss::result][jss::channels][0u][jss::public_key]
1307 env.rpc(
"channel_authorize",
"charlie", chan,
"1000");
1308 auto const sig = rs[jss::result][jss::signature].asString();
1309 BEAST_EXPECT(!
sig.empty());
1312 env.rpc(
"channel_verify", cpk, chan,
"1000",
sig);
1314 !rv[jss::result][jss::signature_verified].asBool());
1319 env.rpc(
"channel_authorize",
"charlie",
"nyx", chan,
"1000");
1320 BEAST_EXPECT(rs1[jss::error] ==
"badKeyType");
1324 auto const rs2 = env.rpc(
1325 "channel_authorize",
"charlie",
"secp256k1", chan,
"1000");
1326 auto const sig2 = rs2[jss::result][jss::signature].asString();
1327 BEAST_EXPECT(!sig2.empty());
1330 env.rpc(
"channel_verify", cpk, chan,
"1000", sig2);
1332 !rv[jss::result][jss::signature_verified].asBool());
1336 auto const rs3 = env.rpc(
1337 "channel_authorize",
"charlie",
"ed25519", chan,
"1000");
1338 auto const sig3 = rs3[jss::result][jss::signature].asString();
1339 BEAST_EXPECT(!sig3.empty());
1342 env.rpc(
"channel_verify", cpk, chan,
"1000", sig3);
1343 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1349 auto rs = env.rpc(
"channel_authorize",
"alice", chan1Str,
"1000x");
1350 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1351 rs = env.rpc(
"channel_authorize",
"alice", chan1Str,
"x1000");
1352 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1353 rs = env.rpc(
"channel_authorize",
"alice", chan1Str,
"x");
1354 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1358 args[jss::amount] =
"2000";
1359 args[jss::key_type] =
"secp256k1";
1360 args[jss::passphrase] =
"passphrase_can_be_anything";
1363 "channel_authorize",
1364 args.toStyledString())[jss::result];
1365 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1370 args[jss::channel_id] = chan1Str;
1371 args[jss::key_type] =
"secp256k1";
1372 args[jss::passphrase] =
"passphrase_can_be_anything";
1375 "channel_authorize",
1376 args.toStyledString())[jss::result];
1377 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1382 args[jss::amount] =
"2000";
1383 args[jss::channel_id] = chan1Str;
1384 args[jss::passphrase] =
"passphrase_can_be_anything";
1387 "channel_authorize",
1388 args.toStyledString())[jss::result];
1389 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1394 args[jss::amount] =
"2000";
1395 args[jss::channel_id] = chan1Str;
1396 args[jss::key_type] =
"secp256k1";
1397 args[jss::passphrase] =
"passphrase_can_be_anything";
1398 args[jss::seed] =
"seed can be anything";
1401 "channel_authorize",
1402 args.toStyledString())[jss::result];
1403 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1408 args[jss::amount] =
"2000";
1409 args[jss::channel_id] = chan1Str +
"1";
1410 args[jss::key_type] =
"secp256k1";
1411 args[jss::passphrase] =
"passphrase_can_be_anything";
1414 "channel_authorize",
1415 args.toStyledString())[jss::result];
1416 BEAST_EXPECT(rs[jss::error] ==
"channelMalformed");
1421 args[jss::amount] = 2000;
1422 args[jss::channel_id] = chan1Str;
1423 args[jss::key_type] =
"secp256k1";
1424 args[jss::passphrase] =
"passphrase_can_be_anything";
1427 "channel_authorize",
1428 args.toStyledString())[jss::result];
1429 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1434 args[jss::amount] =
"TwoThousand";
1435 args[jss::channel_id] = chan1Str;
1436 args[jss::key_type] =
"secp256k1";
1437 args[jss::passphrase] =
"passphrase_can_be_anything";
1440 "channel_authorize",
1441 args.toStyledString())[jss::result];
1442 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1450 testcase(
"Optional Fields");
1451 using namespace jtx;
1452 using namespace std::literals::chrono_literals;
1453 Env env{*
this, features};
1454 auto const alice =
Account(
"alice");
1455 auto const bob =
Account(
"bob");
1456 auto const carol =
Account(
"carol");
1457 auto const dan =
Account(
"dan");
1458 env.fund(
XRP(10000), alice, bob, carol, dan);
1459 auto const pk = alice.pk();
1460 auto const settleDelay = 3600s;
1461 auto const channelFunds =
XRP(1000);
1467 env(
create(alice, bob, channelFunds, settleDelay, pk));
1469 env.rpc(
"account_channels", alice.human(), bob.human());
1470 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1472 r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1473 BEAST_EXPECT(!r[jss::result][jss::channels][0u].isMember(
1474 jss::destination_tag));
1488 env.rpc(
"account_channels", alice.human(), carol.human());
1489 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1491 r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1493 r[jss::result][jss::channels][0u][jss::destination_tag] ==
1501 testcase(
"malformed pk");
1502 using namespace jtx;
1503 using namespace std::literals::chrono_literals;
1504 Env env{*
this, features};
1505 auto const alice =
Account(
"alice");
1506 auto const bob =
Account(
"bob");
1507 auto USDA = alice[
"USD"];
1508 env.fund(
XRP(10000), alice, bob);
1509 auto const pk = alice.pk();
1510 auto const settleDelay = 100s;
1512 auto const chan =
channel(alice, bob, env.seq(alice));
1513 auto jv =
create(alice, bob,
XRP(1000), settleDelay, pk);
1514 auto const pkHex =
strHex(pk.slice());
1515 jv[
"PublicKey"] = pkHex.substr(2, pkHex.size() - 2);
1517 jv[
"PublicKey"] = pkHex.substr(0, pkHex.size() - 2);
1519 auto badPrefix = pkHex;
1522 jv[
"PublicKey"] = badPrefix;
1525 jv[
"PublicKey"] = pkHex;
1528 auto const authAmt =
XRP(100);
1537 jv[
"PublicKey"] = pkHex.substr(2, pkHex.size() - 2);
1539 jv[
"PublicKey"] = pkHex.substr(0, pkHex.size() - 2);
1544 jv[
"PublicKey"] = badPrefix;
1548 jv.removeMember(
"PublicKey");
1552 auto const txn = R
"*(
1555 "channel_id":"5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
1557 "304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064",
1559 "aKijDDiC2q2gXjMpM7i4BUS6cmixgsEe18e7CjsUxwihKfuoFgS5",
1563 auto const r = env.rpc(
"json",
"channel_verify", txn);
1564 BEAST_EXPECT(r[
"result"][
"error"] ==
"publicMalformed");
1571 testcase(
"Metadata & Ownership");
1573 using namespace jtx;
1574 using namespace std::literals::chrono_literals;
1576 auto const alice =
Account(
"alice");
1577 auto const bob =
Account(
"bob");
1578 auto const settleDelay = 100s;
1579 auto const pk = alice.pk();
1581 auto inOwnerDir = [](
ReadView const& view,
1585 return std::find(ownerDir.begin(), ownerDir.end(), chan) !=
1589 auto ownerDirCount = [](
ReadView const& view,
1599 env.
fund(
XRP(10000), alice, bob);
1600 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1602 auto const [chan, chanSle] =
1604 BEAST_EXPECT(inOwnerDir(*env.
current(), alice, chanSle));
1605 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 1);
1606 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1607 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1611 BEAST_EXPECT(!inOwnerDir(*env.
current(), alice, chanSle));
1612 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 0);
1613 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1614 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1619 Env env{*
this, features};
1620 env.fund(
XRP(10000), alice, bob);
1621 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1623 auto const [chan, chanSle] =
1625 BEAST_EXPECT(inOwnerDir(*env.current(), alice, chanSle));
1626 BEAST_EXPECT(ownerDirCount(*env.current(), alice) == 1);
1627 BEAST_EXPECT(inOwnerDir(*env.current(), bob, chanSle));
1628 BEAST_EXPECT(ownerDirCount(*env.current(), bob) == 1);
1632 BEAST_EXPECT(!inOwnerDir(*env.current(), alice, chanSle));
1633 BEAST_EXPECT(ownerDirCount(*env.current(), alice) == 0);
1634 BEAST_EXPECT(!inOwnerDir(*env.current(), bob, chanSle));
1635 BEAST_EXPECT(ownerDirCount(*env.current(), bob) == 0);
1642 env.
fund(
XRP(10000), alice, bob);
1644 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1646 auto const [chan, chanSle] =
1648 BEAST_EXPECT(inOwnerDir(*env.
current(), alice, chanSle));
1649 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 1);
1650 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1651 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1660 BEAST_EXPECT(inOwnerDir(*env.
current(), alice, chanSle));
1661 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1662 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1667 BEAST_EXPECT(!inOwnerDir(*env.
current(), alice, chanSle));
1668 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 0);
1669 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1670 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1677 testcase(
"Account Delete");
1678 using namespace test::jtx;
1679 using namespace std::literals::chrono_literals;
1680 auto rmAccount = [
this](
1687 for (
auto minRmSeq = env.
seq(toRm) + 257;
1688 env.
current()->seq() < minRmSeq;
1702 auto const alice =
Account(
"alice");
1703 auto const bob =
Account(
"bob");
1704 auto const carol =
Account(
"carol");
1706 for (
bool const withOwnerDirFix : {
false,
true})
1708 auto const amd = withOwnerDirFix
1711 Env env{*
this, amd};
1712 env.
fund(
XRP(10000), alice, bob, carol);
1714 auto const feeDrops = env.
current()->fees().base;
1717 auto const pk = alice.pk();
1718 auto const settleDelay = 100s;
1719 auto const chan =
channel(alice, bob, env.
seq(alice));
1720 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1735 BEAST_EXPECT(chanBal ==
XRP(0));
1736 BEAST_EXPECT(chanAmt ==
XRP(1000));
1738 auto preBob = env.
balance(bob);
1739 auto const delta =
XRP(50);
1740 auto reqBal = chanBal + delta;
1741 auto authAmt = reqBal +
XRP(100);
1742 assert(reqBal <= chanAmt);
1745 if (withOwnerDirFix)
1747 env(
claim(alice, chan, reqBal, authAmt));
1751 BEAST_EXPECT(env.
balance(bob) == preBob + delta);
1756 auto const preAlice = env.
balance(alice);
1761 BEAST_EXPECT(env.
balance(bob) == preBob);
1762 BEAST_EXPECT(env.
balance(alice) == preAlice - feeDrops);
1766 if (withOwnerDirFix)
1768 auto const preAlice = env.
balance(alice);
1769 env(
fund(alice, chan,
XRP(1000)));
1772 env.
balance(alice) == preAlice -
XRP(1000) - feeDrops);
1775 chanAmt = chanAmt +
XRP(1000);
1779 auto const preAlice = env.
balance(alice);
1782 BEAST_EXPECT(env.
balance(alice) == preAlice - feeDrops);
1792 auto const closeTime = env.
current()->info().parentCloseTime;
1793 auto const minExpiration = closeTime + settleDelay;
1794 env.
close(minExpiration);
1803 env.
fund(
XRP(10000), alice, bob, carol);
1805 auto const feeDrops = env.
current()->fees().base;
1808 auto const pk = alice.pk();
1809 auto const settleDelay = 100s;
1810 auto const chan =
channel(alice, bob, env.
seq(alice));
1811 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1817 rmAccount(env, bob, carol);
1822 BEAST_EXPECT(chanBal ==
XRP(0));
1823 BEAST_EXPECT(chanAmt ==
XRP(1000));
1824 auto preBob = env.
balance(bob);
1825 auto const delta =
XRP(50);
1826 auto reqBal = chanBal + delta;
1827 auto authAmt = reqBal +
XRP(100);
1828 assert(reqBal <= chanAmt);
1832 auto const preAlice = env.
balance(alice);
1837 BEAST_EXPECT(env.
balance(bob) == preBob);
1838 BEAST_EXPECT(env.
balance(alice) == preAlice - feeDrops);
1843 auto const preAlice = env.
balance(alice);
1846 BEAST_EXPECT(env.
balance(alice) == preAlice - feeDrops);
1851 env(pay(alice, bob,
XRP(20)));
1858 reqBal = chanBal + delta;
1859 authAmt = reqBal +
XRP(100);
1860 env(
claim(alice, chan, reqBal, authAmt));
1863 BEAST_EXPECT(env.
balance(bob) == preBob + delta);
1870 reqBal = chanBal + delta;
1871 authAmt = reqBal +
XRP(100);
1874 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
1877 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
1883 auto const preAlice = env.
balance(alice);
1884 env(
fund(alice, chan,
XRP(1000)));
1886 env.
balance(alice) == preAlice -
XRP(1000) - feeDrops);
1889 chanAmt = chanAmt +
XRP(1000);
1898 auto const closeTime = env.
current()->info().parentCloseTime;
1899 auto const minExpiration = closeTime + settleDelay;
1900 env.
close(minExpiration);
1910 testcase(
"using tickets");
1911 using namespace jtx;
1912 using namespace std::literals::chrono_literals;
1913 Env env{*
this, features};
1914 auto const alice =
Account(
"alice");
1915 auto const bob =
Account(
"bob");
1916 auto USDA = alice[
"USD"];
1917 env.fund(
XRP(10000), alice, bob);
1923 env(ticket::create(alice, 10));
1927 env(ticket::create(bob, 10));
1930 auto const pk = alice.pk();
1931 auto const settleDelay = 100s;
1932 auto const chan =
channel(alice, bob, aliceTicketSeq);
1934 env(
create(alice, bob,
XRP(1000), settleDelay, pk),
1937 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1938 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1944 auto const preAlice = env.balance(alice);
1947 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1948 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1950 auto const feeDrops = env.current()->fees().base;
1951 BEAST_EXPECT(env.balance(alice) == preAlice -
XRP(1000) - feeDrops);
1956 BEAST_EXPECT(chanBal ==
XRP(0));
1957 BEAST_EXPECT(chanAmt ==
XRP(2000));
1961 auto const preBob = env.balance(bob);
1962 auto const delta =
XRP(500);
1963 auto const reqBal = chanBal + delta;
1964 auto const authAmt = reqBal +
XRP(100);
1965 assert(reqBal <= chanAmt);
1966 env(
claim(alice, chan, reqBal, authAmt),
1969 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1970 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1973 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
1974 BEAST_EXPECT(env.balance(bob) == preBob + delta);
1979 auto preBob = env.balance(bob);
1980 auto const delta =
XRP(500);
1981 auto const reqBal = chanBal + delta;
1982 auto const authAmt = reqBal +
XRP(100);
1983 assert(reqBal <= chanAmt);
1986 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()),
1989 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
1990 BEAST_EXPECT(env.seq(bob) == bobSeq);
1993 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
1994 auto const feeDrops = env.current()->fees().base;
1995 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
1999 preBob = env.balance(bob);
2001 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()),
2005 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2006 BEAST_EXPECT(env.seq(bob) == bobSeq);
2009 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
2010 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
2014 auto const preBob = env.balance(bob);
2017 assert(reqAmt <= chanAmt);
2022 env(
claim(bob, chan, reqAmt, authAmt,
Slice(
sig), alice.pk()),
2026 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2027 BEAST_EXPECT(env.seq(bob) == bobSeq);
2030 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
2031 BEAST_EXPECT(env.balance(bob) == preBob);
2035 env(
fund(bob, chan,
XRP(1000)),
2039 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2040 BEAST_EXPECT(env.seq(bob) == bobSeq);
2043 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
2047 auto const preAlice = env.balance(alice);
2048 auto const preBob = env.balance(bob);
2049 env(
claim(bob, chan),
2053 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2054 BEAST_EXPECT(env.seq(bob) == bobSeq);
2057 auto const feeDrops = env.current()->fees().base;
2058 auto const delta = chanAmt - chanBal;
2059 assert(delta > beast::zero);
2060 BEAST_EXPECT(env.balance(alice) == preAlice + delta);
2061 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
2063 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
2064 BEAST_EXPECT(env.seq(alice) == aliceSeq);
2065 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2066 BEAST_EXPECT(env.seq(bob) == bobSeq);
2099 using namespace test::jtx;