3#include <xrpl/basics/chrono.h>
4#include <xrpl/ledger/Dir.h>
5#include <xrpl/protocol/Feature.h>
6#include <xrpl/protocol/Indexes.h>
7#include <xrpl/protocol/PayChan.h>
8#include <xrpl/protocol/TxFlags.h>
9#include <xrpl/protocol/jss.h>
13using namespace jtx::paychan;
24 return {k.key, view.
read(k)};
38 auto const slep = view.
read({ltPAYCHAN, chan});
41 return (*slep)[sfAmount];
47 auto const slep = view.
read({ltPAYCHAN, chan});
50 if (
auto const r = (*slep)[~sfExpiration])
61 Env env{*
this, features};
62 auto const alice =
Account(
"alice");
63 auto const bob =
Account(
"bob");
64 auto USDA = alice[
"USD"];
65 env.fund(
XRP(10000), alice, bob);
66 auto const pk = alice.pk();
67 auto const settleDelay = 100s;
68 auto const chan =
channel(alice, bob, env.seq(alice));
69 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
74 auto const preAlice = env.balance(alice);
75 env(
fund(alice, chan,
XRP(1000)));
76 auto const feeDrops = env.current()->fees().base;
77 BEAST_EXPECT(env.balance(alice) == preAlice -
XRP(1000) - feeDrops);
82 BEAST_EXPECT(chanBal ==
XRP(0));
83 BEAST_EXPECT(chanAmt ==
XRP(2000));
105 auto const iou = USDA(100).value();
106 auto const negXRP =
XRP(-100).value();
107 auto const posXRP =
XRP(100).value();
117 auto const delta =
XRP(500);
118 auto const reqBal = chanBal + delta;
119 auto const authAmt = reqBal +
XRP(-100);
120 assert(reqBal <= chanAmt);
125 auto const preBob = env.balance(bob);
126 auto const delta =
XRP(500);
127 auto const reqBal = chanBal + delta;
128 auto const authAmt = reqBal +
XRP(100);
129 assert(reqBal <= chanAmt);
130 env(
claim(alice, chan, reqBal, authAmt));
132 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
133 BEAST_EXPECT(env.balance(bob) == preBob + delta);
138 auto preBob = env.balance(bob);
139 auto const delta =
XRP(500);
140 auto const reqBal = chanBal + delta;
141 auto const authAmt = reqBal +
XRP(100);
142 assert(reqBal <= chanAmt);
144 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
146 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
147 auto const feeDrops = env.current()->fees().base;
148 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
152 preBob = env.balance(bob);
155 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
156 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
160 auto const preBob = env.balance(bob);
163 assert(reqAmt <= chanAmt);
167 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
168 BEAST_EXPECT(env.balance(bob) == preBob);
174 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
181 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
188 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
192 auto const preAlice = env.balance(alice);
193 auto const preBob = env.balance(bob);
196 auto const feeDrops = env.current()->fees().base;
197 auto const delta = chanAmt - chanBal;
198 assert(delta > beast::zero);
199 BEAST_EXPECT(env.balance(alice) == preAlice + delta);
200 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
211 Env env{*
this, features};
212 auto const alice =
Account(
"alice");
213 auto const bob =
Account(
"bob");
214 auto const cho =
Account(
"cho");
215 env.fund(
XRP(10000), alice, bob, cho);
216 auto const pk = alice.pk();
217 auto const settleDelay = 100s;
225 auto const chan =
channel(alice, bob, env.seq(alice));
236 auto const chan =
channel(bob, alice, env.seq(bob));
247 auto const chan =
channel(alice, bob, env.seq(alice));
254 auto const chan =
channel(cho, alice, env.seq(cho));
265 auto const chan =
channel(cho, alice, env.seq(cho));
277 auto const alice =
Account(
"alice");
278 auto const bob =
Account(
"bob");
279 auto const carol =
Account(
"carol");
282 Env env{*
this, features};
283 env.fund(
XRP(10000), alice, bob);
284 auto const pk = alice.pk();
285 auto const settleDelay = 100s;
287 auto const channelFunds =
XRP(1000);
288 auto const chan =
channel(alice, bob, env.seq(alice));
289 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
291 env.close(cancelAfter);
296 auto preAlice = env.balance(alice);
297 auto preBob = env.balance(bob);
298 auto const delta =
XRP(500);
299 auto const reqBal = chanBal + delta;
300 auto const authAmt = reqBal +
XRP(100);
301 assert(reqBal <= chanAmt);
303 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
304 auto const feeDrops = env.current()->fees().base;
306 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
307 BEAST_EXPECT(env.balance(alice) == preAlice + channelFunds);
312 Env env{*
this, features};
313 env.fund(
XRP(10000), alice, bob, carol);
314 auto const pk = alice.pk();
315 auto const settleDelay = 100s;
317 auto const channelFunds =
XRP(1000);
318 auto const chan =
channel(alice, bob, env.seq(alice));
319 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
324 env.close(cancelAfter);
326 auto const preAlice = env.balance(alice);
329 BEAST_EXPECT(env.balance(alice) == preAlice + channelFunds);
334 for (
bool const withFixPayChan : {
true,
false})
336 auto const amend = withFixPayChan ? features : features - fixPayChanCancelAfter;
337 Env env{*
this, amend};
338 env.
fund(
XRP(10000), alice, bob);
341 auto const pk = alice.pk();
342 auto const settleDelay = 100s;
343 auto const channelFunds =
XRP(1000);
346 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter), txResult);
352 for (
bool const withFixPayChan : {
true,
false})
354 auto const amend = withFixPayChan ? features : features - fixPayChanCancelAfter;
355 Env env{*
this, amend};
356 env.
fund(
XRP(10000), alice, bob);
359 auto const pk = alice.pk();
360 auto const settleDelay = 100s;
361 auto const channelFunds =
XRP(1000);
374 Env env{*
this, features};
375 auto const alice =
Account(
"alice");
376 auto const bob =
Account(
"bob");
377 auto const carol =
Account(
"carol");
378 env.fund(
XRP(10000), alice, bob, carol);
379 auto const pk = alice.pk();
380 auto const settleDelay = 3600s;
381 auto const closeTime = env.current()->header().parentCloseTime;
382 auto const minExpiration = closeTime + settleDelay;
384 auto const channelFunds =
XRP(1000);
385 auto const chan =
channel(alice, bob, env.seq(alice));
386 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
391 auto counts = [](
auto const& t) {
return t.time_since_epoch().count(); };
395 BEAST_EXPECT(*
channelExpiration(*env.current(), chan) == counts(minExpiration) + 100);
398 BEAST_EXPECT(*
channelExpiration(*env.current(), chan) == counts(minExpiration) + 50);
401 BEAST_EXPECT(*
channelExpiration(*env.current(), chan) == counts(minExpiration) + 50);
403 BEAST_EXPECT(*
channelExpiration(*env.current(), chan) == counts(minExpiration) + 50);
410 env.close(minExpiration);
422 Env env{*
this, features};
423 auto const alice =
Account(
"alice");
424 auto const bob =
Account(
"bob");
425 env.fund(
XRP(10000), alice, bob);
426 auto const pk = alice.pk();
427 auto const settleDelay = 3600s;
428 NetClock::time_point const settleTimepoint = env.current()->header().parentCloseTime + settleDelay;
429 auto const channelFunds =
XRP(1000);
430 auto const chan =
channel(alice, bob, env.seq(alice));
431 env(
create(alice, bob, channelFunds, settleDelay, pk));
436 env.close(settleTimepoint - settleDelay / 2);
441 auto preBob = env.balance(bob);
442 auto const delta =
XRP(500);
443 auto const reqBal = chanBal + delta;
444 auto const authAmt = reqBal +
XRP(100);
445 assert(reqBal <= chanAmt);
447 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
449 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
450 auto const feeDrops = env.current()->fees().base;
451 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
453 env.close(settleTimepoint);
458 auto const preAlice = env.balance(alice);
459 auto preBob = env.balance(bob);
460 auto const delta =
XRP(500);
461 auto const reqBal = chanBal + delta;
462 auto const authAmt = reqBal +
XRP(100);
463 assert(reqBal <= chanAmt);
465 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
467 auto const feeDrops = env.current()->fees().base;
468 BEAST_EXPECT(env.balance(alice) == preAlice + chanAmt - chanBal);
469 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
479 Env env{*
this, features};
480 auto const alice =
Account(
"alice");
481 auto const bob =
Account(
"bob");
482 env.fund(
XRP(10000), alice, bob);
483 auto const pk = alice.pk();
484 auto const settleDelay = 3600s;
485 auto const channelFunds =
XRP(1000);
486 auto const chan =
channel(alice, bob, env.seq(alice));
487 env(
create(alice, bob, channelFunds, settleDelay, pk));
494 auto const preBob = env.balance(bob);
495 env(
claim(alice, chan, channelFunds.value(), channelFunds.value()));
496 BEAST_EXPECT(
channelBalance(*env.current(), chan) == channelFunds);
497 BEAST_EXPECT(env.balance(bob) == preBob + channelFunds);
499 auto const preAlice = env.balance(alice);
503 auto const feeDrops = env.current()->fees().base;
504 BEAST_EXPECT(env.balance(alice) == preAlice - feeDrops);
514 Env env{*
this, features};
515 auto const alice =
Account(
"alice");
516 auto const bob =
Account(
"bob");
517 env.fund(
XRP(10000), alice, bob);
518 auto const pk = alice.pk();
519 auto const settleDelay = 3600s;
520 auto const channelFunds =
XRP(1000);
521 auto const chan =
channel(alice, bob, env.seq(alice));
522 env(
create(alice, bob, channelFunds, settleDelay, pk));
530 auto const preBob = env.balance(bob);
532 auto const delta =
XRP(500);
533 auto const reqBal = chanBal + delta;
534 assert(reqBal <= chanAmt);
538 auto const feeDrops = env.current()->fees().base;
539 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
546 auto const preBob = env.balance(bob);
548 auto const delta =
XRP(500);
549 auto const reqBal = chanBal + delta;
550 assert(reqBal <= chanAmt);
554 auto const feeDrops = env.current()->fees().base;
555 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
568 auto const alice =
Account(
"alice");
569 auto const bob =
Account(
"bob");
573 Env env{*
this, features};
574 env.fund(
XRP(10000), alice, bob);
576 auto const chan =
channel(alice, bob, env.seq(alice));
577 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
585 Env env{*
this, features};
586 env.fund(
XRP(10000), alice, bob);
587 auto const chan =
channel(alice, bob, env.seq(alice));
588 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
592 auto const reqBal =
XRP(500).value();
593 env(
claim(alice, chan, reqBal, reqBal));
605 Env env{*
this, features};
606 auto const alice =
Account(
"alice");
607 auto const bob =
Account(
"bob");
608 env.fund(
XRP(10000), alice, bob);
610 auto const pk = alice.pk();
611 auto const settleDelay = 3600s;
612 auto const channelFunds =
XRP(1000);
614 auto const chan =
channel(alice, bob, env.seq(alice));
619 auto const chan =
channel(alice, bob, env.seq(alice));
632 auto const alice =
Account(
"alice");
633 auto const bob =
Account(
"bob");
634 auto const carol =
Account(
"carol");
635 auto USDA = alice[
"USD"];
637 Env env{*
this, features};
638 env.fund(
XRP(10000), alice, bob, carol);
643 auto const pk = alice.pk();
644 auto const settleDelay = 100s;
645 auto const chan =
channel(alice, bob, env.seq(alice));
646 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
654 env(
fund(alice, chan,
XRP(1000)));
662 auto const baseFee = env.current()->fees().base;
663 auto const preBob = env.balance(bob);
665 auto const delta =
XRP(500).value();
672 BEAST_EXPECT(env.balance(bob) == preBob);
684 BEAST_EXPECT(env.balance(bob) == preBob + delta - baseFee);
688 auto const delta =
XRP(600).value();
716 BEAST_EXPECT(env.balance(bob) == preBob + delta - (3 * baseFee));
721 auto const delta =
XRP(800).value();
735 env(
claim(alice, chan, delta, delta));
737 BEAST_EXPECT(env.balance(bob) == preBob +
XRP(800) - (5 * baseFee));
745 testcase(
"Deposit Authorization with Credentials");
749 char const credType[] =
"abcde";
754 Account const dillon(
"dillon");
759 env.
fund(
XRP(10000), alice, bob, carol, dillon, zelda);
761 auto const pk = alice.
pk();
762 auto const settleDelay = 100s;
763 auto const chan =
channel(alice, bob, env.seq(alice));
764 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
768 env(
fund(alice, chan,
XRP(1000)));
772 "D007AE4B6E1274B4AF872588267B810C2F82716726351D1C7D38D3E5499FC6"
775 auto const delta =
XRP(500).value();
779 uint32_t const t = env.current()->header().parentCloseTime.time_since_epoch().count() + 100;
780 jv[sfExpiration.jsonName] = t;
786 std::string const credIdx = jv[jss::result][jss::index].asString();
823 for (
int i = 0; i < 10; ++i)
837 std::string const credIdx = jv[jss::result][jss::index].asString();
846 env.
fund(
XRP(10000), alice, bob, carol, dillon, zelda);
848 auto const pk = alice.
pk();
849 auto const settleDelay = 100s;
850 auto const chan =
channel(alice, bob, env.seq(alice));
851 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
855 env(
fund(alice, chan,
XRP(1000)));
858 auto const delta =
XRP(500).value();
868 std::string const credIdx = jv[jss::result][jss::index].asString();
878 env.
fund(
XRP(5000),
"alice",
"bob");
881 auto const pk = alice.
pk();
882 auto const settleDelay = 100s;
883 auto const chan =
channel(alice, bob, env.
seq(alice));
884 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
887 env(
fund(alice, chan,
XRP(1000)));
890 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
907 testcase(
"Multiple channels to the same account");
910 Env env{*
this, features};
911 auto const alice =
Account(
"alice");
912 auto const bob =
Account(
"bob");
913 env.fund(
XRP(10000), alice, bob);
914 auto const pk = alice.pk();
915 auto const settleDelay = 3600s;
916 auto const channelFunds =
XRP(1000);
917 auto const chan1 =
channel(alice, bob, env.seq(alice));
918 env(
create(alice, bob, channelFunds, settleDelay, pk));
920 auto const chan2 =
channel(alice, bob, env.seq(alice));
921 env(
create(alice, bob, channelFunds, settleDelay, pk));
923 BEAST_EXPECT(chan1 != chan2);
933 Env env{*
this, features};
934 auto const alice =
Account(
"alice");
935 auto const bob =
Account(
"bob");
937 env.fund(
XRP(10000), alice, bob, charlie);
938 auto const pk = alice.pk();
939 auto const settleDelay = 3600s;
940 auto const channelFunds =
XRP(1000);
942 env(
create(alice, bob, channelFunds, settleDelay, pk));
946 auto testInvalidAccountParam = [&](
auto const& param) {
948 params[jss::account] = param;
949 auto jrr = env.rpc(
"json",
"account_channels",
to_string(params))[jss::result];
950 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
951 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'account'.");
954 testInvalidAccountParam(1);
955 testInvalidAccountParam(1.1);
956 testInvalidAccountParam(
true);
962 auto const r = env.rpc(
"account_channels", alice.human(), bob.human());
963 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
964 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
965 BEAST_EXPECT(r[jss::result][jss::validated]);
968 auto const r = env.rpc(
"account_channels", alice.human());
969 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
970 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
971 BEAST_EXPECT(r[jss::result][jss::validated]);
974 auto const r = env.rpc(
"account_channels", bob.human(), alice.human());
975 BEAST_EXPECT(r[jss::result][jss::channels].size() == 0);
976 BEAST_EXPECT(r[jss::result][jss::validated]);
979 env(
create(alice, bob, channelFunds, settleDelay, pk));
982 auto const r = env.rpc(
"account_channels", alice.human(), bob.human());
983 BEAST_EXPECT(r[jss::result][jss::channels].size() == 2);
984 BEAST_EXPECT(r[jss::result][jss::validated]);
985 BEAST_EXPECT(chan1Str != chan2Str);
986 for (
auto const& c : {chan1Str, chan2Str})
988 r[jss::result][jss::channels][0u][jss::channel_id] == c ||
989 r[jss::result][jss::channels][1u][jss::channel_id] == c);
996 testcase(
"Account channels RPC markers");
998 using namespace test::jtx;
1001 auto const alice =
Account(
"alice");
1006 for (
int i = 0; i < n; ++i)
1013 Env env{*
this, features};
1014 env.fund(
XRP(10000), alice);
1015 for (
auto const& a : bobs)
1017 env.fund(
XRP(10000), a);
1023 auto const settleDelay = 3600s;
1024 auto const channelFunds =
XRP(1);
1025 for (
auto const& b : bobs)
1027 env(
create(alice, b, channelFunds, settleDelay, alice.pk()));
1037 jvc[jss::account] = src.human();
1039 jvc[jss::destination_account] = dst->human();
1041 jvc[jss::limit] = *limit;
1043 jvc[jss::marker] = marker;
1045 return env.
rpc(
"json",
"account_channels",
to_string(jvc))[jss::result];
1050 auto const r = testLimit(env, alice);
1051 BEAST_EXPECT(r.isMember(jss::channels));
1052 BEAST_EXPECT(r[jss::channels].size() == bobs.size());
1057 for (
auto const& a : bobs)
1062 for (
int limit = 1; limit < bobs.size() + 1; ++limit)
1064 auto leftToFind = bobsB58;
1065 auto const numFull = bobs.
size() / limit;
1066 auto const numNonFull = bobs.size() % limit ? 1 : 0;
1070 auto const testIt = [&](
bool expectMarker,
int expectedBatchSize) {
1071 auto const r = testLimit(env, alice, limit, marker);
1072 BEAST_EXPECT(!expectMarker || r.isMember(jss::marker));
1073 if (r.isMember(jss::marker))
1074 marker = r[jss::marker];
1075 BEAST_EXPECT(r[jss::channels].size() == expectedBatchSize);
1076 auto const c = r[jss::channels];
1077 auto const s = r[jss::channels].size();
1078 for (
int j = 0; j < s; ++j)
1080 auto const dstAcc = c[j][jss::destination_account].asString();
1081 BEAST_EXPECT(leftToFind.count(dstAcc));
1082 leftToFind.erase(dstAcc);
1086 for (
int i = 0; i < numFull; ++i)
1088 bool const expectMarker = (numNonFull != 0 || i < numFull - 1);
1089 testIt(expectMarker, limit);
1094 testIt(
false, bobs.size() % limit);
1096 BEAST_EXPECT(leftToFind.empty());
1101 auto const r = testLimit(env, alice, 0);
1102 BEAST_EXPECT(r.isMember(jss::error_message));
1111 testcase(
"Account channels RPC owner only");
1113 using namespace test::jtx;
1116 auto const alice =
Account(
"alice");
1117 auto const bob =
Account(
"bob");
1118 Env env{*
this, features};
1119 env.fund(
XRP(10000), alice, bob);
1124 auto const settleDelay = 3600s;
1125 auto const channelFunds =
XRP(1000);
1126 env(
create(alice, bob, channelFunds, settleDelay, alice.pk()));
1127 env(
create(bob, alice, channelFunds, settleDelay, bob.pk()));
1129 auto const r = [&] {
1131 jvc[jss::account] = alice.human();
1133 return env.rpc(
"json",
"account_channels",
to_string(jvc))[jss::result];
1135 BEAST_EXPECT(r.isMember(jss::channels));
1136 BEAST_EXPECT(r[jss::channels].size() == 1);
1137 BEAST_EXPECT(r[jss::channels][0u][jss::destination_account].asString() == bob.human());
1143 using namespace jtx;
1146 Env env{*
this, features};
1147 auto const alice =
Account(
"alice");
1148 auto const bob =
Account(
"bob");
1150 env.fund(
XRP(10000), alice, bob, charlie);
1151 auto const pk = alice.pk();
1152 auto const settleDelay = 3600s;
1153 auto const channelFunds =
XRP(1000);
1155 env(
create(alice, bob, channelFunds, settleDelay, pk));
1159 args[jss::channel_id] = chan1Str;
1160 args[jss::key_type] =
"ed255191";
1161 args[jss::seed] =
"snHq1rzQoN2qiUkC3XF5RyxBzUtN";
1162 args[jss::amount] = 51110000;
1167 args[jss::api_version] = apiVersion;
1168 auto const rs = env.rpc(
"json",
"channel_authorize", args.toStyledString())[jss::result];
1169 auto const error = apiVersion < 2u ?
"invalidParams" :
"badKeyType";
1170 BEAST_EXPECT(rs[jss::error] == error);
1177 testcase(
"PayChan Auth/Verify RPC");
1178 using namespace jtx;
1180 Env env{*
this, features};
1181 auto const alice =
Account(
"alice");
1182 auto const bob =
Account(
"bob");
1184 env.fund(
XRP(10000), alice, bob, charlie);
1185 auto const pk = alice.pk();
1186 auto const settleDelay = 3600s;
1187 auto const channelFunds =
XRP(1000);
1189 env(
create(alice, bob, channelFunds, settleDelay, pk));
1193 auto const r = env.rpc(
"account_channels", alice.human(), bob.human());
1194 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1195 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1196 BEAST_EXPECT(r[jss::result][jss::validated]);
1197 chan1PkStr = r[jss::result][jss::channels][0u][jss::public_key].asString();
1200 auto const r = env.rpc(
"account_channels", alice.human());
1201 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1202 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1203 BEAST_EXPECT(r[jss::result][jss::validated]);
1204 chan1PkStr = r[jss::result][jss::channels][0u][jss::public_key].asString();
1207 auto const r = env.rpc(
"account_channels", bob.human(), alice.human());
1208 BEAST_EXPECT(r[jss::result][jss::channels].size() == 0);
1209 BEAST_EXPECT(r[jss::result][jss::validated]);
1212 env(
create(alice, bob, channelFunds, settleDelay, pk));
1215 auto const r = env.rpc(
"account_channels", alice.human(), bob.human());
1216 BEAST_EXPECT(r[jss::result][jss::channels].size() == 2);
1217 BEAST_EXPECT(r[jss::result][jss::validated]);
1218 BEAST_EXPECT(chan1Str != chan2Str);
1219 for (
auto const& c : {chan1Str, chan2Str})
1221 r[jss::result][jss::channels][0u][jss::channel_id] == c ||
1222 r[jss::result][jss::channels][1u][jss::channel_id] == c);
1230 s +=
"0123456789ABCDEF"[((
slice[i] & 0xf0) >> 4)];
1231 s +=
"0123456789ABCDEF"[((
slice[i] & 0x0f) >> 0)];
1238 auto const rs = env.rpc(
"channel_authorize",
"alice", chan1Str,
"1000");
1239 auto const sig = rs[jss::result][jss::signature].asString();
1240 BEAST_EXPECT(!
sig.empty());
1242 auto const rv = env.rpc(
"channel_verify", chan1PkStr, chan1Str,
"1000",
sig);
1243 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1249 auto const rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000",
sig);
1250 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1255 auto rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000x",
sig);
1256 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1257 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000 ",
sig);
1258 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1259 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"x1000",
sig);
1260 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1261 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"x",
sig);
1262 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1263 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
" ",
sig);
1264 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1265 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000 1000",
sig);
1266 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1267 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1,000",
sig);
1268 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1269 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
" 1000",
sig);
1270 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1271 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"",
sig);
1272 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1277 auto chan1StrBad = chan1Str;
1278 chan1StrBad.pop_back();
1279 auto rv = env.rpc(
"channel_verify", pkAsHex, chan1StrBad,
"1000",
sig);
1280 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1281 rv = env.rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1282 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1284 chan1StrBad = chan1Str;
1285 chan1StrBad.push_back(
'0');
1286 rv = env.rpc(
"channel_verify", pkAsHex, chan1StrBad,
"1000",
sig);
1287 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1288 rv = env.rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1289 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1291 chan1StrBad = chan1Str;
1292 chan1StrBad.back() =
'x';
1293 rv = env.rpc(
"channel_verify", pkAsHex, chan1StrBad,
"1000",
sig);
1294 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1295 rv = env.rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1296 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1300 auto illFormedPk = chan1PkStr.
substr(0, chan1PkStr.
size() - 1);
1301 auto const rv = env.rpc(
"channel_verify", illFormedPk, chan1Str,
"1000",
sig);
1302 BEAST_EXPECT(!rv[jss::result][jss::signature_verified].asBool());
1307 auto illFormedPk = pkAsHex.substr(0, chan1PkStr.
size() - 1);
1308 auto const rv = env.rpc(
"channel_verify", illFormedPk, chan1Str,
"1000",
sig);
1309 BEAST_EXPECT(!rv[jss::result][jss::signature_verified].asBool());
1314 auto const rs = env.rpc(
"channel_authorize",
"alice", chan2Str,
"1000");
1315 auto const sig = rs[jss::result][jss::signature].asString();
1316 BEAST_EXPECT(!
sig.empty());
1318 auto const rv = env.rpc(
"channel_verify", chan1PkStr, chan1Str,
"1000",
sig);
1319 BEAST_EXPECT(!rv[jss::result][jss::signature_verified].asBool());
1324 auto const rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000",
sig);
1325 BEAST_EXPECT(!rv[jss::result][jss::signature_verified].asBool());
1331 env(
create(charlie, alice, channelFunds, settleDelay, charlie.pk()));
1336 auto const r = env.rpc(
"account_channels", charlie.human(), alice.human());
1337 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1338 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1339 BEAST_EXPECT(r[jss::result][jss::validated]);
1340 cpk = r[jss::result][jss::channels][0u][jss::public_key].asString();
1344 auto const rs = env.rpc(
"channel_authorize",
"charlie", chan,
"1000");
1345 auto const sig = rs[jss::result][jss::signature].asString();
1346 BEAST_EXPECT(!
sig.empty());
1348 auto const rv = env.rpc(
"channel_verify", cpk, chan,
"1000",
sig);
1349 BEAST_EXPECT(!rv[jss::result][jss::signature_verified].asBool());
1353 auto const rs1 = env.rpc(
"channel_authorize",
"charlie",
"nyx", chan,
"1000");
1354 BEAST_EXPECT(rs1[jss::error] ==
"badKeyType");
1358 auto const rs2 = env.rpc(
"channel_authorize",
"charlie",
"secp256k1", chan,
"1000");
1359 auto const sig2 = rs2[jss::result][jss::signature].asString();
1360 BEAST_EXPECT(!sig2.empty());
1362 auto const rv = env.rpc(
"channel_verify", cpk, chan,
"1000", sig2);
1363 BEAST_EXPECT(!rv[jss::result][jss::signature_verified].asBool());
1367 auto const rs3 = env.rpc(
"channel_authorize",
"charlie",
"ed25519", chan,
"1000");
1368 auto const sig3 = rs3[jss::result][jss::signature].asString();
1369 BEAST_EXPECT(!sig3.empty());
1371 auto const rv = env.rpc(
"channel_verify", cpk, chan,
"1000", sig3);
1372 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1378 auto rs = env.rpc(
"channel_authorize",
"alice", chan1Str,
"1000x");
1379 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1380 rs = env.rpc(
"channel_authorize",
"alice", chan1Str,
"x1000");
1381 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1382 rs = env.rpc(
"channel_authorize",
"alice", chan1Str,
"x");
1383 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1387 args[jss::amount] =
"2000";
1388 args[jss::key_type] =
"secp256k1";
1389 args[jss::passphrase] =
"passphrase_can_be_anything";
1390 rs = env.rpc(
"json",
"channel_authorize", args.toStyledString())[jss::result];
1391 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1396 args[jss::channel_id] = chan1Str;
1397 args[jss::key_type] =
"secp256k1";
1398 args[jss::passphrase] =
"passphrase_can_be_anything";
1399 rs = env.rpc(
"json",
"channel_authorize", args.toStyledString())[jss::result];
1400 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1405 args[jss::amount] =
"2000";
1406 args[jss::channel_id] = chan1Str;
1407 args[jss::passphrase] =
"passphrase_can_be_anything";
1408 rs = env.rpc(
"json",
"channel_authorize", args.toStyledString())[jss::result];
1409 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1414 args[jss::amount] =
"2000";
1415 args[jss::channel_id] = chan1Str;
1416 args[jss::key_type] =
"secp256k1";
1417 args[jss::passphrase] =
"passphrase_can_be_anything";
1418 args[jss::seed] =
"seed can be anything";
1419 rs = env.rpc(
"json",
"channel_authorize", args.toStyledString())[jss::result];
1420 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1425 args[jss::amount] =
"2000";
1426 args[jss::channel_id] = chan1Str +
"1";
1427 args[jss::key_type] =
"secp256k1";
1428 args[jss::passphrase] =
"passphrase_can_be_anything";
1429 rs = env.rpc(
"json",
"channel_authorize", args.toStyledString())[jss::result];
1430 BEAST_EXPECT(rs[jss::error] ==
"channelMalformed");
1435 args[jss::amount] = 2000;
1436 args[jss::channel_id] = chan1Str;
1437 args[jss::key_type] =
"secp256k1";
1438 args[jss::passphrase] =
"passphrase_can_be_anything";
1439 rs = env.rpc(
"json",
"channel_authorize", args.toStyledString())[jss::result];
1440 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1445 args[jss::amount] =
"TwoThousand";
1446 args[jss::channel_id] = chan1Str;
1447 args[jss::key_type] =
"secp256k1";
1448 args[jss::passphrase] =
"passphrase_can_be_anything";
1449 rs = env.rpc(
"json",
"channel_authorize", args.toStyledString())[jss::result];
1450 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1459 using namespace jtx;
1461 Env env{*
this, features};
1462 auto const alice =
Account(
"alice");
1463 auto const bob =
Account(
"bob");
1464 auto const carol =
Account(
"carol");
1465 auto const dan =
Account(
"dan");
1466 env.fund(
XRP(10000), alice, bob, carol, dan);
1467 auto const pk = alice.pk();
1468 auto const settleDelay = 3600s;
1469 auto const channelFunds =
XRP(1000);
1475 env(
create(alice, bob, channelFunds, settleDelay, pk));
1476 auto const r = env.rpc(
"account_channels", alice.human(), bob.human());
1477 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1478 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1479 BEAST_EXPECT(!r[jss::result][jss::channels][0u].isMember(jss::destination_tag));
1484 env(
create(alice, carol, channelFunds, settleDelay, pk, cancelAfter, dstTag));
1485 auto const r = env.rpc(
"account_channels", alice.human(), carol.human());
1486 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1487 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1488 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::destination_tag] == dstTag);
1496 using namespace jtx;
1498 Env env{*
this, features};
1499 auto const alice =
Account(
"alice");
1500 auto const bob =
Account(
"bob");
1501 auto USDA = alice[
"USD"];
1502 env.fund(
XRP(10000), alice, bob);
1503 auto const pk = alice.pk();
1504 auto const settleDelay = 100s;
1506 auto const chan =
channel(alice, bob, env.seq(alice));
1507 auto jv =
create(alice, bob,
XRP(1000), settleDelay, pk);
1508 auto const pkHex =
strHex(pk.slice());
1509 jv[
"PublicKey"] = pkHex.substr(2, pkHex.size() - 2);
1511 jv[
"PublicKey"] = pkHex.substr(0, pkHex.size() - 2);
1513 auto badPrefix = pkHex;
1516 jv[
"PublicKey"] = badPrefix;
1519 jv[
"PublicKey"] = pkHex;
1522 auto const authAmt =
XRP(100);
1524 jv =
claim(bob, chan, authAmt.value(), authAmt.value(),
Slice(
sig), alice.pk());
1525 jv[
"PublicKey"] = pkHex.substr(2, pkHex.size() - 2);
1527 jv[
"PublicKey"] = pkHex.substr(0, pkHex.size() - 2);
1532 jv[
"PublicKey"] = badPrefix;
1536 jv.removeMember(
"PublicKey");
1540 auto const txn = R
"*(
1543 "channel_id":"5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
1545 "304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064",
1547 "aKijDDiC2q2gXjMpM7i4BUS6cmixgsEe18e7CjsUxwihKfuoFgS5",
1551 auto const r = env.rpc(
"json",
"channel_verify", txn);
1552 BEAST_EXPECT(r[
"result"][
"error"] ==
"publicMalformed");
1561 using namespace jtx;
1564 auto const alice =
Account(
"alice");
1565 auto const bob =
Account(
"bob");
1566 auto const settleDelay = 100s;
1567 auto const pk = alice.pk();
1571 return std::find(ownerDir.begin(), ownerDir.end(), chan) != ownerDir.end();
1581 Env env{*
this, features};
1582 env.fund(
XRP(10000), alice, bob);
1583 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1586 BEAST_EXPECT(inOwnerDir(*env.current(), alice, chanSle));
1587 BEAST_EXPECT(ownerDirCount(*env.current(), alice) == 1);
1588 BEAST_EXPECT(inOwnerDir(*env.current(), bob, chanSle));
1589 BEAST_EXPECT(ownerDirCount(*env.current(), bob) == 1);
1593 BEAST_EXPECT(!inOwnerDir(*env.current(), alice, chanSle));
1594 BEAST_EXPECT(ownerDirCount(*env.current(), alice) == 0);
1595 BEAST_EXPECT(!inOwnerDir(*env.current(), bob, chanSle));
1596 BEAST_EXPECT(ownerDirCount(*env.current(), bob) == 0);
1602 Env env(*
this, features);
1603 env.
fund(
XRP(10000), alice, bob);
1605 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1608 BEAST_EXPECT(inOwnerDir(*env.
current(), alice, chanSle));
1609 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 1);
1610 BEAST_EXPECT(inOwnerDir(*env.
current(), bob, chanSle));
1611 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 1);
1615 BEAST_EXPECT(!inOwnerDir(*env.
current(), alice, chanSle));
1616 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 0);
1617 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1618 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1626 using namespace test::jtx;
1631 for (
auto minRmSeq = env.
seq(toRm) + 257; env.
current()->seq() < minRmSeq; env.
close())
1640 auto const alice =
Account(
"alice");
1641 auto const bob =
Account(
"bob");
1642 auto const carol =
Account(
"carol");
1645 Env env{*
this, features};
1646 env.
fund(
XRP(10000), alice, bob, carol);
1650 auto const pk = alice.pk();
1651 auto const settleDelay = 100s;
1652 auto const chan =
channel(alice, bob, env.
seq(alice));
1653 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1661 auto const feeDrops = env.
current()->fees().base;
1664 BEAST_EXPECT(chanBal ==
XRP(0));
1665 BEAST_EXPECT(chanAmt ==
XRP(1000));
1667 auto preBob = env.
balance(bob);
1668 auto const delta =
XRP(50);
1669 auto reqBal = chanBal + delta;
1670 auto authAmt = reqBal +
XRP(100);
1671 assert(reqBal <= chanAmt);
1673 env(
claim(alice, chan, reqBal, authAmt));
1677 BEAST_EXPECT(env.
balance(bob) == preBob + delta);
1680 auto const preAlice = env.
balance(alice);
1681 env(
fund(alice, chan,
XRP(1000)));
1683 BEAST_EXPECT(env.
balance(alice) == preAlice -
XRP(1000) - feeDrops);
1685 chanAmt = chanAmt +
XRP(1000);
1693 auto const closeTime = env.
current()->header().parentCloseTime;
1694 auto const minExpiration = closeTime + settleDelay;
1695 env.
close(minExpiration);
1706 using namespace jtx;
1708 Env env{*
this, features};
1709 auto const alice =
Account(
"alice");
1710 auto const bob =
Account(
"bob");
1711 auto USDA = alice[
"USD"];
1712 env.fund(
XRP(10000), alice, bob);
1725 auto const pk = alice.pk();
1726 auto const settleDelay = 100s;
1727 auto const chan =
channel(alice, bob, aliceTicketSeq);
1731 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1732 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1738 auto const preAlice = env.balance(alice);
1741 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1742 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1744 auto const feeDrops = env.current()->fees().base;
1745 BEAST_EXPECT(env.balance(alice) == preAlice -
XRP(1000) - feeDrops);
1750 BEAST_EXPECT(chanBal ==
XRP(0));
1751 BEAST_EXPECT(chanAmt ==
XRP(2000));
1755 auto const preBob = env.balance(bob);
1756 auto const delta =
XRP(500);
1757 auto const reqBal = chanBal + delta;
1758 auto const authAmt = reqBal +
XRP(100);
1759 assert(reqBal <= chanAmt);
1762 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1763 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1766 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
1767 BEAST_EXPECT(env.balance(bob) == preBob + delta);
1772 auto preBob = env.balance(bob);
1773 auto const delta =
XRP(500);
1774 auto const reqBal = chanBal + delta;
1775 auto const authAmt = reqBal +
XRP(100);
1776 assert(reqBal <= chanAmt);
1780 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
1781 BEAST_EXPECT(env.seq(bob) == bobSeq);
1784 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
1785 auto const feeDrops = env.current()->fees().base;
1786 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
1790 preBob = env.balance(bob);
1792 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()),
1796 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
1797 BEAST_EXPECT(env.seq(bob) == bobSeq);
1800 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
1801 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
1805 auto const preBob = env.balance(bob);
1808 assert(reqAmt <= chanAmt);
1812 env(
claim(bob, chan, reqAmt, authAmt,
Slice(
sig), alice.pk()),
1816 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
1817 BEAST_EXPECT(env.seq(bob) == bobSeq);
1820 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
1821 BEAST_EXPECT(env.balance(bob) == preBob);
1827 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
1828 BEAST_EXPECT(env.seq(bob) == bobSeq);
1831 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
1835 auto const preAlice = env.balance(alice);
1836 auto const preBob = env.balance(bob);
1839 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
1840 BEAST_EXPECT(env.seq(bob) == bobSeq);
1843 auto const feeDrops = env.current()->fees().base;
1844 auto const delta = chanAmt - chanBal;
1845 assert(delta > beast::zero);
1846 BEAST_EXPECT(env.balance(alice) == preAlice + delta);
1847 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
1849 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1850 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1851 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
1852 BEAST_EXPECT(env.seq(bob) == bobSeq);
1885 using namespace test::jtx;
1893BEAST_DEFINE_TESTSUITE(PayChan, app,
xrpl);
testcase_t testcase
Memberspace for declaring test cases.
Like std::vector<char> but better.
A class that simplifies iterating ledger directory pages.
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
Slice slice() const noexcept
An immutable linear range of bytes.
Immutable cryptographic account descriptor.
PublicKey const & pk() const
Return the public key.
A transaction testing environment.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Set the regular signature on a JTx.
Set the expected result code for a JTx The test will fail if the code doesn't match.
Set a ticket sequence on a JTx.
T emplace_back(T... args)
@ arrayValue
array value (ordered list)
@ objectValue
object value (collection of name/value pairs).
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Keylet account(AccountID const &id) noexcept
AccountID root.
Json::Value accept(jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
Json::Value ledgerEntry(jtx::Env &env, jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
Json::Value create(jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
Json::Value authCredentials(jtx::Account const &account, std::vector< AuthorizeCredentials > const &auth)
Json::Value unauth(Account const &account, Account const &unauth)
Remove pre-authorization for deposit.
Json::Value auth(Account const &account, Account const &auth)
Preauthorize for deposit.
STAmount channelBalance(ReadView const &view, uint256 const &chan)
uint256 channel(AccountID const &account, AccountID const &dst, std::uint32_t seqProxyValue)
Json::Value claim(AccountID const &account, uint256 const &channel, std::optional< STAmount > const &balance, std::optional< STAmount > const &amount, std::optional< Slice > const &signature, std::optional< PublicKey > const &pk)
bool channelExists(ReadView const &view, uint256 const &chan)
Json::Value create(AccountID const &account, AccountID const &to, STAmount const &amount, NetClock::duration const &settleDelay, PublicKey const &pk, std::optional< NetClock::time_point > const &cancelAfter, std::optional< std::uint32_t > const &dstTag)
Json::Value create(Account const &account, std::uint32_t count)
Create one of more tickets.
void fund(jtx::Env &env, jtx::Account const &gw, std::vector< jtx::Account > const &accounts, std::vector< STAmount > const &amts, Fund how)
XRP_t const XRP
Converts to XRP Issue or STAmount.
Json::Value fclear(Account const &account, std::uint32_t off)
Remove account flag.
FeatureBitset testable_amendments()
void sign(Json::Value &jv, Account const &account, Json::Value &sigObject)
Sign automatically into a specific Json field of the jv object.
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
Json::Value acctdelete(Account const &account, Account const &dest)
Delete account.
owner_count< ltTICKET > tickets
Match the number of tickets on the account.
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::uint32_t asfRequireDest
std::string to_string(base_uint< Bits, Tag > const &a)
std::string strHex(FwdIt begin, FwdIt end)
constexpr std::uint32_t asfDisallowIncomingPayChan
constexpr std::uint32_t asfDepositAuth
void serializePayChanAuthorization(Serializer &msg, uint256 const &key, XRPAmount const &amt)
constexpr std::uint32_t tfRenew
TERSubset< CanCvtToTER > TER
void forAllApiVersions(Fn const &fn, Args &&... args)
static std::string sliceToHex(Slice const &slice)
constexpr std::uint32_t tfClose
bool isTesSuccess(TER x) noexcept
constexpr std::uint32_t asfDisallowXRP
void testSettleDelay(FeatureBitset features)
void testOptionalFields(FeatureBitset features)
void testSimple(FeatureBitset features)
void testMetaAndOwnership(FeatureBitset features)
void testMultiple(FeatureBitset features)
static std::pair< uint256, std::shared_ptr< SLE const > > channelKeyAndSle(ReadView const &view, jtx::Account const &account, jtx::Account const &dst)
void testCancelAfter(FeatureBitset features)
static std::optional< std::int64_t > channelExpiration(ReadView const &view, uint256 const &chan)
void testWithFeats(FeatureBitset features)
void testDepositAuth(FeatureBitset features)
void testDefaultAmount(FeatureBitset features)
void testCloseDry(FeatureBitset features)
void testDepositAuthCreds()
void testUsingTickets(FeatureBitset features)
void testDstTag(FeatureBitset features)
void testAccountChannelAuthorize(FeatureBitset features)
void testAccountChannelsRPC(FeatureBitset features)
void testExpiration(FeatureBitset features)
static Buffer signClaimAuth(PublicKey const &pk, SecretKey const &sk, uint256 const &channel, STAmount const &authAmt)
void testDisallowIncoming(FeatureBitset features)
void testAuthVerifyRPC(FeatureBitset features)
void testAccountDelete(FeatureBitset features)
static STAmount channelAmount(ReadView const &view, uint256 const &chan)
void run() override
Runs the suite.
void testDisallowXRP(FeatureBitset features)
void testAccountChannelsRPCSenderOnly(FeatureBitset features)
void testMalformedPK(FeatureBitset features)
void testAccountChannelsRPCMarkers(FeatureBitset features)