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>
58 return {k.key, view.
read(k)};
98 static boost::optional<std::int64_t>
116 boost::optional<NetClock::time_point>
const& cancelAfter = boost::none,
117 boost::optional<std::uint32_t>
const& dstTag = boost::none)
121 jv[jss::TransactionType] = jss::PaymentChannelCreate;
123 jv[jss::Account] = account.human();
124 jv[jss::Destination] = to.
human();
126 jv[
"SettleDelay"] = settleDelay.
count();
129 jv[
"CancelAfter"] = cancelAfter->time_since_epoch().count();
131 jv[
"DestinationTag"] = *dstTag;
140 boost::optional<NetClock::time_point>
const&
expiration = boost::none)
144 jv[jss::TransactionType] = jss::PaymentChannelFund;
146 jv[jss::Account] = account.human();
150 jv[
"Expiration"] =
expiration->time_since_epoch().count();
158 boost::optional<STAmount>
const&
balance = boost::none,
159 boost::optional<STAmount>
const& amount = boost::none,
160 boost::optional<Slice>
const& signature = boost::none,
161 boost::optional<PublicKey>
const& pk = boost::none)
165 jv[jss::TransactionType] = jss::PaymentChannelClaim;
167 jv[jss::Account] = account.human();
174 jv[
"Signature"] =
strHex(*signature);
176 jv[
"PublicKey"] =
strHex(pk->slice());
185 using namespace std::literals::chrono_literals;
187 auto const alice =
Account(
"alice");
188 auto const bob =
Account(
"bob");
189 auto USDA = alice[
"USD"];
190 env.
fund(
XRP(10000), alice, bob);
191 auto const pk = alice.pk();
192 auto const settleDelay = 100s;
193 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
199 auto const preAlice = env.
balance(alice);
200 env(
fund(alice, chan,
XRP(1000)));
201 auto const feeDrops = env.
current()->fees().base;
202 BEAST_EXPECT(env.
balance(alice) == preAlice -
XRP(1000) - feeDrops);
207 BEAST_EXPECT(chanBal ==
XRP(0));
208 BEAST_EXPECT(chanAmt ==
XRP(2000));
212 env(
create(alice, bob, USDA(1000), settleDelay, pk),
215 env(
create(alice, bob,
XRP(-1000), settleDelay, pk),
221 env(
create(alice,
"noAccount",
XRP(1000), settleDelay, pk),
224 env(
create(alice, alice,
XRP(1000), settleDelay, pk),
234 auto const iou = USDA(100).value();
235 auto const negXRP =
XRP(-100).value();
236 auto const posXRP =
XRP(100).value();
246 auto const delta =
XRP(500);
247 auto const reqBal = chanBal + delta;
248 auto const authAmt = reqBal +
XRP(-100);
249 assert(reqBal <= chanAmt);
254 auto const preBob = env.
balance(bob);
255 auto const delta =
XRP(500);
256 auto const reqBal = chanBal + delta;
257 auto const authAmt = reqBal +
XRP(100);
258 assert(reqBal <= chanAmt);
259 env(
claim(alice, chan, reqBal, authAmt));
262 BEAST_EXPECT(env.
balance(bob) == preBob + delta);
267 auto preBob = env.
balance(bob);
268 auto const delta =
XRP(500);
269 auto const reqBal = chanBal + delta;
270 auto const authAmt = reqBal +
XRP(100);
271 assert(reqBal <= chanAmt);
274 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
277 auto const feeDrops = env.
current()->fees().base;
278 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
283 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()),
287 BEAST_EXPECT(env.
balance(bob) == preBob - feeDrops);
291 auto const preBob = env.
balance(bob);
294 assert(reqAmt <= chanAmt);
297 env(
claim(bob, chan, reqAmt, authAmt,
Slice(
sig), alice.pk()),
301 BEAST_EXPECT(env.
balance(bob) == preBob);
339 auto const preAlice = env.
balance(alice);
340 auto const preBob = env.
balance(bob);
343 auto const feeDrops = env.
current()->fees().base;
344 auto const delta = chanAmt - chanBal;
345 assert(delta > beast::zero);
346 BEAST_EXPECT(env.
balance(alice) == preAlice + delta);
347 BEAST_EXPECT(env.
balance(bob) == preBob - feeDrops);
354 testcase(
"cancel after");
356 using namespace std::literals::chrono_literals;
357 auto const alice =
Account(
"alice");
358 auto const bob =
Account(
"bob");
359 auto const carol =
Account(
"carol");
363 env.
fund(
XRP(10000), alice, bob);
364 auto const pk = alice.pk();
365 auto const settleDelay = 100s;
367 env.
current()->info().parentCloseTime + 3600s;
368 auto const channelFunds =
XRP(1000);
369 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
377 env.
close(cancelAfter);
382 auto preAlice = env.
balance(alice);
383 auto preBob = env.
balance(bob);
384 auto const delta =
XRP(500);
385 auto const reqBal = chanBal + delta;
386 auto const authAmt = reqBal +
XRP(100);
387 assert(reqBal <= chanAmt);
390 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
391 auto const feeDrops = env.
current()->fees().base;
393 BEAST_EXPECT(env.
balance(bob) == preBob - feeDrops);
394 BEAST_EXPECT(env.
balance(alice) == preAlice + channelFunds);
400 env.
fund(
XRP(10000), alice, bob, carol);
401 auto const pk = alice.pk();
402 auto const settleDelay = 100s;
404 env.
current()->info().parentCloseTime + 3600s;
405 auto const channelFunds =
XRP(1000);
406 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
412 env.
close(cancelAfter);
414 auto const preAlice = env.
balance(alice);
417 BEAST_EXPECT(env.
balance(alice) == preAlice + channelFunds);
424 testcase(
"expiration");
426 using namespace std::literals::chrono_literals;
428 auto const alice =
Account(
"alice");
429 auto const bob =
Account(
"bob");
430 auto const carol =
Account(
"carol");
431 env.
fund(
XRP(10000), alice, bob, carol);
432 auto const pk = alice.pk();
433 auto const settleDelay = 3600s;
434 auto const closeTime = env.
current()->info().parentCloseTime;
435 auto const minExpiration = closeTime + settleDelay;
437 auto const channelFunds =
XRP(1000);
438 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
444 auto counts = [](
auto const& t) {
445 return t.time_since_epoch().count();
454 counts(minExpiration) + 100);
460 counts(minExpiration) + 50);
467 counts(minExpiration) + 50);
471 counts(minExpiration) + 50);
480 env.
close(minExpiration);
490 testcase(
"settle delay");
492 using namespace std::literals::chrono_literals;
494 auto const alice =
Account(
"alice");
495 auto const bob =
Account(
"bob");
496 env.
fund(
XRP(10000), alice, bob);
497 auto const pk = alice.pk();
498 auto const settleDelay = 3600s;
500 env.
current()->info().parentCloseTime + settleDelay;
501 auto const channelFunds =
XRP(1000);
502 env(
create(alice, bob, channelFunds, settleDelay, pk));
508 env.
close(settleTimepoint - settleDelay / 2);
513 auto preBob = env.
balance(bob);
514 auto const delta =
XRP(500);
515 auto const reqBal = chanBal + delta;
516 auto const authAmt = reqBal +
XRP(100);
517 assert(reqBal <= chanAmt);
520 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
523 auto const feeDrops = env.
current()->fees().base;
524 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
526 env.
close(settleTimepoint);
531 auto const preAlice = env.
balance(alice);
532 auto preBob = env.
balance(bob);
533 auto const delta =
XRP(500);
534 auto const reqBal = chanBal + delta;
535 auto const authAmt = reqBal +
XRP(100);
536 assert(reqBal <= chanAmt);
539 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
541 auto const feeDrops = env.
current()->fees().base;
542 BEAST_EXPECT(env.
balance(alice) == preAlice + chanAmt - chanBal);
543 BEAST_EXPECT(env.
balance(bob) == preBob - feeDrops);
550 testcase(
"close dry");
552 using namespace std::literals::chrono_literals;
554 auto const alice =
Account(
"alice");
555 auto const bob =
Account(
"bob");
556 env.
fund(
XRP(10000), alice, bob);
557 auto const pk = alice.pk();
558 auto const settleDelay = 3600s;
559 auto const channelFunds =
XRP(1000);
560 env(
create(alice, bob, channelFunds, settleDelay, pk));
568 auto const preBob = env.
balance(bob);
569 env(
claim(alice, chan, channelFunds.value(), channelFunds.value()));
571 BEAST_EXPECT(env.
balance(bob) == preBob + channelFunds);
573 auto const preAlice = env.
balance(alice);
577 auto const feeDrops = env.
current()->fees().base;
578 BEAST_EXPECT(env.
balance(alice) == preAlice - feeDrops);
585 testcase(
"default amount");
587 using namespace std::literals::chrono_literals;
589 auto const alice =
Account(
"alice");
590 auto const bob =
Account(
"bob");
591 env.
fund(
XRP(10000), alice, bob);
592 auto const pk = alice.pk();
593 auto const settleDelay = 3600s;
594 auto const channelFunds =
XRP(1000);
595 env(
create(alice, bob, channelFunds, settleDelay, pk));
604 auto const preBob = env.
balance(bob);
606 auto const delta =
XRP(500);
607 auto const reqBal = chanBal + delta;
608 assert(reqBal <= chanAmt);
611 env(
claim(bob, chan, reqBal, boost::none,
Slice(
sig), alice.pk()));
613 auto const feeDrops = env.
current()->fees().base;
614 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
621 auto const preBob = env.
balance(bob);
623 auto const delta =
XRP(500);
624 auto const reqBal = chanBal + delta;
625 assert(reqBal <= chanAmt);
628 env(
claim(bob, chan, reqBal, boost::none,
Slice(
sig), alice.pk()));
630 auto const feeDrops = env.
current()->fees().base;
631 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
640 testcase(
"Disallow XRP");
642 using namespace std::literals::chrono_literals;
644 auto const alice =
Account(
"alice");
645 auto const bob =
Account(
"bob");
649 env.
fund(
XRP(10000), alice, bob);
651 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()),
660 env.
fund(
XRP(10000), alice, bob);
662 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
671 env.
fund(
XRP(10000), alice, bob);
672 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
677 auto const reqBal =
XRP(500).value();
685 env.
fund(
XRP(10000), alice, bob);
686 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
691 auto const reqBal =
XRP(500).value();
692 env(
claim(alice, chan, reqBal, reqBal));
702 using namespace std::literals::chrono_literals;
705 auto const alice =
Account(
"alice");
706 auto const bob =
Account(
"bob");
707 env.
fund(
XRP(10000), alice, bob);
709 auto const pk = alice.pk();
710 auto const settleDelay = 3600s;
711 auto const channelFunds =
XRP(1000);
712 env(
create(alice, bob, channelFunds, settleDelay, pk),
716 env(
create(alice, bob, channelFunds, settleDelay, pk, boost::none, 1));
724 testcase(
"Deposit Authorization");
726 using namespace std::literals::chrono_literals;
728 auto const alice =
Account(
"alice");
729 auto const bob =
Account(
"bob");
730 auto const carol =
Account(
"carol");
731 auto USDA = alice[
"USD"];
734 env.
fund(
XRP(10000), alice, bob, carol);
739 auto const pk = alice.pk();
740 auto const settleDelay = 100s;
741 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
750 env(
fund(alice, chan,
XRP(1000)));
754 env(
claim(alice, chan,
XRP(500).value(),
XRP(500).value()),
759 auto const baseFee = env.
current()->fees().base;
760 auto const preBob = env.
balance(bob);
762 auto const delta =
XRP(500).value();
770 BEAST_EXPECT(env.
balance(bob) == preBob);
782 BEAST_EXPECT(env.
balance(bob) == preBob + delta - baseFee);
786 auto const delta =
XRP(600).value();
797 env(deposit::auth(bob, carol));
811 env(deposit::auth(bob, alice));
818 env.
balance(bob) == preBob + delta - (3 * baseFee));
823 auto const delta =
XRP(800).value();
825 env(deposit::unauth(bob, alice));
837 env(
claim(alice, chan, delta, delta));
840 env.
balance(bob) == preBob +
XRP(800) - (5 * baseFee));
849 testcase(
"Multiple channels to the same account");
851 using namespace std::literals::chrono_literals;
853 auto const alice =
Account(
"alice");
854 auto const bob =
Account(
"bob");
855 env.
fund(
XRP(10000), alice, bob);
856 auto const pk = alice.pk();
857 auto const settleDelay = 3600s;
858 auto const channelFunds =
XRP(1000);
859 env(
create(alice, bob, channelFunds, settleDelay, pk));
862 env(
create(alice, bob, channelFunds, settleDelay, pk));
865 BEAST_EXPECT(chan1 != chan2);
871 testcase(
"AccountChannels RPC");
874 using namespace std::literals::chrono_literals;
876 auto const alice =
Account(
"alice");
877 auto const bob =
Account(
"bob");
879 env.
fund(
XRP(10000), alice, bob, charlie);
880 auto const pk = alice.pk();
881 auto const settleDelay = 3600s;
882 auto const channelFunds =
XRP(1000);
883 env(
create(alice, bob, channelFunds, settleDelay, pk));
888 env.
rpc(
"account_channels", alice.human(), bob.human());
889 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
891 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
892 BEAST_EXPECT(r[jss::result][jss::validated]);
895 auto const r = env.
rpc(
"account_channels", alice.human());
896 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
898 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
899 BEAST_EXPECT(r[jss::result][jss::validated]);
903 env.
rpc(
"account_channels", bob.human(), alice.human());
904 BEAST_EXPECT(r[jss::result][jss::channels].size() == 0);
905 BEAST_EXPECT(r[jss::result][jss::validated]);
907 env(
create(alice, bob, channelFunds, settleDelay, pk));
912 env.
rpc(
"account_channels", alice.human(), bob.human());
913 BEAST_EXPECT(r[jss::result][jss::channels].size() == 2);
914 BEAST_EXPECT(r[jss::result][jss::validated]);
915 BEAST_EXPECT(chan1Str != chan2Str);
916 for (
auto const& c : {chan1Str, chan2Str})
918 r[jss::result][jss::channels][0u][jss::channel_id] == c ||
919 r[jss::result][jss::channels][1u][jss::channel_id] == c);
926 testcase(
"Account channels RPC markers");
928 using namespace test::jtx;
929 using namespace std::literals;
931 auto const alice =
Account(
"alice");
936 for (
int i = 0; i < n; ++i)
945 for (
auto const& a : bobs)
953 auto const settleDelay = 3600s;
954 auto const channelFunds =
XRP(1);
955 for (
auto const& b : bobs)
957 env(
create(alice, b, channelFunds, settleDelay, alice.pk()));
963 boost::optional<int> limit = boost::none,
965 boost::optional<test::jtx::Account>
const& dst =
968 jvc[jss::account] = src.human();
970 jvc[jss::destination_account] = dst->human();
972 jvc[jss::limit] = *limit;
974 jvc[jss::marker] = marker;
977 "json",
"account_channels",
to_string(jvc))[jss::result];
982 auto const r = testLimit(env, alice);
983 BEAST_EXPECT(r.isMember(jss::channels));
984 BEAST_EXPECT(r[jss::channels].size() == bobs.size());
989 for (
auto const& a : bobs)
994 for (
int limit = 1; limit < bobs.size() + 1; ++limit)
996 auto leftToFind = bobsB58;
997 auto const numFull = bobs.
size() / limit;
998 auto const numNonFull = bobs.size() % limit ? 1 : 0;
1002 auto const testIt = [&](
bool expectMarker,
int expectedBatchSize) {
1003 auto const r = testLimit(env, alice, limit, marker);
1004 BEAST_EXPECT(!expectMarker || r.isMember(jss::marker));
1005 if (r.isMember(jss::marker))
1006 marker = r[jss::marker];
1007 BEAST_EXPECT(r[jss::channels].size() == expectedBatchSize);
1008 auto const c = r[jss::channels];
1009 auto const s = r[jss::channels].size();
1010 for (
int j = 0; j < s; ++j)
1013 c[j][jss::destination_account].asString();
1014 BEAST_EXPECT(leftToFind.count(dstAcc));
1015 leftToFind.erase(dstAcc);
1019 for (
int i = 0; i < numFull; ++i)
1021 bool const expectMarker = (numNonFull != 0 || i < numFull - 1);
1022 testIt(expectMarker, limit);
1027 testIt(
false, bobs.size() % limit);
1029 BEAST_EXPECT(leftToFind.empty());
1034 auto const r = testLimit(env, alice, 0);
1035 BEAST_EXPECT(r.isMember(jss::marker));
1036 BEAST_EXPECT(r[jss::channels].size() == 0);
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);
1091 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]);
1120 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());
1258 charlie, alice, channelFunds, settleDelay, charlie.pk()));
1267 env.
rpc(
"account_channels", charlie.human(), alice.human());
1268 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1270 r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1271 BEAST_EXPECT(r[jss::result][jss::validated]);
1272 cpk = r[jss::result][jss::channels][0u][jss::public_key]
1278 env.
rpc(
"channel_authorize",
"charlie", chan,
"1000");
1279 auto const sig = rs[jss::result][jss::signature].asString();
1280 BEAST_EXPECT(!
sig.empty());
1283 env.
rpc(
"channel_verify", cpk, chan,
"1000",
sig);
1285 !rv[jss::result][jss::signature_verified].asBool());
1290 env.
rpc(
"channel_authorize",
"charlie",
"nyx", chan,
"1000");
1291 BEAST_EXPECT(rs1[jss::error] ==
"badKeyType");
1295 auto const rs2 = env.
rpc(
1296 "channel_authorize",
"charlie",
"secp256k1", chan,
"1000");
1297 auto const sig2 = rs2[jss::result][jss::signature].
asString();
1298 BEAST_EXPECT(!sig2.empty());
1301 env.
rpc(
"channel_verify", cpk, chan,
"1000", sig2);
1303 !rv[jss::result][jss::signature_verified].asBool());
1307 auto const rs3 = env.
rpc(
1308 "channel_authorize",
"charlie",
"ed25519", chan,
"1000");
1309 auto const sig3 = rs3[jss::result][jss::signature].
asString();
1310 BEAST_EXPECT(!sig3.empty());
1313 env.
rpc(
"channel_verify", cpk, chan,
"1000", sig3);
1314 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1320 auto rs = env.
rpc(
"channel_authorize",
"alice", chan1Str,
"1000x");
1321 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1322 rs = env.
rpc(
"channel_authorize",
"alice", chan1Str,
"x1000");
1323 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1324 rs = env.
rpc(
"channel_authorize",
"alice", chan1Str,
"x");
1325 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1329 args[jss::amount] =
"2000";
1330 args[jss::key_type] =
"secp256k1";
1331 args[jss::passphrase] =
"passphrase_can_be_anything";
1334 "channel_authorize",
1335 args.toStyledString())[jss::result];
1336 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1341 args[jss::channel_id] = chan1Str;
1342 args[jss::key_type] =
"secp256k1";
1343 args[jss::passphrase] =
"passphrase_can_be_anything";
1346 "channel_authorize",
1347 args.toStyledString())[jss::result];
1348 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1353 args[jss::amount] =
"2000";
1354 args[jss::channel_id] = chan1Str;
1355 args[jss::passphrase] =
"passphrase_can_be_anything";
1358 "channel_authorize",
1359 args.toStyledString())[jss::result];
1360 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1365 args[jss::amount] =
"2000";
1366 args[jss::channel_id] = chan1Str;
1367 args[jss::key_type] =
"secp256k1";
1368 args[jss::passphrase] =
"passphrase_can_be_anything";
1369 args[jss::seed] =
"seed can be anything";
1372 "channel_authorize",
1373 args.toStyledString())[jss::result];
1374 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1379 args[jss::amount] =
"2000";
1380 args[jss::channel_id] = chan1Str +
"1";
1381 args[jss::key_type] =
"secp256k1";
1382 args[jss::passphrase] =
"passphrase_can_be_anything";
1385 "channel_authorize",
1386 args.toStyledString())[jss::result];
1387 BEAST_EXPECT(rs[jss::error] ==
"channelMalformed");
1392 args[jss::amount] = 2000;
1393 args[jss::channel_id] = chan1Str;
1394 args[jss::key_type] =
"secp256k1";
1395 args[jss::passphrase] =
"passphrase_can_be_anything";
1398 "channel_authorize",
1399 args.toStyledString())[jss::result];
1400 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1405 args[jss::amount] =
"TwoThousand";
1406 args[jss::channel_id] = chan1Str;
1407 args[jss::key_type] =
"secp256k1";
1408 args[jss::passphrase] =
"passphrase_can_be_anything";
1411 "channel_authorize",
1412 args.toStyledString())[jss::result];
1413 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1421 testcase(
"Optional Fields");
1422 using namespace jtx;
1423 using namespace std::literals::chrono_literals;
1425 auto const alice =
Account(
"alice");
1426 auto const bob =
Account(
"bob");
1427 auto const carol =
Account(
"carol");
1428 auto const dan =
Account(
"dan");
1429 env.
fund(
XRP(10000), alice, bob, carol, dan);
1430 auto const pk = alice.pk();
1431 auto const settleDelay = 3600s;
1432 auto const channelFunds =
XRP(1000);
1434 boost::optional<NetClock::time_point> cancelAfter;
1437 env(
create(alice, bob, channelFunds, settleDelay, pk));
1440 env.
rpc(
"account_channels", alice.human(), bob.human());
1441 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1443 r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1444 BEAST_EXPECT(!r[jss::result][jss::channels][0u].isMember(
1445 jss::destination_tag));
1459 env.
rpc(
"account_channels", alice.human(), carol.human());
1460 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1462 r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1464 r[jss::result][jss::channels][0u][jss::destination_tag] ==
1472 testcase(
"malformed pk");
1473 using namespace jtx;
1474 using namespace std::literals::chrono_literals;
1476 auto const alice =
Account(
"alice");
1477 auto const bob =
Account(
"bob");
1478 auto USDA = alice[
"USD"];
1479 env.
fund(
XRP(10000), alice, bob);
1480 auto const pk = alice.pk();
1481 auto const settleDelay = 100s;
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;
1499 auto const authAmt =
XRP(100);
1508 jv[
"PublicKey"] = pkHex.substr(2, pkHex.size() - 2);
1510 jv[
"PublicKey"] = pkHex.substr(0, pkHex.size() - 2);
1515 jv[
"PublicKey"] = badPrefix;
1519 jv.removeMember(
"PublicKey");
1523 auto const txn = R
"*(
1526 "channel_id":"5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
1528 "304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064",
1530 "aKijDDiC2q2gXjMpM7i4BUS6cmixgsEe18e7CjsUxwihKfuoFgS5",
1534 auto const r = env.
rpc(
"json",
"channel_verify", txn);
1535 BEAST_EXPECT(r[
"result"][
"error"] ==
"publicMalformed");
1542 testcase(
"Metadata & Ownership");
1544 using namespace jtx;
1545 using namespace std::literals::chrono_literals;
1547 auto const alice =
Account(
"alice");
1548 auto const bob =
Account(
"bob");
1549 auto const settleDelay = 100s;
1550 auto const pk = alice.pk();
1552 auto inOwnerDir = [](
ReadView const& view,
1556 return std::find(ownerDir.begin(), ownerDir.end(), chan) !=
1560 auto ownerDirCount = [](
ReadView const& view,
1571 env.
fund(
XRP(10000), alice, bob);
1572 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1574 auto const [chan, chanSle] =
1576 BEAST_EXPECT(inOwnerDir(*env.
current(), alice, chanSle));
1577 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 1);
1578 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1579 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1583 BEAST_EXPECT(!inOwnerDir(*env.
current(), alice, chanSle));
1584 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 0);
1585 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1586 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1592 env.
fund(
XRP(10000), alice, bob);
1593 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1595 auto const [chan, chanSle] =
1597 BEAST_EXPECT(inOwnerDir(*env.
current(), alice, chanSle));
1598 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 1);
1599 BEAST_EXPECT(inOwnerDir(*env.
current(), bob, chanSle));
1600 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 1);
1604 BEAST_EXPECT(!inOwnerDir(*env.
current(), alice, chanSle));
1605 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 0);
1606 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1607 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1615 env.
fund(
XRP(10000), alice, bob);
1617 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1619 auto const [chan, chanSle] =
1621 BEAST_EXPECT(inOwnerDir(*env.
current(), alice, chanSle));
1622 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 1);
1623 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1624 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1633 BEAST_EXPECT(inOwnerDir(*env.
current(), alice, chanSle));
1634 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1635 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1640 BEAST_EXPECT(!inOwnerDir(*env.
current(), alice, chanSle));
1641 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 0);
1642 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1643 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1650 testcase(
"Account Delete");
1651 using namespace test::jtx;
1652 using namespace std::literals::chrono_literals;
1653 auto rmAccount = [
this](
1660 for (
auto minRmSeq = env.
seq(toRm) + 257;
1661 env.
current()->seq() < minRmSeq;
1675 auto const alice =
Account(
"alice");
1676 auto const bob =
Account(
"bob");
1677 auto const carol =
Account(
"carol");
1679 for (
bool const withOwnerDirFix : {
false,
true})
1681 auto const amd = withOwnerDirFix
1684 Env env{*
this, amd};
1685 env.
fund(
XRP(10000), alice, bob, carol);
1687 auto const feeDrops = env.
current()->fees().base;
1690 auto const pk = alice.pk();
1691 auto const settleDelay = 100s;
1692 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1708 BEAST_EXPECT(chanBal ==
XRP(0));
1709 BEAST_EXPECT(chanAmt ==
XRP(1000));
1711 auto preBob = env.
balance(bob);
1712 auto const delta =
XRP(50);
1713 auto reqBal = chanBal + delta;
1714 auto authAmt = reqBal +
XRP(100);
1715 assert(reqBal <= chanAmt);
1718 if (withOwnerDirFix)
1720 env(
claim(alice, chan, reqBal, authAmt));
1724 BEAST_EXPECT(env.
balance(bob) == preBob + delta);
1729 auto const preAlice = env.
balance(alice);
1734 BEAST_EXPECT(env.
balance(bob) == preBob);
1735 BEAST_EXPECT(env.
balance(alice) == preAlice - feeDrops);
1739 if (withOwnerDirFix)
1741 auto const preAlice = env.
balance(alice);
1742 env(
fund(alice, chan,
XRP(1000)));
1745 env.
balance(alice) == preAlice -
XRP(1000) - feeDrops);
1748 chanAmt = chanAmt +
XRP(1000);
1752 auto const preAlice = env.
balance(alice);
1755 BEAST_EXPECT(env.
balance(alice) == preAlice - feeDrops);
1765 auto const closeTime = env.
current()->info().parentCloseTime;
1766 auto const minExpiration = closeTime + settleDelay;
1767 env.
close(minExpiration);
1777 env.
fund(
XRP(10000), alice, bob, carol);
1779 auto const feeDrops = env.
current()->fees().base;
1782 auto const pk = alice.pk();
1783 auto const settleDelay = 100s;
1784 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1791 rmAccount(env, bob, carol);
1796 BEAST_EXPECT(chanBal ==
XRP(0));
1797 BEAST_EXPECT(chanAmt ==
XRP(1000));
1798 auto preBob = env.
balance(bob);
1799 auto const delta =
XRP(50);
1800 auto reqBal = chanBal + delta;
1801 auto authAmt = reqBal +
XRP(100);
1802 assert(reqBal <= chanAmt);
1806 auto const preAlice = env.
balance(alice);
1811 BEAST_EXPECT(env.
balance(bob) == preBob);
1812 BEAST_EXPECT(env.
balance(alice) == preAlice - feeDrops);
1817 auto const preAlice = env.
balance(alice);
1820 BEAST_EXPECT(env.
balance(alice) == preAlice - feeDrops);
1825 env(
pay(alice, bob,
XRP(20)));
1832 reqBal = chanBal + delta;
1833 authAmt = reqBal +
XRP(100);
1834 env(
claim(alice, chan, reqBal, authAmt));
1837 BEAST_EXPECT(env.
balance(bob) == preBob + delta);
1844 reqBal = chanBal + delta;
1845 authAmt = reqBal +
XRP(100);
1848 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
1851 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
1857 auto const preAlice = env.
balance(alice);
1858 env(
fund(alice, chan,
XRP(1000)));
1860 env.
balance(alice) == preAlice -
XRP(1000) - feeDrops);
1863 chanAmt = chanAmt +
XRP(1000);
1872 auto const closeTime = env.
current()->info().parentCloseTime;
1873 auto const minExpiration = closeTime + settleDelay;
1874 env.
close(minExpiration);