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>
55 return {k.key, view.
read(k)};
118 jv[jss::TransactionType] = jss::PaymentChannelCreate;
120 jv[jss::Account] = account.human();
121 jv[jss::Destination] = to.
human();
123 jv[
"SettleDelay"] = settleDelay.
count();
126 jv[
"CancelAfter"] = cancelAfter->time_since_epoch().count();
128 jv[
"DestinationTag"] = *dstTag;
141 jv[jss::TransactionType] = jss::PaymentChannelFund;
143 jv[jss::Account] = account.human();
147 jv[
"Expiration"] =
expiration->time_since_epoch().count();
162 jv[jss::TransactionType] = jss::PaymentChannelClaim;
164 jv[jss::Account] = account.human();
171 jv[
"Signature"] =
strHex(*signature);
173 jv[
"PublicKey"] =
strHex(pk->slice());
182 using namespace std::literals::chrono_literals;
184 auto const alice =
Account(
"alice");
185 auto const bob =
Account(
"bob");
186 auto USDA = alice[
"USD"];
187 env.
fund(
XRP(10000), alice, bob);
188 auto const pk = alice.pk();
189 auto const settleDelay = 100s;
190 auto const chan =
channel(alice, bob, env.
seq(alice));
191 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
196 auto const preAlice = env.
balance(alice);
197 env(
fund(alice, chan,
XRP(1000)));
198 auto const feeDrops = env.
current()->fees().base;
199 BEAST_EXPECT(env.
balance(alice) == preAlice -
XRP(1000) - feeDrops);
204 BEAST_EXPECT(chanBal ==
XRP(0));
205 BEAST_EXPECT(chanAmt ==
XRP(2000));
209 env(
create(alice, bob, USDA(1000), settleDelay, pk),
212 env(
create(alice, bob,
XRP(-1000), settleDelay, pk),
218 env(
create(alice,
"noAccount",
XRP(1000), settleDelay, pk),
221 env(
create(alice, alice,
XRP(1000), settleDelay, pk),
227 channel(alice,
"noAccount", env.
seq(alice) - 1),
235 auto const iou = USDA(100).value();
236 auto const negXRP =
XRP(-100).value();
237 auto const posXRP =
XRP(100).value();
247 auto const delta =
XRP(500);
248 auto const reqBal = chanBal + delta;
249 auto const authAmt = reqBal +
XRP(-100);
250 assert(reqBal <= chanAmt);
255 auto const preBob = env.
balance(bob);
256 auto const delta =
XRP(500);
257 auto const reqBal = chanBal + delta;
258 auto const authAmt = reqBal +
XRP(100);
259 assert(reqBal <= chanAmt);
260 env(
claim(alice, chan, reqBal, authAmt));
263 BEAST_EXPECT(env.
balance(bob) == preBob + delta);
268 auto preBob = env.
balance(bob);
269 auto const delta =
XRP(500);
270 auto const reqBal = chanBal + delta;
271 auto const authAmt = reqBal +
XRP(100);
272 assert(reqBal <= chanAmt);
275 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
278 auto const feeDrops = env.
current()->fees().base;
279 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
284 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()),
288 BEAST_EXPECT(env.
balance(bob) == preBob - feeDrops);
292 auto const preBob = env.
balance(bob);
295 assert(reqAmt <= chanAmt);
298 env(
claim(bob, chan, reqAmt, authAmt,
Slice(
sig), alice.pk()),
302 BEAST_EXPECT(env.
balance(bob) == preBob);
340 auto const preAlice = env.
balance(alice);
341 auto const preBob = env.
balance(bob);
344 auto const feeDrops = env.
current()->fees().base;
345 auto const delta = chanAmt - chanBal;
346 assert(delta > beast::zero);
347 BEAST_EXPECT(env.
balance(alice) == preAlice + delta);
348 BEAST_EXPECT(env.
balance(bob) == preBob - feeDrops);
355 testcase(
"cancel after");
357 using namespace std::literals::chrono_literals;
358 auto const alice =
Account(
"alice");
359 auto const bob =
Account(
"bob");
360 auto const carol =
Account(
"carol");
364 env.
fund(
XRP(10000), alice, bob);
365 auto const pk = alice.pk();
366 auto const settleDelay = 100s;
368 env.
current()->info().parentCloseTime + 3600s;
369 auto const channelFunds =
XRP(1000);
370 auto const chan =
channel(alice, bob, env.
seq(alice));
371 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
373 env.
close(cancelAfter);
378 auto preAlice = env.
balance(alice);
379 auto preBob = env.
balance(bob);
380 auto const delta =
XRP(500);
381 auto const reqBal = chanBal + delta;
382 auto const authAmt = reqBal +
XRP(100);
383 assert(reqBal <= chanAmt);
386 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
387 auto const feeDrops = env.
current()->fees().base;
389 BEAST_EXPECT(env.
balance(bob) == preBob - feeDrops);
390 BEAST_EXPECT(env.
balance(alice) == preAlice + channelFunds);
396 env.
fund(
XRP(10000), alice, bob, carol);
397 auto const pk = alice.pk();
398 auto const settleDelay = 100s;
400 env.
current()->info().parentCloseTime + 3600s;
401 auto const channelFunds =
XRP(1000);
402 auto const chan =
channel(alice, bob, env.
seq(alice));
403 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
408 env.
close(cancelAfter);
410 auto const preAlice = env.
balance(alice);
413 BEAST_EXPECT(env.
balance(alice) == preAlice + channelFunds);
420 testcase(
"expiration");
422 using namespace std::literals::chrono_literals;
424 auto const alice =
Account(
"alice");
425 auto const bob =
Account(
"bob");
426 auto const carol =
Account(
"carol");
427 env.
fund(
XRP(10000), alice, bob, carol);
428 auto const pk = alice.pk();
429 auto const settleDelay = 3600s;
430 auto const closeTime = env.
current()->info().parentCloseTime;
431 auto const minExpiration = closeTime + settleDelay;
433 auto const channelFunds =
XRP(1000);
434 auto const chan =
channel(alice, bob, env.
seq(alice));
435 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
440 auto counts = [](
auto const& t) {
441 return t.time_since_epoch().count();
450 counts(minExpiration) + 100);
456 counts(minExpiration) + 50);
463 counts(minExpiration) + 50);
467 counts(minExpiration) + 50);
476 env.
close(minExpiration);
486 testcase(
"settle delay");
488 using namespace std::literals::chrono_literals;
490 auto const alice =
Account(
"alice");
491 auto const bob =
Account(
"bob");
492 env.
fund(
XRP(10000), alice, bob);
493 auto const pk = alice.pk();
494 auto const settleDelay = 3600s;
496 env.
current()->info().parentCloseTime + settleDelay;
497 auto const channelFunds =
XRP(1000);
498 auto const chan =
channel(alice, bob, env.
seq(alice));
499 env(
create(alice, bob, channelFunds, settleDelay, pk));
504 env.
close(settleTimepoint - settleDelay / 2);
509 auto preBob = env.
balance(bob);
510 auto const delta =
XRP(500);
511 auto const reqBal = chanBal + delta;
512 auto const authAmt = reqBal +
XRP(100);
513 assert(reqBal <= chanAmt);
516 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
519 auto const feeDrops = env.
current()->fees().base;
520 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
522 env.
close(settleTimepoint);
527 auto const preAlice = env.
balance(alice);
528 auto preBob = env.
balance(bob);
529 auto const delta =
XRP(500);
530 auto const reqBal = chanBal + delta;
531 auto const authAmt = reqBal +
XRP(100);
532 assert(reqBal <= chanAmt);
535 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
537 auto const feeDrops = env.
current()->fees().base;
538 BEAST_EXPECT(env.
balance(alice) == preAlice + chanAmt - chanBal);
539 BEAST_EXPECT(env.
balance(bob) == preBob - feeDrops);
546 testcase(
"close dry");
548 using namespace std::literals::chrono_literals;
550 auto const alice =
Account(
"alice");
551 auto const bob =
Account(
"bob");
552 env.
fund(
XRP(10000), alice, bob);
553 auto const pk = alice.pk();
554 auto const settleDelay = 3600s;
555 auto const channelFunds =
XRP(1000);
556 auto const chan =
channel(alice, bob, env.
seq(alice));
557 env(
create(alice, bob, channelFunds, settleDelay, pk));
564 auto const preBob = env.
balance(bob);
565 env(
claim(alice, chan, channelFunds.value(), channelFunds.value()));
567 BEAST_EXPECT(env.
balance(bob) == preBob + channelFunds);
569 auto const preAlice = env.
balance(alice);
573 auto const feeDrops = env.
current()->fees().base;
574 BEAST_EXPECT(env.
balance(alice) == preAlice - feeDrops);
581 testcase(
"default amount");
583 using namespace std::literals::chrono_literals;
585 auto const alice =
Account(
"alice");
586 auto const bob =
Account(
"bob");
587 env.
fund(
XRP(10000), alice, bob);
588 auto const pk = alice.pk();
589 auto const settleDelay = 3600s;
590 auto const channelFunds =
XRP(1000);
591 auto const chan =
channel(alice, bob, env.
seq(alice));
592 env(
create(alice, bob, channelFunds, settleDelay, pk));
600 auto const preBob = env.
balance(bob);
602 auto const delta =
XRP(500);
603 auto const reqBal = chanBal + delta;
604 assert(reqBal <= chanAmt);
607 env(
claim(bob, chan, reqBal, std::nullopt,
Slice(
sig), alice.pk()));
609 auto const feeDrops = env.
current()->fees().base;
610 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
617 auto const preBob = env.
balance(bob);
619 auto const delta =
XRP(500);
620 auto const reqBal = chanBal + delta;
621 assert(reqBal <= chanAmt);
624 env(
claim(bob, chan, reqBal, std::nullopt,
Slice(
sig), alice.pk()));
626 auto const feeDrops = env.
current()->fees().base;
627 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
636 testcase(
"Disallow XRP");
638 using namespace std::literals::chrono_literals;
640 auto const alice =
Account(
"alice");
641 auto const bob =
Account(
"bob");
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);
658 auto const chan =
channel(alice, bob, env.
seq(alice));
659 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
667 env.
fund(
XRP(10000), alice, bob);
668 auto const chan =
channel(alice, bob, env.
seq(alice));
669 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
673 auto const reqBal =
XRP(500).value();
681 env.
fund(
XRP(10000), alice, bob);
682 auto const chan =
channel(alice, bob, env.
seq(alice));
683 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
687 auto const reqBal =
XRP(500).value();
688 env(
claim(alice, chan, reqBal, reqBal));
698 using namespace std::literals::chrono_literals;
701 auto const alice =
Account(
"alice");
702 auto const bob =
Account(
"bob");
703 env.
fund(
XRP(10000), alice, bob);
705 auto const pk = alice.pk();
706 auto const settleDelay = 3600s;
707 auto const channelFunds =
XRP(1000);
709 auto const chan =
channel(alice, bob, env.
seq(alice));
710 env(
create(alice, bob, channelFunds, settleDelay, pk),
715 auto const chan =
channel(alice, bob, env.
seq(alice));
717 alice, bob, channelFunds, settleDelay, pk, std::nullopt, 1));
725 testcase(
"Deposit Authorization");
727 using namespace std::literals::chrono_literals;
729 auto const alice =
Account(
"alice");
730 auto const bob =
Account(
"bob");
731 auto const carol =
Account(
"carol");
732 auto USDA = alice[
"USD"];
735 env.
fund(
XRP(10000), alice, bob, carol);
740 auto const pk = alice.pk();
741 auto const settleDelay = 100s;
742 auto const chan =
channel(alice, bob, env.
seq(alice));
743 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
751 env(
fund(alice, chan,
XRP(1000)));
755 env(
claim(alice, chan,
XRP(500).value(),
XRP(500).value()),
760 auto const baseFee = env.
current()->fees().base;
761 auto const preBob = env.
balance(bob);
763 auto const delta =
XRP(500).value();
771 BEAST_EXPECT(env.
balance(bob) == preBob);
783 BEAST_EXPECT(env.
balance(bob) == preBob + delta - baseFee);
787 auto const delta =
XRP(600).value();
798 env(deposit::auth(bob, carol));
812 env(deposit::auth(bob, alice));
819 env.
balance(bob) == preBob + delta - (3 * baseFee));
824 auto const delta =
XRP(800).value();
826 env(deposit::unauth(bob, alice));
838 env(
claim(alice, chan, delta, delta));
841 env.
balance(bob) == preBob +
XRP(800) - (5 * baseFee));
850 testcase(
"Multiple channels to the same account");
852 using namespace std::literals::chrono_literals;
854 auto const alice =
Account(
"alice");
855 auto const bob =
Account(
"bob");
856 env.
fund(
XRP(10000), alice, bob);
857 auto const pk = alice.pk();
858 auto const settleDelay = 3600s;
859 auto const channelFunds =
XRP(1000);
860 auto const chan1 =
channel(alice, bob, env.
seq(alice));
861 env(
create(alice, bob, channelFunds, settleDelay, pk));
863 auto const chan2 =
channel(alice, bob, env.
seq(alice));
864 env(
create(alice, bob, channelFunds, settleDelay, pk));
866 BEAST_EXPECT(chan1 != chan2);
872 testcase(
"AccountChannels RPC");
875 using namespace std::literals::chrono_literals;
877 auto const alice =
Account(
"alice");
878 auto const bob =
Account(
"bob");
880 env.
fund(
XRP(10000), alice, bob, charlie);
881 auto const pk = alice.pk();
882 auto const settleDelay = 3600s;
883 auto const channelFunds =
XRP(1000);
885 env(
create(alice, bob, channelFunds, settleDelay, pk));
889 env.
rpc(
"account_channels", alice.human(), bob.human());
890 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
892 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
893 BEAST_EXPECT(r[jss::result][jss::validated]);
896 auto const r = env.
rpc(
"account_channels", alice.human());
897 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
899 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
900 BEAST_EXPECT(r[jss::result][jss::validated]);
904 env.
rpc(
"account_channels", bob.human(), alice.human());
905 BEAST_EXPECT(r[jss::result][jss::channels].size() == 0);
906 BEAST_EXPECT(r[jss::result][jss::validated]);
909 env(
create(alice, bob, channelFunds, settleDelay, pk));
913 env.
rpc(
"account_channels", alice.human(), bob.human());
914 BEAST_EXPECT(r[jss::result][jss::channels].size() == 2);
915 BEAST_EXPECT(r[jss::result][jss::validated]);
916 BEAST_EXPECT(chan1Str != chan2Str);
917 for (
auto const& c : {chan1Str, chan2Str})
919 r[jss::result][jss::channels][0u][jss::channel_id] == c ||
920 r[jss::result][jss::channels][1u][jss::channel_id] == c);
927 testcase(
"Account channels RPC markers");
929 using namespace test::jtx;
930 using namespace std::literals;
932 auto const alice =
Account(
"alice");
937 for (
int i = 0; i < n; ++i)
946 for (
auto const& a : bobs)
954 auto const settleDelay = 3600s;
955 auto const channelFunds =
XRP(1);
956 for (
auto const& b : bobs)
958 env(
create(alice, b, channelFunds, settleDelay, alice.pk()));
969 jvc[jss::account] = src.human();
971 jvc[jss::destination_account] = dst->human();
973 jvc[jss::limit] = *limit;
975 jvc[jss::marker] = marker;
978 "json",
"account_channels",
to_string(jvc))[jss::result];
983 auto const r = testLimit(env, alice);
984 BEAST_EXPECT(r.isMember(jss::channels));
985 BEAST_EXPECT(r[jss::channels].size() == bobs.size());
990 for (
auto const& a : bobs)
995 for (
int limit = 1; limit < bobs.size() + 1; ++limit)
997 auto leftToFind = bobsB58;
998 auto const numFull = bobs.
size() / limit;
999 auto const numNonFull = bobs.size() % limit ? 1 : 0;
1003 auto const testIt = [&](
bool expectMarker,
int expectedBatchSize) {
1004 auto const r = testLimit(env, alice, limit, marker);
1005 BEAST_EXPECT(!expectMarker || r.isMember(jss::marker));
1006 if (r.isMember(jss::marker))
1007 marker = r[jss::marker];
1008 BEAST_EXPECT(r[jss::channels].size() == expectedBatchSize);
1009 auto const c = r[jss::channels];
1010 auto const s = r[jss::channels].size();
1011 for (
int j = 0; j < s; ++j)
1014 c[j][jss::destination_account].asString();
1015 BEAST_EXPECT(leftToFind.count(dstAcc));
1016 leftToFind.erase(dstAcc);
1020 for (
int i = 0; i < numFull; ++i)
1022 bool const expectMarker = (numNonFull != 0 || i < numFull - 1);
1023 testIt(expectMarker, limit);
1028 testIt(
false, bobs.size() % limit);
1030 BEAST_EXPECT(leftToFind.empty());
1035 auto const r = testLimit(env, alice, 0);
1036 BEAST_EXPECT(r.isMember(jss::error_message));
1045 testcase(
"Account channels RPC owner only");
1047 using namespace test::jtx;
1048 using namespace std::literals;
1050 auto const alice =
Account(
"alice");
1051 auto const bob =
Account(
"bob");
1053 env.
fund(
XRP(10000), alice, bob);
1058 auto const settleDelay = 3600s;
1059 auto const channelFunds =
XRP(1000);
1060 env(
create(alice, bob, channelFunds, settleDelay, alice.pk()));
1061 env(
create(bob, alice, channelFunds, settleDelay, bob.pk()));
1063 auto const r = [&] {
1065 jvc[jss::account] = alice.human();
1068 "json",
"account_channels",
to_string(jvc))[jss::result];
1070 BEAST_EXPECT(r.isMember(jss::channels));
1071 BEAST_EXPECT(r[jss::channels].size() == 1);
1073 r[jss::channels][0u][jss::destination_account].asString() ==
1080 testcase(
"PayChan Auth/Verify RPC");
1081 using namespace jtx;
1082 using namespace std::literals::chrono_literals;
1084 auto const alice =
Account(
"alice");
1085 auto const bob =
Account(
"bob");
1087 env.
fund(
XRP(10000), alice, bob, charlie);
1088 auto const pk = alice.pk();
1089 auto const settleDelay = 3600s;
1090 auto const channelFunds =
XRP(1000);
1092 env(
create(alice, bob, channelFunds, settleDelay, pk));
1097 env.
rpc(
"account_channels", alice.human(), bob.human());
1098 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1100 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1101 BEAST_EXPECT(r[jss::result][jss::validated]);
1103 r[jss::result][jss::channels][0u][jss::public_key].asString();
1106 auto const r = env.
rpc(
"account_channels", alice.human());
1107 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1109 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1110 BEAST_EXPECT(r[jss::result][jss::validated]);
1112 r[jss::result][jss::channels][0u][jss::public_key].asString();
1116 env.
rpc(
"account_channels", bob.human(), alice.human());
1117 BEAST_EXPECT(r[jss::result][jss::channels].size() == 0);
1118 BEAST_EXPECT(r[jss::result][jss::validated]);
1121 env(
create(alice, bob, channelFunds, settleDelay, pk));
1125 env.
rpc(
"account_channels", alice.human(), bob.human());
1126 BEAST_EXPECT(r[jss::result][jss::channels].size() == 2);
1127 BEAST_EXPECT(r[jss::result][jss::validated]);
1128 BEAST_EXPECT(chan1Str != chan2Str);
1129 for (
auto const& c : {chan1Str, chan2Str})
1131 r[jss::result][jss::channels][0u][jss::channel_id] == c ||
1132 r[jss::result][jss::channels][1u][jss::channel_id] == c);
1138 for (
int i = 0; i < slice.size(); ++i)
1140 s +=
"0123456789ABCDEF"[((slice[i] & 0xf0) >> 4)];
1141 s +=
"0123456789ABCDEF"[((slice[i] & 0x0f) >> 0)];
1149 env.
rpc(
"channel_authorize",
"alice", chan1Str,
"1000");
1150 auto const sig = rs[jss::result][jss::signature].asString();
1151 BEAST_EXPECT(!
sig.empty());
1153 auto const rv = env.
rpc(
1154 "channel_verify", chan1PkStr, chan1Str,
"1000",
sig);
1155 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1162 env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"1000",
sig);
1163 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1169 env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"1000x",
sig);
1170 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1171 rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"1000 ",
sig);
1172 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1173 rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"x1000",
sig);
1174 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1175 rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"x",
sig);
1176 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1177 rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
" ",
sig);
1178 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1180 "channel_verify", pkAsHex, chan1Str,
"1000 1000",
sig);
1181 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1182 rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"1,000",
sig);
1183 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1184 rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
" 1000",
sig);
1185 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1186 rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"",
sig);
1187 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1192 auto chan1StrBad = chan1Str;
1193 chan1StrBad.pop_back();
1195 "channel_verify", pkAsHex, chan1StrBad,
"1000",
sig);
1196 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1197 rv = env.
rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1198 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1200 chan1StrBad = chan1Str;
1201 chan1StrBad.push_back(
'0');
1203 "channel_verify", pkAsHex, chan1StrBad,
"1000",
sig);
1204 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1205 rv = env.
rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1206 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1208 chan1StrBad = chan1Str;
1209 chan1StrBad.back() =
'x';
1211 "channel_verify", pkAsHex, chan1StrBad,
"1000",
sig);
1212 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1213 rv = env.
rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1214 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1218 auto illFormedPk = chan1PkStr.
substr(0, chan1PkStr.
size() - 1);
1219 auto const rv = env.
rpc(
1220 "channel_verify", illFormedPk, chan1Str,
"1000",
sig);
1222 !rv[jss::result][jss::signature_verified].asBool());
1227 auto illFormedPk = pkAsHex.substr(0, chan1PkStr.
size() - 1);
1228 auto const rv = env.
rpc(
1229 "channel_verify", illFormedPk, chan1Str,
"1000",
sig);
1231 !rv[jss::result][jss::signature_verified].asBool());
1237 env.
rpc(
"channel_authorize",
"alice", chan2Str,
"1000");
1238 auto const sig = rs[jss::result][jss::signature].asString();
1239 BEAST_EXPECT(!
sig.empty());
1241 auto const rv = env.
rpc(
1242 "channel_verify", chan1PkStr, chan1Str,
"1000",
sig);
1244 !rv[jss::result][jss::signature_verified].asBool());
1250 env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"1000",
sig);
1252 !rv[jss::result][jss::signature_verified].asBool());
1260 charlie, alice, channelFunds, settleDelay, charlie.pk()));
1266 env.
rpc(
"account_channels", charlie.human(), alice.human());
1267 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1269 r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1270 BEAST_EXPECT(r[jss::result][jss::validated]);
1271 cpk = r[jss::result][jss::channels][0u][jss::public_key]
1277 env.
rpc(
"channel_authorize",
"charlie", chan,
"1000");
1278 auto const sig = rs[jss::result][jss::signature].asString();
1279 BEAST_EXPECT(!
sig.empty());
1282 env.
rpc(
"channel_verify", cpk, chan,
"1000",
sig);
1284 !rv[jss::result][jss::signature_verified].asBool());
1289 env.
rpc(
"channel_authorize",
"charlie",
"nyx", chan,
"1000");
1290 BEAST_EXPECT(rs1[jss::error] ==
"badKeyType");
1294 auto const rs2 = env.
rpc(
1295 "channel_authorize",
"charlie",
"secp256k1", chan,
"1000");
1296 auto const sig2 = rs2[jss::result][jss::signature].
asString();
1297 BEAST_EXPECT(!sig2.empty());
1300 env.
rpc(
"channel_verify", cpk, chan,
"1000", sig2);
1302 !rv[jss::result][jss::signature_verified].asBool());
1306 auto const rs3 = env.
rpc(
1307 "channel_authorize",
"charlie",
"ed25519", chan,
"1000");
1308 auto const sig3 = rs3[jss::result][jss::signature].
asString();
1309 BEAST_EXPECT(!sig3.empty());
1312 env.
rpc(
"channel_verify", cpk, chan,
"1000", sig3);
1313 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1319 auto rs = env.
rpc(
"channel_authorize",
"alice", chan1Str,
"1000x");
1320 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1321 rs = env.
rpc(
"channel_authorize",
"alice", chan1Str,
"x1000");
1322 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1323 rs = env.
rpc(
"channel_authorize",
"alice", chan1Str,
"x");
1324 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1328 args[jss::amount] =
"2000";
1329 args[jss::key_type] =
"secp256k1";
1330 args[jss::passphrase] =
"passphrase_can_be_anything";
1333 "channel_authorize",
1334 args.toStyledString())[jss::result];
1335 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1340 args[jss::channel_id] = chan1Str;
1341 args[jss::key_type] =
"secp256k1";
1342 args[jss::passphrase] =
"passphrase_can_be_anything";
1345 "channel_authorize",
1346 args.toStyledString())[jss::result];
1347 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1352 args[jss::amount] =
"2000";
1353 args[jss::channel_id] = chan1Str;
1354 args[jss::passphrase] =
"passphrase_can_be_anything";
1357 "channel_authorize",
1358 args.toStyledString())[jss::result];
1359 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1364 args[jss::amount] =
"2000";
1365 args[jss::channel_id] = chan1Str;
1366 args[jss::key_type] =
"secp256k1";
1367 args[jss::passphrase] =
"passphrase_can_be_anything";
1368 args[jss::seed] =
"seed can be anything";
1371 "channel_authorize",
1372 args.toStyledString())[jss::result];
1373 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1378 args[jss::amount] =
"2000";
1379 args[jss::channel_id] = chan1Str +
"1";
1380 args[jss::key_type] =
"secp256k1";
1381 args[jss::passphrase] =
"passphrase_can_be_anything";
1384 "channel_authorize",
1385 args.toStyledString())[jss::result];
1386 BEAST_EXPECT(rs[jss::error] ==
"channelMalformed");
1391 args[jss::amount] = 2000;
1392 args[jss::channel_id] = chan1Str;
1393 args[jss::key_type] =
"secp256k1";
1394 args[jss::passphrase] =
"passphrase_can_be_anything";
1397 "channel_authorize",
1398 args.toStyledString())[jss::result];
1399 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1404 args[jss::amount] =
"TwoThousand";
1405 args[jss::channel_id] = chan1Str;
1406 args[jss::key_type] =
"secp256k1";
1407 args[jss::passphrase] =
"passphrase_can_be_anything";
1410 "channel_authorize",
1411 args.toStyledString())[jss::result];
1412 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1420 testcase(
"Optional Fields");
1421 using namespace jtx;
1422 using namespace std::literals::chrono_literals;
1424 auto const alice =
Account(
"alice");
1425 auto const bob =
Account(
"bob");
1426 auto const carol =
Account(
"carol");
1427 auto const dan =
Account(
"dan");
1428 env.
fund(
XRP(10000), alice, bob, carol, dan);
1429 auto const pk = alice.pk();
1430 auto const settleDelay = 3600s;
1431 auto const channelFunds =
XRP(1000);
1437 env(
create(alice, bob, channelFunds, settleDelay, pk));
1439 env.
rpc(
"account_channels", alice.human(), bob.human());
1440 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1442 r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1443 BEAST_EXPECT(!r[jss::result][jss::channels][0u].isMember(
1444 jss::destination_tag));
1458 env.
rpc(
"account_channels", alice.human(), carol.human());
1459 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1461 r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1463 r[jss::result][jss::channels][0u][jss::destination_tag] ==
1471 testcase(
"malformed pk");
1472 using namespace jtx;
1473 using namespace std::literals::chrono_literals;
1475 auto const alice =
Account(
"alice");
1476 auto const bob =
Account(
"bob");
1477 auto USDA = alice[
"USD"];
1478 env.
fund(
XRP(10000), alice, bob);
1479 auto const pk = alice.pk();
1480 auto const settleDelay = 100s;
1482 auto const chan =
channel(alice, bob, env.
seq(alice));
1483 auto jv =
create(alice, bob,
XRP(1000), settleDelay, pk);
1484 auto const pkHex =
strHex(pk.slice());
1485 jv[
"PublicKey"] = pkHex.substr(2, pkHex.size() - 2);
1487 jv[
"PublicKey"] = pkHex.substr(0, pkHex.size() - 2);
1489 auto badPrefix = pkHex;
1492 jv[
"PublicKey"] = badPrefix;
1495 jv[
"PublicKey"] = pkHex;
1498 auto const authAmt =
XRP(100);
1507 jv[
"PublicKey"] = pkHex.substr(2, pkHex.size() - 2);
1509 jv[
"PublicKey"] = pkHex.substr(0, pkHex.size() - 2);
1514 jv[
"PublicKey"] = badPrefix;
1518 jv.removeMember(
"PublicKey");
1522 auto const txn = R
"*(
1525 "channel_id":"5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
1527 "304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064",
1529 "aKijDDiC2q2gXjMpM7i4BUS6cmixgsEe18e7CjsUxwihKfuoFgS5",
1533 auto const r = env.
rpc(
"json",
"channel_verify", txn);
1534 BEAST_EXPECT(r[
"result"][
"error"] ==
"publicMalformed");
1541 testcase(
"Metadata & Ownership");
1543 using namespace jtx;
1544 using namespace std::literals::chrono_literals;
1546 auto const alice =
Account(
"alice");
1547 auto const bob =
Account(
"bob");
1548 auto const settleDelay = 100s;
1549 auto const pk = alice.pk();
1551 auto inOwnerDir = [](
ReadView const& view,
1555 return std::find(ownerDir.begin(), ownerDir.end(), chan) !=
1559 auto ownerDirCount = [](
ReadView const& view,
1570 env.
fund(
XRP(10000), alice, bob);
1571 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1573 auto const [chan, chanSle] =
1575 BEAST_EXPECT(inOwnerDir(*env.
current(), alice, chanSle));
1576 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 1);
1577 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1578 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1582 BEAST_EXPECT(!inOwnerDir(*env.
current(), alice, chanSle));
1583 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 0);
1584 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1585 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1591 env.
fund(
XRP(10000), alice, bob);
1592 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1594 auto const [chan, chanSle] =
1596 BEAST_EXPECT(inOwnerDir(*env.
current(), alice, chanSle));
1597 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 1);
1598 BEAST_EXPECT(inOwnerDir(*env.
current(), bob, chanSle));
1599 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 1);
1603 BEAST_EXPECT(!inOwnerDir(*env.
current(), alice, chanSle));
1604 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 0);
1605 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1606 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1614 env.
fund(
XRP(10000), alice, bob);
1616 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1618 auto const [chan, chanSle] =
1620 BEAST_EXPECT(inOwnerDir(*env.
current(), alice, chanSle));
1621 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 1);
1622 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1623 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1632 BEAST_EXPECT(inOwnerDir(*env.
current(), alice, chanSle));
1633 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1634 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1639 BEAST_EXPECT(!inOwnerDir(*env.
current(), alice, chanSle));
1640 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 0);
1641 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1642 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1649 testcase(
"Account Delete");
1650 using namespace test::jtx;
1651 using namespace std::literals::chrono_literals;
1652 auto rmAccount = [
this](
1659 for (
auto minRmSeq = env.
seq(toRm) + 257;
1660 env.
current()->seq() < minRmSeq;
1674 auto const alice =
Account(
"alice");
1675 auto const bob =
Account(
"bob");
1676 auto const carol =
Account(
"carol");
1678 for (
bool const withOwnerDirFix : {
false,
true})
1680 auto const amd = withOwnerDirFix
1683 Env env{*
this, amd};
1684 env.
fund(
XRP(10000), alice, bob, carol);
1686 auto const feeDrops = env.
current()->fees().base;
1689 auto const pk = alice.pk();
1690 auto const settleDelay = 100s;
1691 auto const chan =
channel(alice, bob, env.
seq(alice));
1692 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1707 BEAST_EXPECT(chanBal ==
XRP(0));
1708 BEAST_EXPECT(chanAmt ==
XRP(1000));
1710 auto preBob = env.
balance(bob);
1711 auto const delta =
XRP(50);
1712 auto reqBal = chanBal + delta;
1713 auto authAmt = reqBal +
XRP(100);
1714 assert(reqBal <= chanAmt);
1717 if (withOwnerDirFix)
1719 env(
claim(alice, chan, reqBal, authAmt));
1723 BEAST_EXPECT(env.
balance(bob) == preBob + delta);
1728 auto const preAlice = env.
balance(alice);
1733 BEAST_EXPECT(env.
balance(bob) == preBob);
1734 BEAST_EXPECT(env.
balance(alice) == preAlice - feeDrops);
1738 if (withOwnerDirFix)
1740 auto const preAlice = env.
balance(alice);
1741 env(
fund(alice, chan,
XRP(1000)));
1744 env.
balance(alice) == preAlice -
XRP(1000) - feeDrops);
1747 chanAmt = chanAmt +
XRP(1000);
1751 auto const preAlice = env.
balance(alice);
1754 BEAST_EXPECT(env.
balance(alice) == preAlice - feeDrops);
1764 auto const closeTime = env.
current()->info().parentCloseTime;
1765 auto const minExpiration = closeTime + settleDelay;
1766 env.
close(minExpiration);
1776 env.
fund(
XRP(10000), alice, bob, carol);
1778 auto const feeDrops = env.
current()->fees().base;
1781 auto const pk = alice.pk();
1782 auto const settleDelay = 100s;
1783 auto const chan =
channel(alice, bob, env.
seq(alice));
1784 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1790 rmAccount(env, bob, carol);
1795 BEAST_EXPECT(chanBal ==
XRP(0));
1796 BEAST_EXPECT(chanAmt ==
XRP(1000));
1797 auto preBob = env.
balance(bob);
1798 auto const delta =
XRP(50);
1799 auto reqBal = chanBal + delta;
1800 auto authAmt = reqBal +
XRP(100);
1801 assert(reqBal <= chanAmt);
1805 auto const preAlice = env.
balance(alice);
1810 BEAST_EXPECT(env.
balance(bob) == preBob);
1811 BEAST_EXPECT(env.
balance(alice) == preAlice - feeDrops);
1816 auto const preAlice = env.
balance(alice);
1819 BEAST_EXPECT(env.
balance(alice) == preAlice - feeDrops);
1824 env(
pay(alice, bob,
XRP(20)));
1831 reqBal = chanBal + delta;
1832 authAmt = reqBal +
XRP(100);
1833 env(
claim(alice, chan, reqBal, authAmt));
1836 BEAST_EXPECT(env.
balance(bob) == preBob + delta);
1843 reqBal = chanBal + delta;
1844 authAmt = reqBal +
XRP(100);
1847 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
1850 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
1856 auto const preAlice = env.
balance(alice);
1857 env(
fund(alice, chan,
XRP(1000)));
1859 env.
balance(alice) == preAlice -
XRP(1000) - feeDrops);
1862 chanAmt = chanAmt +
XRP(1000);
1871 auto const closeTime = env.
current()->info().parentCloseTime;
1872 auto const minExpiration = closeTime + settleDelay;
1873 env.
close(minExpiration);
1883 testcase(
"using tickets");
1884 using namespace jtx;
1885 using namespace std::literals::chrono_literals;
1887 auto const alice =
Account(
"alice");
1888 auto const bob =
Account(
"bob");
1889 auto USDA = alice[
"USD"];
1890 env.
fund(
XRP(10000), alice, bob);
1896 env(ticket::create(alice, 10));
1900 env(ticket::create(bob, 10));
1903 auto const pk = alice.pk();
1904 auto const settleDelay = 100s;
1905 auto const chan =
channel(alice, bob, aliceTicketSeq);
1907 env(
create(alice, bob,
XRP(1000), settleDelay, pk),
1911 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
1917 auto const preAlice = env.
balance(alice);
1921 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
1923 auto const feeDrops = env.
current()->fees().base;
1924 BEAST_EXPECT(env.
balance(alice) == preAlice -
XRP(1000) - feeDrops);
1929 BEAST_EXPECT(chanBal ==
XRP(0));
1930 BEAST_EXPECT(chanAmt ==
XRP(2000));
1934 auto const preBob = env.
balance(bob);
1935 auto const delta =
XRP(500);
1936 auto const reqBal = chanBal + delta;
1937 auto const authAmt = reqBal +
XRP(100);
1938 assert(reqBal <= chanAmt);
1939 env(
claim(alice, chan, reqBal, authAmt),
1943 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
1947 BEAST_EXPECT(env.
balance(bob) == preBob + delta);
1952 auto preBob = env.
balance(bob);
1953 auto const delta =
XRP(500);
1954 auto const reqBal = chanBal + delta;
1955 auto const authAmt = reqBal +
XRP(100);
1956 assert(reqBal <= chanAmt);
1959 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()),
1963 BEAST_EXPECT(env.
seq(bob) == bobSeq);
1967 auto const feeDrops = env.
current()->fees().base;
1968 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
1974 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()),
1979 BEAST_EXPECT(env.
seq(bob) == bobSeq);
1983 BEAST_EXPECT(env.
balance(bob) == preBob - feeDrops);
1987 auto const preBob = env.
balance(bob);
1990 assert(reqAmt <= chanAmt);
1995 env(
claim(bob, chan, reqAmt, authAmt,
Slice(
sig), alice.pk()),
2000 BEAST_EXPECT(env.
seq(bob) == bobSeq);
2004 BEAST_EXPECT(env.
balance(bob) == preBob);
2008 env(
fund(bob, chan,
XRP(1000)),
2013 BEAST_EXPECT(env.
seq(bob) == bobSeq);
2020 auto const preAlice = env.
balance(alice);
2021 auto const preBob = env.
balance(bob);
2022 env(
claim(bob, chan),
2027 BEAST_EXPECT(env.
seq(bob) == bobSeq);
2030 auto const feeDrops = env.
current()->fees().base;
2031 auto const delta = chanAmt - chanBal;
2032 assert(delta > beast::zero);
2033 BEAST_EXPECT(env.
balance(alice) == preAlice + delta);
2034 BEAST_EXPECT(env.
balance(bob) == preBob - feeDrops);
2037 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
2039 BEAST_EXPECT(env.
seq(bob) == bobSeq);