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;
27 return {k.key, view.
read(k)};
45 auto const slep = view.
read({ltPAYCHAN, chan});
48 return (*slep)[sfAmount];
54 auto const slep = view.
read({ltPAYCHAN, chan});
57 if (
auto const r = (*slep)[~sfExpiration])
68 Env env{*
this, features};
69 auto const alice =
Account(
"alice");
70 auto const bob =
Account(
"bob");
71 auto USDA = alice[
"USD"];
72 env.fund(
XRP(10000), alice, bob);
73 auto const pk = alice.pk();
74 auto const settleDelay = 100s;
75 auto const chan =
channel(alice, bob, env.seq(alice));
76 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
81 auto const preAlice = env.balance(alice);
82 env(
fund(alice, chan,
XRP(1000)));
83 auto const feeDrops = env.current()->fees().base;
84 BEAST_EXPECT(env.balance(alice) == preAlice -
XRP(1000) - feeDrops);
89 BEAST_EXPECT(chanBal ==
XRP(0));
90 BEAST_EXPECT(chanAmt ==
XRP(2000));
94 env(
create(alice, bob, USDA(1000), settleDelay, pk),
97 env(
create(alice, bob,
XRP(-1000), settleDelay, pk),
103 env(
create(alice,
"noAccount",
XRP(1000), settleDelay, pk),
106 env(
create(alice, alice,
XRP(1000), settleDelay, pk),
112 channel(alice,
"noAccount", env.seq(alice) - 1),
120 auto const iou = USDA(100).value();
121 auto const negXRP =
XRP(-100).value();
122 auto const posXRP =
XRP(100).value();
132 auto const delta =
XRP(500);
133 auto const reqBal = chanBal + delta;
134 auto const authAmt = reqBal +
XRP(-100);
135 assert(reqBal <= chanAmt);
140 auto const preBob = env.balance(bob);
141 auto const delta =
XRP(500);
142 auto const reqBal = chanBal + delta;
143 auto const authAmt = reqBal +
XRP(100);
144 assert(reqBal <= chanAmt);
145 env(
claim(alice, chan, reqBal, authAmt));
147 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
148 BEAST_EXPECT(env.balance(bob) == preBob + delta);
153 auto preBob = env.balance(bob);
154 auto const delta =
XRP(500);
155 auto const reqBal = chanBal + delta;
156 auto const authAmt = reqBal +
XRP(100);
157 assert(reqBal <= chanAmt);
160 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
162 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
163 auto const feeDrops = env.current()->fees().base;
164 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
168 preBob = env.balance(bob);
169 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()),
172 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
173 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
177 auto const preBob = env.balance(bob);
180 assert(reqAmt <= chanAmt);
183 env(
claim(bob, chan, reqAmt, authAmt,
Slice(
sig), alice.pk()),
186 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
187 BEAST_EXPECT(env.balance(bob) == preBob);
193 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
207 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
221 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
225 auto const preAlice = env.balance(alice);
226 auto const preBob = env.balance(bob);
229 auto const feeDrops = env.current()->fees().base;
230 auto const delta = chanAmt - chanBal;
231 assert(delta > beast::zero);
232 BEAST_EXPECT(env.balance(alice) == preAlice + delta);
233 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
244 Env env{*
this, features};
245 auto const alice =
Account(
"alice");
246 auto const bob =
Account(
"bob");
247 auto const cho =
Account(
"cho");
248 env.fund(
XRP(10000), alice, bob, cho);
249 auto const pk = alice.pk();
250 auto const settleDelay = 100s;
258 auto const chan =
channel(alice, bob, env.seq(alice));
259 env(
create(alice, bob,
XRP(1000), settleDelay, pk),
270 auto const chan =
channel(bob, alice, env.seq(bob));
271 env(
create(bob, alice,
XRP(1000), settleDelay, pk),
282 auto const chan =
channel(alice, bob, env.seq(alice));
283 env(
create(alice, bob,
XRP(1000), settleDelay, pk),
290 auto const chan =
channel(cho, alice, env.seq(cho));
291 env(
create(cho, alice,
XRP(1000), settleDelay, pk),
302 auto const chan =
channel(cho, alice, env.seq(cho));
303 env(
create(cho, alice,
XRP(1000), settleDelay, pk),
315 auto const alice =
Account(
"alice");
316 auto const bob =
Account(
"bob");
317 auto const carol =
Account(
"carol");
320 Env env{*
this, features};
321 env.fund(
XRP(10000), alice, bob);
322 auto const pk = alice.pk();
323 auto const settleDelay = 100s;
325 env.current()->info().parentCloseTime + 3600s;
326 auto const channelFunds =
XRP(1000);
327 auto const chan =
channel(alice, bob, env.seq(alice));
328 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
330 env.close(cancelAfter);
335 auto preAlice = env.balance(alice);
336 auto preBob = env.balance(bob);
337 auto const delta =
XRP(500);
338 auto const reqBal = chanBal + delta;
339 auto const authAmt = reqBal +
XRP(100);
340 assert(reqBal <= chanAmt);
343 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
344 auto const feeDrops = env.current()->fees().base;
346 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
347 BEAST_EXPECT(env.balance(alice) == preAlice + channelFunds);
352 Env env{*
this, features};
353 env.fund(
XRP(10000), alice, bob, carol);
354 auto const pk = alice.pk();
355 auto const settleDelay = 100s;
357 env.current()->info().parentCloseTime + 3600s;
358 auto const channelFunds =
XRP(1000);
359 auto const chan =
channel(alice, bob, env.seq(alice));
360 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
365 env.close(cancelAfter);
367 auto const preAlice = env.balance(alice);
370 BEAST_EXPECT(env.balance(alice) == preAlice + channelFunds);
375 for (
bool const withFixPayChan : {
true,
false})
377 auto const amend = withFixPayChan
379 : features - fixPayChanCancelAfter;
380 Env env{*
this, amend};
381 env.
fund(
XRP(10000), alice, bob);
384 auto const pk = alice.pk();
385 auto const settleDelay = 100s;
386 auto const channelFunds =
XRP(1000);
388 env.current()->info().parentCloseTime - 1s;
389 auto const txResult =
392 alice, bob, channelFunds, settleDelay, pk, cancelAfter),
399 for (
bool const withFixPayChan : {
true,
false})
401 auto const amend = withFixPayChan
403 : features - fixPayChanCancelAfter;
404 Env env{*
this, amend};
405 env.
fund(
XRP(10000), alice, bob);
408 auto const pk = alice.pk();
409 auto const settleDelay = 100s;
410 auto const channelFunds =
XRP(1000);
412 env.current()->info().parentCloseTime;
414 alice, bob, channelFunds, settleDelay, pk, cancelAfter),
426 Env env{*
this, features};
427 auto const alice =
Account(
"alice");
428 auto const bob =
Account(
"bob");
429 auto const carol =
Account(
"carol");
430 env.fund(
XRP(10000), alice, bob, carol);
431 auto const pk = alice.pk();
432 auto const settleDelay = 3600s;
433 auto const closeTime = env.current()->info().parentCloseTime;
434 auto const minExpiration = closeTime + settleDelay;
436 auto const channelFunds =
XRP(1000);
437 auto const chan =
channel(alice, bob, env.seq(alice));
438 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
443 auto counts = [](
auto const& t) {
444 return t.time_since_epoch().count();
453 counts(minExpiration) + 100);
459 counts(minExpiration) + 50);
466 counts(minExpiration) + 50);
470 counts(minExpiration) + 50);
479 env.close(minExpiration);
492 Env env{*
this, features};
493 auto const alice =
Account(
"alice");
494 auto const bob =
Account(
"bob");
495 env.fund(
XRP(10000), alice, bob);
496 auto const pk = alice.pk();
497 auto const settleDelay = 3600s;
499 env.current()->info().parentCloseTime + settleDelay;
500 auto const channelFunds =
XRP(1000);
501 auto const chan =
channel(alice, bob, env.seq(alice));
502 env(
create(alice, bob, channelFunds, settleDelay, pk));
507 env.close(settleTimepoint - settleDelay / 2);
512 auto preBob = env.balance(bob);
513 auto const delta =
XRP(500);
514 auto const reqBal = chanBal + delta;
515 auto const authAmt = reqBal +
XRP(100);
516 assert(reqBal <= chanAmt);
519 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
521 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
522 auto const feeDrops = env.current()->fees().base;
523 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
525 env.close(settleTimepoint);
530 auto const preAlice = env.balance(alice);
531 auto preBob = env.balance(bob);
532 auto const delta =
XRP(500);
533 auto const reqBal = chanBal + delta;
534 auto const authAmt = reqBal +
XRP(100);
535 assert(reqBal <= chanAmt);
538 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
540 auto const feeDrops = env.current()->fees().base;
541 BEAST_EXPECT(env.balance(alice) == preAlice + chanAmt - chanBal);
542 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
552 Env env{*
this, features};
553 auto const alice =
Account(
"alice");
554 auto const bob =
Account(
"bob");
555 env.fund(
XRP(10000), alice, bob);
556 auto const pk = alice.pk();
557 auto const settleDelay = 3600s;
558 auto const channelFunds =
XRP(1000);
559 auto const chan =
channel(alice, bob, env.seq(alice));
560 env(
create(alice, bob, channelFunds, settleDelay, pk));
567 auto const preBob = env.balance(bob);
568 env(
claim(alice, chan, channelFunds.value(), channelFunds.value()));
569 BEAST_EXPECT(
channelBalance(*env.current(), chan) == channelFunds);
570 BEAST_EXPECT(env.balance(bob) == preBob + channelFunds);
572 auto const preAlice = env.balance(alice);
576 auto const feeDrops = env.current()->fees().base;
577 BEAST_EXPECT(env.balance(alice) == preAlice - feeDrops);
587 Env env{*
this, features};
588 auto const alice =
Account(
"alice");
589 auto const bob =
Account(
"bob");
590 env.fund(
XRP(10000), alice, bob);
591 auto const pk = alice.pk();
592 auto const settleDelay = 3600s;
593 auto const channelFunds =
XRP(1000);
594 auto const chan =
channel(alice, bob, env.seq(alice));
595 env(
create(alice, bob, channelFunds, settleDelay, pk));
603 auto const preBob = env.balance(bob);
605 auto const delta =
XRP(500);
606 auto const reqBal = chanBal + delta;
607 assert(reqBal <= chanAmt);
612 auto const feeDrops = env.current()->fees().base;
613 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
620 auto const preBob = env.balance(bob);
622 auto const delta =
XRP(500);
623 auto const reqBal = chanBal + delta;
624 assert(reqBal <= chanAmt);
629 auto const feeDrops = env.current()->fees().base;
630 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
643 auto const alice =
Account(
"alice");
644 auto const bob =
Account(
"bob");
648 Env env{*
this, features};
649 env.fund(
XRP(10000), alice, bob);
651 auto const chan =
channel(alice, bob, env.seq(alice));
652 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
660 Env env{*
this, features};
661 env.fund(
XRP(10000), alice, bob);
662 auto const chan =
channel(alice, bob, env.seq(alice));
663 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
667 auto const reqBal =
XRP(500).value();
668 env(
claim(alice, chan, reqBal, reqBal));
680 Env env{*
this, features};
681 auto const alice =
Account(
"alice");
682 auto const bob =
Account(
"bob");
683 env.fund(
XRP(10000), alice, bob);
685 auto const pk = alice.pk();
686 auto const settleDelay = 3600s;
687 auto const channelFunds =
XRP(1000);
689 auto const chan =
channel(alice, bob, env.seq(alice));
690 env(
create(alice, bob, channelFunds, settleDelay, pk),
695 auto const chan =
channel(alice, bob, env.seq(alice));
697 alice, bob, channelFunds, settleDelay, pk,
std::nullopt, 1));
709 auto const alice =
Account(
"alice");
710 auto const bob =
Account(
"bob");
711 auto const carol =
Account(
"carol");
712 auto USDA = alice[
"USD"];
714 Env env{*
this, features};
715 env.fund(
XRP(10000), alice, bob, carol);
720 auto const pk = alice.pk();
721 auto const settleDelay = 100s;
722 auto const chan =
channel(alice, bob, env.seq(alice));
723 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
731 env(
fund(alice, chan,
XRP(1000)));
735 env(
claim(alice, chan,
XRP(500).value(),
XRP(500).value()),
740 auto const baseFee = env.current()->fees().base;
741 auto const preBob = env.balance(bob);
743 auto const delta =
XRP(500).value();
751 BEAST_EXPECT(env.balance(bob) == preBob);
763 BEAST_EXPECT(env.balance(bob) == preBob + delta - baseFee);
767 auto const delta =
XRP(600).value();
799 env.balance(bob) == preBob + delta - (3 * baseFee));
804 auto const delta =
XRP(800).value();
818 env(
claim(alice, chan, delta, delta));
821 env.balance(bob) == preBob +
XRP(800) - (5 * baseFee));
829 testcase(
"Deposit Authorization with Credentials");
833 char const credType[] =
"abcde";
838 Account const dillon(
"dillon");
843 env.
fund(
XRP(10000), alice, bob, carol, dillon, zelda);
845 auto const pk = alice.
pk();
846 auto const settleDelay = 100s;
847 auto const chan =
channel(alice, bob, env.seq(alice));
848 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
852 env(
fund(alice, chan,
XRP(1000)));
856 "D007AE4B6E1274B4AF872588267B810C2F82716726351D1C7D38D3E5499FC6"
859 auto const delta =
XRP(500).value();
865 .parentCloseTime.time_since_epoch()
868 jv[sfExpiration.jsonName] = t;
875 std::string const credIdx = jv[jss::result][jss::index].asString();
882 env(
claim(alice, chan, delta, delta),
891 env(
claim(alice, chan, delta, delta),
901 env(
claim(dillon, chan, delta, delta),
909 env(
claim(alice, chan, delta, delta),
914 env(
claim(alice, chan, delta, delta),
922 for (
int i = 0; i < 10; ++i)
925 env(
claim(alice, chan, delta, delta),
940 jv[jss::result][jss::index].asString();
943 env(
claim(alice, chan, delta, delta),
950 env.
fund(
XRP(10000), alice, bob, carol, dillon, zelda);
952 auto const pk = alice.
pk();
953 auto const settleDelay = 100s;
954 auto const chan =
channel(alice, bob, env.seq(alice));
955 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
959 env(
fund(alice, chan,
XRP(1000)));
962 auto const delta =
XRP(500).value();
973 std::string const credIdx = jv[jss::result][jss::index].asString();
983 env.
fund(
XRP(5000),
"alice",
"bob");
986 auto const pk = alice.
pk();
987 auto const settleDelay = 100s;
988 auto const chan =
channel(alice, bob, env.
seq(alice));
989 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
992 env(
fund(alice, chan,
XRP(1000)));
995 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
1004 env(
claim(alice, chan,
XRP(500).value(),
XRP(500).value()),
1014 testcase(
"Multiple channels to the same account");
1015 using namespace jtx;
1017 Env env{*
this, features};
1018 auto const alice =
Account(
"alice");
1019 auto const bob =
Account(
"bob");
1020 env.fund(
XRP(10000), alice, bob);
1021 auto const pk = alice.pk();
1022 auto const settleDelay = 3600s;
1023 auto const channelFunds =
XRP(1000);
1024 auto const chan1 =
channel(alice, bob, env.seq(alice));
1025 env(
create(alice, bob, channelFunds, settleDelay, pk));
1027 auto const chan2 =
channel(alice, bob, env.seq(alice));
1028 env(
create(alice, bob, channelFunds, settleDelay, pk));
1030 BEAST_EXPECT(chan1 != chan2);
1038 using namespace jtx;
1040 Env env{*
this, features};
1041 auto const alice =
Account(
"alice");
1042 auto const bob =
Account(
"bob");
1044 env.fund(
XRP(10000), alice, bob, charlie);
1045 auto const pk = alice.pk();
1046 auto const settleDelay = 3600s;
1047 auto const channelFunds =
XRP(1000);
1049 env(
create(alice, bob, channelFunds, settleDelay, pk));
1053 auto testInvalidAccountParam = [&](
auto const& param) {
1055 params[jss::account] = param;
1057 "json",
"account_channels",
to_string(params))[jss::result];
1058 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1060 jrr[jss::error_message] ==
"Invalid field 'account'.");
1063 testInvalidAccountParam(1);
1064 testInvalidAccountParam(1.1);
1065 testInvalidAccountParam(
true);
1072 env.rpc(
"account_channels", alice.human(), bob.human());
1073 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1075 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1076 BEAST_EXPECT(r[jss::result][jss::validated]);
1079 auto const r = env.rpc(
"account_channels", alice.human());
1080 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1082 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1083 BEAST_EXPECT(r[jss::result][jss::validated]);
1087 env.rpc(
"account_channels", bob.human(), alice.human());
1088 BEAST_EXPECT(r[jss::result][jss::channels].size() == 0);
1089 BEAST_EXPECT(r[jss::result][jss::validated]);
1092 env(
create(alice, bob, channelFunds, settleDelay, pk));
1096 env.rpc(
"account_channels", alice.human(), bob.human());
1097 BEAST_EXPECT(r[jss::result][jss::channels].size() == 2);
1098 BEAST_EXPECT(r[jss::result][jss::validated]);
1099 BEAST_EXPECT(chan1Str != chan2Str);
1100 for (
auto const& c : {chan1Str, chan2Str})
1102 r[jss::result][jss::channels][0u][jss::channel_id] == c ||
1103 r[jss::result][jss::channels][1u][jss::channel_id] == c);
1110 testcase(
"Account channels RPC markers");
1112 using namespace test::jtx;
1115 auto const alice =
Account(
"alice");
1120 for (
int i = 0; i < n; ++i)
1127 Env env{*
this, features};
1128 env.fund(
XRP(10000), alice);
1129 for (
auto const& a : bobs)
1131 env.fund(
XRP(10000), a);
1137 auto const settleDelay = 3600s;
1138 auto const channelFunds =
XRP(1);
1139 for (
auto const& b : bobs)
1141 env(
create(alice, b, channelFunds, settleDelay, alice.pk()));
1152 jvc[jss::account] = src.human();
1154 jvc[jss::destination_account] = dst->human();
1156 jvc[jss::limit] = *limit;
1158 jvc[jss::marker] = marker;
1161 "json",
"account_channels",
to_string(jvc))[jss::result];
1166 auto const r = testLimit(env, alice);
1167 BEAST_EXPECT(r.isMember(jss::channels));
1168 BEAST_EXPECT(r[jss::channels].size() == bobs.size());
1173 for (
auto const& a : bobs)
1178 for (
int limit = 1; limit < bobs.size() + 1; ++limit)
1180 auto leftToFind = bobsB58;
1181 auto const numFull = bobs.
size() / limit;
1182 auto const numNonFull = bobs.size() % limit ? 1 : 0;
1186 auto const testIt = [&](
bool expectMarker,
int expectedBatchSize) {
1187 auto const r = testLimit(env, alice, limit, marker);
1188 BEAST_EXPECT(!expectMarker || r.isMember(jss::marker));
1189 if (r.isMember(jss::marker))
1190 marker = r[jss::marker];
1191 BEAST_EXPECT(r[jss::channels].size() == expectedBatchSize);
1192 auto const c = r[jss::channels];
1193 auto const s = r[jss::channels].size();
1194 for (
int j = 0; j < s; ++j)
1197 c[j][jss::destination_account].asString();
1198 BEAST_EXPECT(leftToFind.count(dstAcc));
1199 leftToFind.erase(dstAcc);
1203 for (
int i = 0; i < numFull; ++i)
1205 bool const expectMarker = (numNonFull != 0 || i < numFull - 1);
1206 testIt(expectMarker, limit);
1211 testIt(
false, bobs.size() % limit);
1213 BEAST_EXPECT(leftToFind.empty());
1218 auto const r = testLimit(env, alice, 0);
1219 BEAST_EXPECT(r.isMember(jss::error_message));
1228 testcase(
"Account channels RPC owner only");
1230 using namespace test::jtx;
1233 auto const alice =
Account(
"alice");
1234 auto const bob =
Account(
"bob");
1235 Env env{*
this, features};
1236 env.fund(
XRP(10000), alice, bob);
1241 auto const settleDelay = 3600s;
1242 auto const channelFunds =
XRP(1000);
1243 env(
create(alice, bob, channelFunds, settleDelay, alice.pk()));
1244 env(
create(bob, alice, channelFunds, settleDelay, bob.pk()));
1246 auto const r = [&] {
1248 jvc[jss::account] = alice.human();
1251 "json",
"account_channels",
to_string(jvc))[jss::result];
1253 BEAST_EXPECT(r.isMember(jss::channels));
1254 BEAST_EXPECT(r[jss::channels].size() == 1);
1256 r[jss::channels][0u][jss::destination_account].asString() ==
1263 using namespace jtx;
1266 Env env{*
this, features};
1267 auto const alice =
Account(
"alice");
1268 auto const bob =
Account(
"bob");
1270 env.fund(
XRP(10000), alice, bob, charlie);
1271 auto const pk = alice.pk();
1272 auto const settleDelay = 3600s;
1273 auto const channelFunds =
XRP(1000);
1275 env(
create(alice, bob, channelFunds, settleDelay, pk));
1279 args[jss::channel_id] = chan1Str;
1280 args[jss::key_type] =
"ed255191";
1281 args[jss::seed] =
"snHq1rzQoN2qiUkC3XF5RyxBzUtN";
1282 args[jss::amount] = 51110000;
1288 args[jss::api_version] = apiVersion;
1289 auto const rs = env.rpc(
1291 "channel_authorize",
1292 args.toStyledString())[jss::result];
1293 auto const error = apiVersion < 2u ?
"invalidParams" :
"badKeyType";
1294 BEAST_EXPECT(rs[jss::error] == error);
1301 testcase(
"PayChan Auth/Verify RPC");
1302 using namespace jtx;
1304 Env env{*
this, features};
1305 auto const alice =
Account(
"alice");
1306 auto const bob =
Account(
"bob");
1308 env.fund(
XRP(10000), alice, bob, charlie);
1309 auto const pk = alice.pk();
1310 auto const settleDelay = 3600s;
1311 auto const channelFunds =
XRP(1000);
1313 env(
create(alice, bob, channelFunds, settleDelay, pk));
1318 env.rpc(
"account_channels", alice.human(), bob.human());
1319 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1321 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1322 BEAST_EXPECT(r[jss::result][jss::validated]);
1324 r[jss::result][jss::channels][0u][jss::public_key].asString();
1327 auto const r = env.rpc(
"account_channels", alice.human());
1328 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1330 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1331 BEAST_EXPECT(r[jss::result][jss::validated]);
1333 r[jss::result][jss::channels][0u][jss::public_key].asString();
1337 env.rpc(
"account_channels", bob.human(), alice.human());
1338 BEAST_EXPECT(r[jss::result][jss::channels].size() == 0);
1339 BEAST_EXPECT(r[jss::result][jss::validated]);
1342 env(
create(alice, bob, channelFunds, settleDelay, pk));
1346 env.rpc(
"account_channels", alice.human(), bob.human());
1347 BEAST_EXPECT(r[jss::result][jss::channels].size() == 2);
1348 BEAST_EXPECT(r[jss::result][jss::validated]);
1349 BEAST_EXPECT(chan1Str != chan2Str);
1350 for (
auto const& c : {chan1Str, chan2Str})
1352 r[jss::result][jss::channels][0u][jss::channel_id] == c ||
1353 r[jss::result][jss::channels][1u][jss::channel_id] == c);
1361 s +=
"0123456789ABCDEF"[((
slice[i] & 0xf0) >> 4)];
1362 s +=
"0123456789ABCDEF"[((
slice[i] & 0x0f) >> 0)];
1370 env.rpc(
"channel_authorize",
"alice", chan1Str,
"1000");
1371 auto const sig = rs[jss::result][jss::signature].asString();
1372 BEAST_EXPECT(!
sig.empty());
1374 auto const rv = env.rpc(
1375 "channel_verify", chan1PkStr, chan1Str,
"1000",
sig);
1376 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1383 env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000",
sig);
1384 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1390 env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000x",
sig);
1391 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1392 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000 ",
sig);
1393 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1394 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"x1000",
sig);
1395 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1396 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"x",
sig);
1397 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1398 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
" ",
sig);
1399 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1401 "channel_verify", pkAsHex, chan1Str,
"1000 1000",
sig);
1402 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1403 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1,000",
sig);
1404 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1405 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
" 1000",
sig);
1406 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1407 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"",
sig);
1408 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1413 auto chan1StrBad = chan1Str;
1414 chan1StrBad.pop_back();
1416 "channel_verify", pkAsHex, chan1StrBad,
"1000",
sig);
1417 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1418 rv = env.rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1419 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1421 chan1StrBad = chan1Str;
1422 chan1StrBad.push_back(
'0');
1424 "channel_verify", pkAsHex, chan1StrBad,
"1000",
sig);
1425 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1426 rv = env.rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1427 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1429 chan1StrBad = chan1Str;
1430 chan1StrBad.back() =
'x';
1432 "channel_verify", pkAsHex, chan1StrBad,
"1000",
sig);
1433 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1434 rv = env.rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1435 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1439 auto illFormedPk = chan1PkStr.
substr(0, chan1PkStr.
size() - 1);
1440 auto const rv = env.rpc(
1441 "channel_verify", illFormedPk, chan1Str,
"1000",
sig);
1443 !rv[jss::result][jss::signature_verified].asBool());
1448 auto illFormedPk = pkAsHex.substr(0, chan1PkStr.
size() - 1);
1449 auto const rv = env.rpc(
1450 "channel_verify", illFormedPk, chan1Str,
"1000",
sig);
1452 !rv[jss::result][jss::signature_verified].asBool());
1458 env.rpc(
"channel_authorize",
"alice", chan2Str,
"1000");
1459 auto const sig = rs[jss::result][jss::signature].asString();
1460 BEAST_EXPECT(!
sig.empty());
1462 auto const rv = env.rpc(
1463 "channel_verify", chan1PkStr, chan1Str,
"1000",
sig);
1465 !rv[jss::result][jss::signature_verified].asBool());
1471 env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000",
sig);
1473 !rv[jss::result][jss::signature_verified].asBool());
1481 charlie, alice, channelFunds, settleDelay, charlie.pk()));
1487 env.rpc(
"account_channels", charlie.human(), alice.human());
1488 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1490 r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1491 BEAST_EXPECT(r[jss::result][jss::validated]);
1492 cpk = r[jss::result][jss::channels][0u][jss::public_key]
1498 env.rpc(
"channel_authorize",
"charlie", chan,
"1000");
1499 auto const sig = rs[jss::result][jss::signature].asString();
1500 BEAST_EXPECT(!
sig.empty());
1503 env.rpc(
"channel_verify", cpk, chan,
"1000",
sig);
1505 !rv[jss::result][jss::signature_verified].asBool());
1510 env.rpc(
"channel_authorize",
"charlie",
"nyx", chan,
"1000");
1511 BEAST_EXPECT(rs1[jss::error] ==
"badKeyType");
1515 auto const rs2 = env.rpc(
1516 "channel_authorize",
"charlie",
"secp256k1", chan,
"1000");
1517 auto const sig2 = rs2[jss::result][jss::signature].asString();
1518 BEAST_EXPECT(!sig2.empty());
1521 env.rpc(
"channel_verify", cpk, chan,
"1000", sig2);
1523 !rv[jss::result][jss::signature_verified].asBool());
1527 auto const rs3 = env.rpc(
1528 "channel_authorize",
"charlie",
"ed25519", chan,
"1000");
1529 auto const sig3 = rs3[jss::result][jss::signature].asString();
1530 BEAST_EXPECT(!sig3.empty());
1533 env.rpc(
"channel_verify", cpk, chan,
"1000", sig3);
1534 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1540 auto rs = env.rpc(
"channel_authorize",
"alice", chan1Str,
"1000x");
1541 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1542 rs = env.rpc(
"channel_authorize",
"alice", chan1Str,
"x1000");
1543 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1544 rs = env.rpc(
"channel_authorize",
"alice", chan1Str,
"x");
1545 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1549 args[jss::amount] =
"2000";
1550 args[jss::key_type] =
"secp256k1";
1551 args[jss::passphrase] =
"passphrase_can_be_anything";
1554 "channel_authorize",
1555 args.toStyledString())[jss::result];
1556 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1561 args[jss::channel_id] = chan1Str;
1562 args[jss::key_type] =
"secp256k1";
1563 args[jss::passphrase] =
"passphrase_can_be_anything";
1566 "channel_authorize",
1567 args.toStyledString())[jss::result];
1568 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1573 args[jss::amount] =
"2000";
1574 args[jss::channel_id] = chan1Str;
1575 args[jss::passphrase] =
"passphrase_can_be_anything";
1578 "channel_authorize",
1579 args.toStyledString())[jss::result];
1580 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1585 args[jss::amount] =
"2000";
1586 args[jss::channel_id] = chan1Str;
1587 args[jss::key_type] =
"secp256k1";
1588 args[jss::passphrase] =
"passphrase_can_be_anything";
1589 args[jss::seed] =
"seed can be anything";
1592 "channel_authorize",
1593 args.toStyledString())[jss::result];
1594 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1599 args[jss::amount] =
"2000";
1600 args[jss::channel_id] = chan1Str +
"1";
1601 args[jss::key_type] =
"secp256k1";
1602 args[jss::passphrase] =
"passphrase_can_be_anything";
1605 "channel_authorize",
1606 args.toStyledString())[jss::result];
1607 BEAST_EXPECT(rs[jss::error] ==
"channelMalformed");
1612 args[jss::amount] = 2000;
1613 args[jss::channel_id] = chan1Str;
1614 args[jss::key_type] =
"secp256k1";
1615 args[jss::passphrase] =
"passphrase_can_be_anything";
1618 "channel_authorize",
1619 args.toStyledString())[jss::result];
1620 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1625 args[jss::amount] =
"TwoThousand";
1626 args[jss::channel_id] = chan1Str;
1627 args[jss::key_type] =
"secp256k1";
1628 args[jss::passphrase] =
"passphrase_can_be_anything";
1631 "channel_authorize",
1632 args.toStyledString())[jss::result];
1633 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1642 using namespace jtx;
1644 Env env{*
this, features};
1645 auto const alice =
Account(
"alice");
1646 auto const bob =
Account(
"bob");
1647 auto const carol =
Account(
"carol");
1648 auto const dan =
Account(
"dan");
1649 env.fund(
XRP(10000), alice, bob, carol, dan);
1650 auto const pk = alice.pk();
1651 auto const settleDelay = 3600s;
1652 auto const channelFunds =
XRP(1000);
1658 env(
create(alice, bob, channelFunds, settleDelay, pk));
1660 env.rpc(
"account_channels", alice.human(), bob.human());
1661 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1663 r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1664 BEAST_EXPECT(!r[jss::result][jss::channels][0u].isMember(
1665 jss::destination_tag));
1679 env.rpc(
"account_channels", alice.human(), carol.human());
1680 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1682 r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1684 r[jss::result][jss::channels][0u][jss::destination_tag] ==
1693 using namespace jtx;
1695 Env env{*
this, features};
1696 auto const alice =
Account(
"alice");
1697 auto const bob =
Account(
"bob");
1698 auto USDA = alice[
"USD"];
1699 env.fund(
XRP(10000), alice, bob);
1700 auto const pk = alice.pk();
1701 auto const settleDelay = 100s;
1703 auto const chan =
channel(alice, bob, env.seq(alice));
1704 auto jv =
create(alice, bob,
XRP(1000), settleDelay, pk);
1705 auto const pkHex =
strHex(pk.slice());
1706 jv[
"PublicKey"] = pkHex.substr(2, pkHex.size() - 2);
1708 jv[
"PublicKey"] = pkHex.substr(0, pkHex.size() - 2);
1710 auto badPrefix = pkHex;
1713 jv[
"PublicKey"] = badPrefix;
1716 jv[
"PublicKey"] = pkHex;
1719 auto const authAmt =
XRP(100);
1728 jv[
"PublicKey"] = pkHex.substr(2, pkHex.size() - 2);
1730 jv[
"PublicKey"] = pkHex.substr(0, pkHex.size() - 2);
1735 jv[
"PublicKey"] = badPrefix;
1739 jv.removeMember(
"PublicKey");
1743 auto const txn = R
"*(
1746 "channel_id":"5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
1748 "304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064",
1750 "aKijDDiC2q2gXjMpM7i4BUS6cmixgsEe18e7CjsUxwihKfuoFgS5",
1754 auto const r = env.rpc(
"json",
"channel_verify", txn);
1755 BEAST_EXPECT(r[
"result"][
"error"] ==
"publicMalformed");
1764 using namespace jtx;
1767 auto const alice =
Account(
"alice");
1768 auto const bob =
Account(
"bob");
1769 auto const settleDelay = 100s;
1770 auto const pk = alice.pk();
1772 auto inOwnerDir = [](
ReadView const& view,
1776 return std::find(ownerDir.begin(), ownerDir.end(), chan) !=
1780 auto ownerDirCount = [](
ReadView const& view,
1788 Env env{*
this, features};
1789 env.fund(
XRP(10000), alice, bob);
1790 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1792 auto const [chan, chanSle] =
1794 BEAST_EXPECT(inOwnerDir(*env.current(), alice, chanSle));
1795 BEAST_EXPECT(ownerDirCount(*env.current(), alice) == 1);
1796 BEAST_EXPECT(inOwnerDir(*env.current(), bob, chanSle));
1797 BEAST_EXPECT(ownerDirCount(*env.current(), bob) == 1);
1801 BEAST_EXPECT(!inOwnerDir(*env.current(), alice, chanSle));
1802 BEAST_EXPECT(ownerDirCount(*env.current(), alice) == 0);
1803 BEAST_EXPECT(!inOwnerDir(*env.current(), bob, chanSle));
1804 BEAST_EXPECT(ownerDirCount(*env.current(), bob) == 0);
1810 Env env(*
this, features);
1811 env.
fund(
XRP(10000), alice, bob);
1813 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1815 auto const [chan, chanSle] =
1817 BEAST_EXPECT(inOwnerDir(*env.
current(), alice, chanSle));
1818 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 1);
1819 BEAST_EXPECT(inOwnerDir(*env.
current(), bob, chanSle));
1820 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 1);
1824 BEAST_EXPECT(!inOwnerDir(*env.
current(), alice, chanSle));
1825 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 0);
1826 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1827 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1835 using namespace test::jtx;
1837 auto rmAccount = [
this](
1844 for (
auto minRmSeq = env.
seq(toRm) + 257;
1845 env.
current()->seq() < minRmSeq;
1859 auto const alice =
Account(
"alice");
1860 auto const bob =
Account(
"bob");
1861 auto const carol =
Account(
"carol");
1864 Env env{*
this, features};
1865 env.
fund(
XRP(10000), alice, bob, carol);
1869 auto const pk = alice.pk();
1870 auto const settleDelay = 100s;
1871 auto const chan =
channel(alice, bob, env.
seq(alice));
1872 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1880 auto const feeDrops = env.
current()->fees().base;
1883 BEAST_EXPECT(chanBal ==
XRP(0));
1884 BEAST_EXPECT(chanAmt ==
XRP(1000));
1886 auto preBob = env.
balance(bob);
1887 auto const delta =
XRP(50);
1888 auto reqBal = chanBal + delta;
1889 auto authAmt = reqBal +
XRP(100);
1890 assert(reqBal <= chanAmt);
1892 env(
claim(alice, chan, reqBal, authAmt));
1896 BEAST_EXPECT(env.
balance(bob) == preBob + delta);
1899 auto const preAlice = env.
balance(alice);
1900 env(
fund(alice, chan,
XRP(1000)));
1902 BEAST_EXPECT(env.
balance(alice) == preAlice -
XRP(1000) - feeDrops);
1905 chanAmt = chanAmt +
XRP(1000);
1913 auto const closeTime = env.
current()->info().parentCloseTime;
1914 auto const minExpiration = closeTime + settleDelay;
1915 env.
close(minExpiration);
1926 using namespace jtx;
1928 Env env{*
this, features};
1929 auto const alice =
Account(
"alice");
1930 auto const bob =
Account(
"bob");
1931 auto USDA = alice[
"USD"];
1932 env.fund(
XRP(10000), alice, bob);
1945 auto const pk = alice.pk();
1946 auto const settleDelay = 100s;
1947 auto const chan =
channel(alice, bob, aliceTicketSeq);
1949 env(
create(alice, bob,
XRP(1000), settleDelay, pk),
1952 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1953 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1959 auto const preAlice = env.balance(alice);
1962 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1963 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1965 auto const feeDrops = env.current()->fees().base;
1966 BEAST_EXPECT(env.balance(alice) == preAlice -
XRP(1000) - feeDrops);
1971 BEAST_EXPECT(chanBal ==
XRP(0));
1972 BEAST_EXPECT(chanAmt ==
XRP(2000));
1976 auto const preBob = env.balance(bob);
1977 auto const delta =
XRP(500);
1978 auto const reqBal = chanBal + delta;
1979 auto const authAmt = reqBal +
XRP(100);
1980 assert(reqBal <= chanAmt);
1981 env(
claim(alice, chan, reqBal, authAmt),
1984 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1985 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1988 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
1989 BEAST_EXPECT(env.balance(bob) == preBob + delta);
1994 auto preBob = env.balance(bob);
1995 auto const delta =
XRP(500);
1996 auto const reqBal = chanBal + delta;
1997 auto const authAmt = reqBal +
XRP(100);
1998 assert(reqBal <= chanAmt);
2001 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()),
2004 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2005 BEAST_EXPECT(env.seq(bob) == bobSeq);
2008 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
2009 auto const feeDrops = env.current()->fees().base;
2010 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
2014 preBob = env.balance(bob);
2016 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()),
2020 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2021 BEAST_EXPECT(env.seq(bob) == bobSeq);
2024 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
2025 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
2029 auto const preBob = env.balance(bob);
2032 assert(reqAmt <= chanAmt);
2037 env(
claim(bob, chan, reqAmt, authAmt,
Slice(
sig), alice.pk()),
2041 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2042 BEAST_EXPECT(env.seq(bob) == bobSeq);
2045 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
2046 BEAST_EXPECT(env.balance(bob) == preBob);
2050 env(
fund(bob, chan,
XRP(1000)),
2054 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2055 BEAST_EXPECT(env.seq(bob) == bobSeq);
2058 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
2062 auto const preAlice = env.balance(alice);
2063 auto const preBob = env.balance(bob);
2064 env(
claim(bob, chan),
2068 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2069 BEAST_EXPECT(env.seq(bob) == bobSeq);
2072 auto const feeDrops = env.current()->fees().base;
2073 auto const delta = chanAmt - chanBal;
2074 assert(delta > beast::zero);
2075 BEAST_EXPECT(env.balance(alice) == preAlice + delta);
2076 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
2078 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
2079 BEAST_EXPECT(env.seq(alice) == aliceSeq);
2080 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2081 BEAST_EXPECT(env.seq(bob) == bobSeq);
2114 using namespace test::jtx;
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.
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
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 account(AccountID const &id) noexcept
AccountID root.
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.
Json::Value create(jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
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 unauth(Account const &account, Account const &unauth)
Remove preauthorization for deposit.
Json::Value auth(Account const &account, Account const &auth)
Preauthorize for deposit.
Json::Value authCredentials(jtx::Account const &account, std::vector< AuthorizeCredentials > const &auth)
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)
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)
STAmount channelBalance(ReadView const &view, uint256 const &chan)
Json::Value create(Account const &account, std::uint32_t count)
Create one of more tickets.
Json::Value fclear(Account const &account, std::uint32_t off)
Remove account flag.
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
void fund(jtx::Env &env, jtx::Account const &gw, std::vector< jtx::Account > const &accounts, std::vector< STAmount > const &amts, Fund how)
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 acctdelete(Account const &account, Account const &dest)
Delete account.
owner_count< ltTICKET > tickets
Match the number of tickets on the account.
XRP_t const XRP
Converts to XRP Issue or STAmount.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::uint32_t asfDepositAuth
constexpr std::uint32_t asfRequireDest
constexpr std::uint32_t tfRenew
static std::string sliceToHex(Slice const &slice)
void serializePayChanAuthorization(Serializer &msg, uint256 const &key, XRPAmount const &amt)
std::string strHex(FwdIt begin, FwdIt end)
void forAllApiVersions(Fn const &fn, Args &&... args)
bool isTesSuccess(TER x) noexcept
std::string to_string(base_uint< Bits, Tag > const &a)
constexpr std::uint32_t asfDisallowIncomingPayChan
constexpr std::uint32_t tfClose
TERSubset< CanCvtToTER > TER
constexpr std::uint32_t asfDisallowXRP
static std::pair< uint256, std::shared_ptr< SLE const > > channelKeyAndSle(ReadView const &view, jtx::Account const &account, jtx::Account const &dst)
void testSimple(FeatureBitset features)
void testMultiple(FeatureBitset features)
void testAccountChannelsRPC(FeatureBitset features)
void testUsingTickets(FeatureBitset features)
void run() override
Runs the suite.
void testSettleDelay(FeatureBitset features)
void testDisallowXRP(FeatureBitset features)
void testDepositAuth(FeatureBitset features)
static std::optional< std::int64_t > channelExpiration(ReadView const &view, uint256 const &chan)
void testAccountDelete(FeatureBitset features)
void testCloseDry(FeatureBitset features)
void testExpiration(FeatureBitset features)
void testMetaAndOwnership(FeatureBitset features)
void testDefaultAmount(FeatureBitset features)
void testAuthVerifyRPC(FeatureBitset features)
void testMalformedPK(FeatureBitset features)
void testCancelAfter(FeatureBitset features)
void testWithFeats(FeatureBitset features)
void testDisallowIncoming(FeatureBitset features)
void testAccountChannelsRPCMarkers(FeatureBitset features)
void testAccountChannelAuthorize(FeatureBitset features)
void testAccountChannelsRPCSenderOnly(FeatureBitset features)
void testDstTag(FeatureBitset features)
static STAmount channelAmount(ReadView const &view, uint256 const &chan)
void testDepositAuthCreds()
static Buffer signClaimAuth(PublicKey const &pk, SecretKey const &sk, uint256 const &channel, STAmount const &authAmt)
void testOptionalFields(FeatureBitset features)