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;
29 return {k.key, view.
read(k)};
47 auto const slep = view.
read({ltPAYCHAN, chan});
50 return (*slep)[sfAmount];
56 auto const slep = view.
read({ltPAYCHAN, chan});
59 if (
auto const r = (*slep)[~sfExpiration])
70 Env env{*
this, features};
71 auto const alice =
Account(
"alice");
72 auto const bob =
Account(
"bob");
73 auto USDA = alice[
"USD"];
74 env.fund(
XRP(10000), alice, bob);
75 auto const pk = alice.pk();
76 auto const settleDelay = 100s;
77 auto const chan =
channel(alice, bob, env.seq(alice));
78 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
83 auto const preAlice = env.balance(alice);
84 env(
fund(alice, chan,
XRP(1000)));
85 auto const feeDrops = env.current()->fees().base;
86 BEAST_EXPECT(env.balance(alice) == preAlice -
XRP(1000) - feeDrops);
91 BEAST_EXPECT(chanBal ==
XRP(0));
92 BEAST_EXPECT(chanAmt ==
XRP(2000));
96 env(
create(alice, bob, USDA(1000), settleDelay, pk),
99 env(
create(alice, bob,
XRP(-1000), settleDelay, pk),
105 env(
create(alice,
"noAccount",
XRP(1000), settleDelay, pk),
108 env(
create(alice, alice,
XRP(1000), settleDelay, pk),
114 channel(alice,
"noAccount", env.seq(alice) - 1),
122 auto const iou = USDA(100).value();
123 auto const negXRP =
XRP(-100).value();
124 auto const posXRP =
XRP(100).value();
134 auto const delta =
XRP(500);
135 auto const reqBal = chanBal + delta;
136 auto const authAmt = reqBal +
XRP(-100);
137 assert(reqBal <= chanAmt);
142 auto const preBob = env.balance(bob);
143 auto const delta =
XRP(500);
144 auto const reqBal = chanBal + delta;
145 auto const authAmt = reqBal +
XRP(100);
146 assert(reqBal <= chanAmt);
147 env(
claim(alice, chan, reqBal, authAmt));
149 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
150 BEAST_EXPECT(env.balance(bob) == preBob + delta);
155 auto preBob = env.balance(bob);
156 auto const delta =
XRP(500);
157 auto const reqBal = chanBal + delta;
158 auto const authAmt = reqBal +
XRP(100);
159 assert(reqBal <= chanAmt);
162 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
164 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
165 auto const feeDrops = env.current()->fees().base;
166 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
170 preBob = env.balance(bob);
171 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()),
174 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
175 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
179 auto const preBob = env.balance(bob);
182 assert(reqAmt <= chanAmt);
185 env(
claim(bob, chan, reqAmt, authAmt,
Slice(
sig), alice.pk()),
188 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
189 BEAST_EXPECT(env.balance(bob) == preBob);
195 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
209 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
223 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
227 auto const preAlice = env.balance(alice);
228 auto const preBob = env.balance(bob);
231 auto const feeDrops = env.current()->fees().base;
232 auto const delta = chanAmt - chanBal;
233 assert(delta > beast::zero);
234 BEAST_EXPECT(env.balance(alice) == preAlice + delta);
235 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
249 env.fund(
XRP(10000), alice);
252 auto const sle = env.le(alice);
259 auto const alice =
Account(
"alice");
260 auto const bob =
Account(
"bob");
261 auto const cho =
Account(
"cho");
262 env.fund(
XRP(10000), alice, bob, cho);
263 auto const pk = alice.pk();
264 auto const settleDelay = 100s;
272 auto const chan =
channel(alice, bob, env.seq(alice));
273 env(
create(alice, bob,
XRP(1000), settleDelay, pk),
284 auto const chan =
channel(bob, alice, env.seq(bob));
285 env(
create(bob, alice,
XRP(1000), settleDelay, pk),
296 auto const chan =
channel(alice, bob, env.seq(alice));
297 env(
create(alice, bob,
XRP(1000), settleDelay, pk),
304 auto const chan =
channel(cho, alice, env.seq(cho));
305 env(
create(cho, alice,
XRP(1000), settleDelay, pk),
316 auto const chan =
channel(cho, alice, env.seq(cho));
317 env(
create(cho, alice,
XRP(1000), settleDelay, pk),
329 auto const alice =
Account(
"alice");
330 auto const bob =
Account(
"bob");
331 auto const carol =
Account(
"carol");
334 Env env{*
this, features};
335 env.fund(
XRP(10000), alice, bob);
336 auto const pk = alice.pk();
337 auto const settleDelay = 100s;
339 env.current()->info().parentCloseTime + 3600s;
340 auto const channelFunds =
XRP(1000);
341 auto const chan =
channel(alice, bob, env.seq(alice));
342 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
344 env.close(cancelAfter);
349 auto preAlice = env.balance(alice);
350 auto preBob = env.balance(bob);
351 auto const delta =
XRP(500);
352 auto const reqBal = chanBal + delta;
353 auto const authAmt = reqBal +
XRP(100);
354 assert(reqBal <= chanAmt);
357 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
358 auto const feeDrops = env.current()->fees().base;
360 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
361 BEAST_EXPECT(env.balance(alice) == preAlice + channelFunds);
366 Env env{*
this, features};
367 env.fund(
XRP(10000), alice, bob, carol);
368 auto const pk = alice.pk();
369 auto const settleDelay = 100s;
371 env.current()->info().parentCloseTime + 3600s;
372 auto const channelFunds =
XRP(1000);
373 auto const chan =
channel(alice, bob, env.seq(alice));
374 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
379 env.close(cancelAfter);
381 auto const preAlice = env.balance(alice);
384 BEAST_EXPECT(env.balance(alice) == preAlice + channelFunds);
389 for (
bool const withFixPayChan : {
true,
false})
391 auto const amend = withFixPayChan
393 : features - fixPayChanCancelAfter;
394 Env env{*
this, amend};
395 env.
fund(
XRP(10000), alice, bob);
398 auto const pk = alice.pk();
399 auto const settleDelay = 100s;
400 auto const channelFunds =
XRP(1000);
402 env.current()->info().parentCloseTime - 1s;
403 auto const txResult =
406 alice, bob, channelFunds, settleDelay, pk, cancelAfter),
413 for (
bool const withFixPayChan : {
true,
false})
415 auto const amend = withFixPayChan
417 : features - fixPayChanCancelAfter;
418 Env env{*
this, amend};
419 env.
fund(
XRP(10000), alice, bob);
422 auto const pk = alice.pk();
423 auto const settleDelay = 100s;
424 auto const channelFunds =
XRP(1000);
426 env.current()->info().parentCloseTime;
428 alice, bob, channelFunds, settleDelay, pk, cancelAfter),
440 Env env{*
this, features};
441 auto const alice =
Account(
"alice");
442 auto const bob =
Account(
"bob");
443 auto const carol =
Account(
"carol");
444 env.fund(
XRP(10000), alice, bob, carol);
445 auto const pk = alice.pk();
446 auto const settleDelay = 3600s;
447 auto const closeTime = env.current()->info().parentCloseTime;
448 auto const minExpiration = closeTime + settleDelay;
450 auto const channelFunds =
XRP(1000);
451 auto const chan =
channel(alice, bob, env.seq(alice));
452 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
457 auto counts = [](
auto const& t) {
458 return t.time_since_epoch().count();
467 counts(minExpiration) + 100);
473 counts(minExpiration) + 50);
480 counts(minExpiration) + 50);
484 counts(minExpiration) + 50);
493 env.close(minExpiration);
506 Env env{*
this, features};
507 auto const alice =
Account(
"alice");
508 auto const bob =
Account(
"bob");
509 env.fund(
XRP(10000), alice, bob);
510 auto const pk = alice.pk();
511 auto const settleDelay = 3600s;
513 env.current()->info().parentCloseTime + settleDelay;
514 auto const channelFunds =
XRP(1000);
515 auto const chan =
channel(alice, bob, env.seq(alice));
516 env(
create(alice, bob, channelFunds, settleDelay, pk));
521 env.close(settleTimepoint - settleDelay / 2);
526 auto preBob = env.balance(bob);
527 auto const delta =
XRP(500);
528 auto const reqBal = chanBal + delta;
529 auto const authAmt = reqBal +
XRP(100);
530 assert(reqBal <= chanAmt);
533 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
535 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
536 auto const feeDrops = env.current()->fees().base;
537 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
539 env.close(settleTimepoint);
544 auto const preAlice = env.balance(alice);
545 auto preBob = env.balance(bob);
546 auto const delta =
XRP(500);
547 auto const reqBal = chanBal + delta;
548 auto const authAmt = reqBal +
XRP(100);
549 assert(reqBal <= chanAmt);
552 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()));
554 auto const feeDrops = env.current()->fees().base;
555 BEAST_EXPECT(env.balance(alice) == preAlice + chanAmt - chanBal);
556 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
566 Env env{*
this, features};
567 auto const alice =
Account(
"alice");
568 auto const bob =
Account(
"bob");
569 env.fund(
XRP(10000), alice, bob);
570 auto const pk = alice.pk();
571 auto const settleDelay = 3600s;
572 auto const channelFunds =
XRP(1000);
573 auto const chan =
channel(alice, bob, env.seq(alice));
574 env(
create(alice, bob, channelFunds, settleDelay, pk));
581 auto const preBob = env.balance(bob);
582 env(
claim(alice, chan, channelFunds.value(), channelFunds.value()));
583 BEAST_EXPECT(
channelBalance(*env.current(), chan) == channelFunds);
584 BEAST_EXPECT(env.balance(bob) == preBob + channelFunds);
586 auto const preAlice = env.balance(alice);
590 auto const feeDrops = env.current()->fees().base;
591 BEAST_EXPECT(env.balance(alice) == preAlice - feeDrops);
601 Env env{*
this, features};
602 auto const alice =
Account(
"alice");
603 auto const bob =
Account(
"bob");
604 env.fund(
XRP(10000), alice, bob);
605 auto const pk = alice.pk();
606 auto const settleDelay = 3600s;
607 auto const channelFunds =
XRP(1000);
608 auto const chan =
channel(alice, bob, env.seq(alice));
609 env(
create(alice, bob, channelFunds, settleDelay, pk));
617 auto const preBob = env.balance(bob);
619 auto const delta =
XRP(500);
620 auto const reqBal = chanBal + delta;
621 assert(reqBal <= chanAmt);
626 auto const feeDrops = env.current()->fees().base;
627 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
634 auto const preBob = env.balance(bob);
636 auto const delta =
XRP(500);
637 auto const reqBal = chanBal + delta;
638 assert(reqBal <= chanAmt);
643 auto const feeDrops = env.current()->fees().base;
644 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
657 auto const alice =
Account(
"alice");
658 auto const bob =
Account(
"bob");
662 Env env{*
this, features};
663 env.fund(
XRP(10000), alice, bob);
665 auto const chan =
channel(alice, bob, env.seq(alice));
666 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
674 Env env{*
this, features};
675 env.fund(
XRP(10000), alice, bob);
676 auto const chan =
channel(alice, bob, env.seq(alice));
677 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
681 auto const reqBal =
XRP(500).value();
682 env(
claim(alice, chan, reqBal, reqBal));
694 Env env{*
this, features};
695 auto const alice =
Account(
"alice");
696 auto const bob =
Account(
"bob");
697 env.fund(
XRP(10000), alice, bob);
699 auto const pk = alice.pk();
700 auto const settleDelay = 3600s;
701 auto const channelFunds =
XRP(1000);
703 auto const chan =
channel(alice, bob, env.seq(alice));
704 env(
create(alice, bob, channelFunds, settleDelay, pk),
709 auto const chan =
channel(alice, bob, env.seq(alice));
711 alice, bob, channelFunds, settleDelay, pk,
std::nullopt, 1));
723 auto const alice =
Account(
"alice");
724 auto const bob =
Account(
"bob");
725 auto const carol =
Account(
"carol");
726 auto USDA = alice[
"USD"];
728 Env env{*
this, features};
729 env.fund(
XRP(10000), alice, bob, carol);
734 auto const pk = alice.pk();
735 auto const settleDelay = 100s;
736 auto const chan =
channel(alice, bob, env.seq(alice));
737 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
745 env(
fund(alice, chan,
XRP(1000)));
749 env(
claim(alice, chan,
XRP(500).value(),
XRP(500).value()),
754 auto const baseFee = env.current()->fees().base;
755 auto const preBob = env.balance(bob);
757 auto const delta =
XRP(500).value();
765 BEAST_EXPECT(env.balance(bob) == preBob);
777 BEAST_EXPECT(env.balance(bob) == preBob + delta - baseFee);
781 auto const delta =
XRP(600).value();
813 env.balance(bob) == preBob + delta - (3 * baseFee));
818 auto const delta =
XRP(800).value();
832 env(
claim(alice, chan, delta, delta));
835 env.balance(bob) == preBob +
XRP(800) - (5 * baseFee));
843 testcase(
"Deposit Authorization with Credentials");
847 char const credType[] =
"abcde";
852 Account const dillon(
"dillon");
857 env.
fund(
XRP(10000), alice, bob, carol, dillon, zelda);
859 auto const pk = alice.
pk();
860 auto const settleDelay = 100s;
861 auto const chan =
channel(alice, bob, env.seq(alice));
862 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
866 env(
fund(alice, chan,
XRP(1000)));
870 "D007AE4B6E1274B4AF872588267B810C2F82716726351D1C7D38D3E5499FC6"
873 auto const delta =
XRP(500).value();
879 .parentCloseTime.time_since_epoch()
882 jv[sfExpiration.jsonName] = t;
889 std::string const credIdx = jv[jss::result][jss::index].asString();
896 env(
claim(alice, chan, delta, delta),
905 env(
claim(alice, chan, delta, delta),
915 env(
claim(dillon, chan, delta, delta),
923 env(
claim(alice, chan, delta, delta),
928 env(
claim(alice, chan, delta, delta),
936 for (
int i = 0; i < 10; ++i)
939 env(
claim(alice, chan, delta, delta),
954 jv[jss::result][jss::index].asString();
957 env(
claim(alice, chan, delta, delta),
964 env.
fund(
XRP(10000), alice, bob, carol, dillon, zelda);
966 auto const pk = alice.
pk();
967 auto const settleDelay = 100s;
968 auto const chan =
channel(alice, bob, env.seq(alice));
969 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
973 env(
fund(alice, chan,
XRP(1000)));
976 auto const delta =
XRP(500).value();
987 std::string const credIdx = jv[jss::result][jss::index].asString();
997 env.
fund(
XRP(5000),
"alice",
"bob");
1000 auto const pk = alice.
pk();
1001 auto const settleDelay = 100s;
1002 auto const chan =
channel(alice, bob, env.
seq(alice));
1003 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1006 env(
fund(alice, chan,
XRP(1000)));
1009 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
1018 env(
claim(alice, chan,
XRP(500).value(),
XRP(500).value()),
1028 testcase(
"Multiple channels to the same account");
1029 using namespace jtx;
1031 Env env{*
this, features};
1032 auto const alice =
Account(
"alice");
1033 auto const bob =
Account(
"bob");
1034 env.fund(
XRP(10000), alice, bob);
1035 auto const pk = alice.pk();
1036 auto const settleDelay = 3600s;
1037 auto const channelFunds =
XRP(1000);
1038 auto const chan1 =
channel(alice, bob, env.seq(alice));
1039 env(
create(alice, bob, channelFunds, settleDelay, pk));
1041 auto const chan2 =
channel(alice, bob, env.seq(alice));
1042 env(
create(alice, bob, channelFunds, settleDelay, pk));
1044 BEAST_EXPECT(chan1 != chan2);
1052 using namespace jtx;
1054 Env env{*
this, features};
1055 auto const alice =
Account(
"alice");
1056 auto const bob =
Account(
"bob");
1058 env.fund(
XRP(10000), alice, bob, charlie);
1059 auto const pk = alice.pk();
1060 auto const settleDelay = 3600s;
1061 auto const channelFunds =
XRP(1000);
1063 env(
create(alice, bob, channelFunds, settleDelay, pk));
1067 auto testInvalidAccountParam = [&](
auto const& param) {
1069 params[jss::account] = param;
1071 "json",
"account_channels",
to_string(params))[jss::result];
1072 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1074 jrr[jss::error_message] ==
"Invalid field 'account'.");
1077 testInvalidAccountParam(1);
1078 testInvalidAccountParam(1.1);
1079 testInvalidAccountParam(
true);
1086 env.rpc(
"account_channels", alice.human(), bob.human());
1087 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1089 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1090 BEAST_EXPECT(r[jss::result][jss::validated]);
1093 auto const r = env.rpc(
"account_channels", alice.human());
1094 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1096 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1097 BEAST_EXPECT(r[jss::result][jss::validated]);
1101 env.rpc(
"account_channels", bob.human(), alice.human());
1102 BEAST_EXPECT(r[jss::result][jss::channels].size() == 0);
1103 BEAST_EXPECT(r[jss::result][jss::validated]);
1106 env(
create(alice, bob, channelFunds, settleDelay, pk));
1110 env.rpc(
"account_channels", alice.human(), bob.human());
1111 BEAST_EXPECT(r[jss::result][jss::channels].size() == 2);
1112 BEAST_EXPECT(r[jss::result][jss::validated]);
1113 BEAST_EXPECT(chan1Str != chan2Str);
1114 for (
auto const& c : {chan1Str, chan2Str})
1116 r[jss::result][jss::channels][0u][jss::channel_id] == c ||
1117 r[jss::result][jss::channels][1u][jss::channel_id] == c);
1124 testcase(
"Account channels RPC markers");
1126 using namespace test::jtx;
1129 auto const alice =
Account(
"alice");
1134 for (
int i = 0; i < n; ++i)
1141 Env env{*
this, features};
1142 env.fund(
XRP(10000), alice);
1143 for (
auto const& a : bobs)
1145 env.fund(
XRP(10000), a);
1151 auto const settleDelay = 3600s;
1152 auto const channelFunds =
XRP(1);
1153 for (
auto const& b : bobs)
1155 env(
create(alice, b, channelFunds, settleDelay, alice.pk()));
1166 jvc[jss::account] = src.human();
1168 jvc[jss::destination_account] = dst->human();
1170 jvc[jss::limit] = *limit;
1172 jvc[jss::marker] = marker;
1175 "json",
"account_channels",
to_string(jvc))[jss::result];
1180 auto const r = testLimit(env, alice);
1181 BEAST_EXPECT(r.isMember(jss::channels));
1182 BEAST_EXPECT(r[jss::channels].size() == bobs.size());
1187 for (
auto const& a : bobs)
1192 for (
int limit = 1; limit < bobs.size() + 1; ++limit)
1194 auto leftToFind = bobsB58;
1195 auto const numFull = bobs.
size() / limit;
1196 auto const numNonFull = bobs.size() % limit ? 1 : 0;
1200 auto const testIt = [&](
bool expectMarker,
int expectedBatchSize) {
1201 auto const r = testLimit(env, alice, limit, marker);
1202 BEAST_EXPECT(!expectMarker || r.isMember(jss::marker));
1203 if (r.isMember(jss::marker))
1204 marker = r[jss::marker];
1205 BEAST_EXPECT(r[jss::channels].size() == expectedBatchSize);
1206 auto const c = r[jss::channels];
1207 auto const s = r[jss::channels].size();
1208 for (
int j = 0; j < s; ++j)
1211 c[j][jss::destination_account].asString();
1212 BEAST_EXPECT(leftToFind.count(dstAcc));
1213 leftToFind.erase(dstAcc);
1217 for (
int i = 0; i < numFull; ++i)
1219 bool const expectMarker = (numNonFull != 0 || i < numFull - 1);
1220 testIt(expectMarker, limit);
1225 testIt(
false, bobs.size() % limit);
1227 BEAST_EXPECT(leftToFind.empty());
1232 auto const r = testLimit(env, alice, 0);
1233 BEAST_EXPECT(r.isMember(jss::error_message));
1242 testcase(
"Account channels RPC owner only");
1244 using namespace test::jtx;
1247 auto const alice =
Account(
"alice");
1248 auto const bob =
Account(
"bob");
1249 Env env{*
this, features};
1250 env.fund(
XRP(10000), alice, bob);
1255 auto const settleDelay = 3600s;
1256 auto const channelFunds =
XRP(1000);
1257 env(
create(alice, bob, channelFunds, settleDelay, alice.pk()));
1258 env(
create(bob, alice, channelFunds, settleDelay, bob.pk()));
1260 auto const r = [&] {
1262 jvc[jss::account] = alice.human();
1265 "json",
"account_channels",
to_string(jvc))[jss::result];
1267 BEAST_EXPECT(r.isMember(jss::channels));
1268 BEAST_EXPECT(r[jss::channels].size() == 1);
1270 r[jss::channels][0u][jss::destination_account].asString() ==
1277 using namespace jtx;
1280 Env env{*
this, features};
1281 auto const alice =
Account(
"alice");
1282 auto const bob =
Account(
"bob");
1284 env.fund(
XRP(10000), alice, bob, charlie);
1285 auto const pk = alice.pk();
1286 auto const settleDelay = 3600s;
1287 auto const channelFunds =
XRP(1000);
1289 env(
create(alice, bob, channelFunds, settleDelay, pk));
1293 args[jss::channel_id] = chan1Str;
1294 args[jss::key_type] =
"ed255191";
1295 args[jss::seed] =
"snHq1rzQoN2qiUkC3XF5RyxBzUtN";
1296 args[jss::amount] = 51110000;
1302 args[jss::api_version] = apiVersion;
1303 auto const rs = env.rpc(
1305 "channel_authorize",
1306 args.toStyledString())[jss::result];
1307 auto const error = apiVersion < 2u ?
"invalidParams" :
"badKeyType";
1308 BEAST_EXPECT(rs[jss::error] == error);
1315 testcase(
"PayChan Auth/Verify RPC");
1316 using namespace jtx;
1318 Env env{*
this, features};
1319 auto const alice =
Account(
"alice");
1320 auto const bob =
Account(
"bob");
1322 env.fund(
XRP(10000), alice, bob, charlie);
1323 auto const pk = alice.pk();
1324 auto const settleDelay = 3600s;
1325 auto const channelFunds =
XRP(1000);
1327 env(
create(alice, bob, channelFunds, settleDelay, pk));
1332 env.rpc(
"account_channels", alice.human(), bob.human());
1333 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1335 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1336 BEAST_EXPECT(r[jss::result][jss::validated]);
1338 r[jss::result][jss::channels][0u][jss::public_key].asString();
1341 auto const r = env.rpc(
"account_channels", alice.human());
1342 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1344 r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1345 BEAST_EXPECT(r[jss::result][jss::validated]);
1347 r[jss::result][jss::channels][0u][jss::public_key].asString();
1351 env.rpc(
"account_channels", bob.human(), alice.human());
1352 BEAST_EXPECT(r[jss::result][jss::channels].size() == 0);
1353 BEAST_EXPECT(r[jss::result][jss::validated]);
1356 env(
create(alice, bob, channelFunds, settleDelay, pk));
1360 env.rpc(
"account_channels", alice.human(), bob.human());
1361 BEAST_EXPECT(r[jss::result][jss::channels].size() == 2);
1362 BEAST_EXPECT(r[jss::result][jss::validated]);
1363 BEAST_EXPECT(chan1Str != chan2Str);
1364 for (
auto const& c : {chan1Str, chan2Str})
1366 r[jss::result][jss::channels][0u][jss::channel_id] == c ||
1367 r[jss::result][jss::channels][1u][jss::channel_id] == c);
1375 s +=
"0123456789ABCDEF"[((
slice[i] & 0xf0) >> 4)];
1376 s +=
"0123456789ABCDEF"[((
slice[i] & 0x0f) >> 0)];
1384 env.rpc(
"channel_authorize",
"alice", chan1Str,
"1000");
1385 auto const sig = rs[jss::result][jss::signature].asString();
1386 BEAST_EXPECT(!
sig.empty());
1388 auto const rv = env.rpc(
1389 "channel_verify", chan1PkStr, chan1Str,
"1000",
sig);
1390 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1397 env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000",
sig);
1398 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1404 env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000x",
sig);
1405 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1406 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000 ",
sig);
1407 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1408 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"x1000",
sig);
1409 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1410 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"x",
sig);
1411 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1412 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
" ",
sig);
1413 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1415 "channel_verify", pkAsHex, chan1Str,
"1000 1000",
sig);
1416 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1417 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1,000",
sig);
1418 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1419 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
" 1000",
sig);
1420 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1421 rv = env.rpc(
"channel_verify", pkAsHex, chan1Str,
"",
sig);
1422 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1427 auto chan1StrBad = chan1Str;
1428 chan1StrBad.pop_back();
1430 "channel_verify", pkAsHex, chan1StrBad,
"1000",
sig);
1431 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1432 rv = env.rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1433 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1435 chan1StrBad = chan1Str;
1436 chan1StrBad.push_back(
'0');
1438 "channel_verify", pkAsHex, chan1StrBad,
"1000",
sig);
1439 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1440 rv = env.rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1441 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1443 chan1StrBad = chan1Str;
1444 chan1StrBad.back() =
'x';
1446 "channel_verify", pkAsHex, chan1StrBad,
"1000",
sig);
1447 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1448 rv = env.rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1449 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1453 auto illFormedPk = chan1PkStr.
substr(0, chan1PkStr.
size() - 1);
1454 auto const rv = env.rpc(
1455 "channel_verify", illFormedPk, chan1Str,
"1000",
sig);
1457 !rv[jss::result][jss::signature_verified].asBool());
1462 auto illFormedPk = pkAsHex.substr(0, chan1PkStr.
size() - 1);
1463 auto const rv = env.rpc(
1464 "channel_verify", illFormedPk, chan1Str,
"1000",
sig);
1466 !rv[jss::result][jss::signature_verified].asBool());
1472 env.rpc(
"channel_authorize",
"alice", chan2Str,
"1000");
1473 auto const sig = rs[jss::result][jss::signature].asString();
1474 BEAST_EXPECT(!
sig.empty());
1476 auto const rv = env.rpc(
1477 "channel_verify", chan1PkStr, chan1Str,
"1000",
sig);
1479 !rv[jss::result][jss::signature_verified].asBool());
1485 env.rpc(
"channel_verify", pkAsHex, chan1Str,
"1000",
sig);
1487 !rv[jss::result][jss::signature_verified].asBool());
1495 charlie, alice, channelFunds, settleDelay, charlie.pk()));
1501 env.rpc(
"account_channels", charlie.human(), alice.human());
1502 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1504 r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1505 BEAST_EXPECT(r[jss::result][jss::validated]);
1506 cpk = r[jss::result][jss::channels][0u][jss::public_key]
1512 env.rpc(
"channel_authorize",
"charlie", chan,
"1000");
1513 auto const sig = rs[jss::result][jss::signature].asString();
1514 BEAST_EXPECT(!
sig.empty());
1517 env.rpc(
"channel_verify", cpk, chan,
"1000",
sig);
1519 !rv[jss::result][jss::signature_verified].asBool());
1524 env.rpc(
"channel_authorize",
"charlie",
"nyx", chan,
"1000");
1525 BEAST_EXPECT(rs1[jss::error] ==
"badKeyType");
1529 auto const rs2 = env.rpc(
1530 "channel_authorize",
"charlie",
"secp256k1", chan,
"1000");
1531 auto const sig2 = rs2[jss::result][jss::signature].asString();
1532 BEAST_EXPECT(!sig2.empty());
1535 env.rpc(
"channel_verify", cpk, chan,
"1000", sig2);
1537 !rv[jss::result][jss::signature_verified].asBool());
1541 auto const rs3 = env.rpc(
1542 "channel_authorize",
"charlie",
"ed25519", chan,
"1000");
1543 auto const sig3 = rs3[jss::result][jss::signature].asString();
1544 BEAST_EXPECT(!sig3.empty());
1547 env.rpc(
"channel_verify", cpk, chan,
"1000", sig3);
1548 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1554 auto rs = env.rpc(
"channel_authorize",
"alice", chan1Str,
"1000x");
1555 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1556 rs = env.rpc(
"channel_authorize",
"alice", chan1Str,
"x1000");
1557 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1558 rs = env.rpc(
"channel_authorize",
"alice", chan1Str,
"x");
1559 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1563 args[jss::amount] =
"2000";
1564 args[jss::key_type] =
"secp256k1";
1565 args[jss::passphrase] =
"passphrase_can_be_anything";
1568 "channel_authorize",
1569 args.toStyledString())[jss::result];
1570 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1575 args[jss::channel_id] = chan1Str;
1576 args[jss::key_type] =
"secp256k1";
1577 args[jss::passphrase] =
"passphrase_can_be_anything";
1580 "channel_authorize",
1581 args.toStyledString())[jss::result];
1582 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1587 args[jss::amount] =
"2000";
1588 args[jss::channel_id] = chan1Str;
1589 args[jss::passphrase] =
"passphrase_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;
1601 args[jss::key_type] =
"secp256k1";
1602 args[jss::passphrase] =
"passphrase_can_be_anything";
1603 args[jss::seed] =
"seed can be anything";
1606 "channel_authorize",
1607 args.toStyledString())[jss::result];
1608 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1613 args[jss::amount] =
"2000";
1614 args[jss::channel_id] = chan1Str +
"1";
1615 args[jss::key_type] =
"secp256k1";
1616 args[jss::passphrase] =
"passphrase_can_be_anything";
1619 "channel_authorize",
1620 args.toStyledString())[jss::result];
1621 BEAST_EXPECT(rs[jss::error] ==
"channelMalformed");
1626 args[jss::amount] = 2000;
1627 args[jss::channel_id] = chan1Str;
1628 args[jss::key_type] =
"secp256k1";
1629 args[jss::passphrase] =
"passphrase_can_be_anything";
1632 "channel_authorize",
1633 args.toStyledString())[jss::result];
1634 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1639 args[jss::amount] =
"TwoThousand";
1640 args[jss::channel_id] = chan1Str;
1641 args[jss::key_type] =
"secp256k1";
1642 args[jss::passphrase] =
"passphrase_can_be_anything";
1645 "channel_authorize",
1646 args.toStyledString())[jss::result];
1647 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1656 using namespace jtx;
1658 Env env{*
this, features};
1659 auto const alice =
Account(
"alice");
1660 auto const bob =
Account(
"bob");
1661 auto const carol =
Account(
"carol");
1662 auto const dan =
Account(
"dan");
1663 env.fund(
XRP(10000), alice, bob, carol, dan);
1664 auto const pk = alice.pk();
1665 auto const settleDelay = 3600s;
1666 auto const channelFunds =
XRP(1000);
1672 env(
create(alice, bob, channelFunds, settleDelay, pk));
1674 env.rpc(
"account_channels", alice.human(), bob.human());
1675 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1677 r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1678 BEAST_EXPECT(!r[jss::result][jss::channels][0u].isMember(
1679 jss::destination_tag));
1693 env.rpc(
"account_channels", alice.human(), carol.human());
1694 BEAST_EXPECT(r[jss::result][jss::channels].size() == 1);
1696 r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1698 r[jss::result][jss::channels][0u][jss::destination_tag] ==
1707 using namespace jtx;
1709 Env env{*
this, features};
1710 auto const alice =
Account(
"alice");
1711 auto const bob =
Account(
"bob");
1712 auto USDA = alice[
"USD"];
1713 env.fund(
XRP(10000), alice, bob);
1714 auto const pk = alice.pk();
1715 auto const settleDelay = 100s;
1717 auto const chan =
channel(alice, bob, env.seq(alice));
1718 auto jv =
create(alice, bob,
XRP(1000), settleDelay, pk);
1719 auto const pkHex =
strHex(pk.slice());
1720 jv[
"PublicKey"] = pkHex.substr(2, pkHex.size() - 2);
1722 jv[
"PublicKey"] = pkHex.substr(0, pkHex.size() - 2);
1724 auto badPrefix = pkHex;
1727 jv[
"PublicKey"] = badPrefix;
1730 jv[
"PublicKey"] = pkHex;
1733 auto const authAmt =
XRP(100);
1742 jv[
"PublicKey"] = pkHex.substr(2, pkHex.size() - 2);
1744 jv[
"PublicKey"] = pkHex.substr(0, pkHex.size() - 2);
1749 jv[
"PublicKey"] = badPrefix;
1753 jv.removeMember(
"PublicKey");
1757 auto const txn = R
"*(
1760 "channel_id":"5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
1762 "304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064",
1764 "aKijDDiC2q2gXjMpM7i4BUS6cmixgsEe18e7CjsUxwihKfuoFgS5",
1768 auto const r = env.rpc(
"json",
"channel_verify", txn);
1769 BEAST_EXPECT(r[
"result"][
"error"] ==
"publicMalformed");
1778 using namespace jtx;
1781 auto const alice =
Account(
"alice");
1782 auto const bob =
Account(
"bob");
1783 auto const settleDelay = 100s;
1784 auto const pk = alice.pk();
1786 auto inOwnerDir = [](
ReadView const& view,
1790 return std::find(ownerDir.begin(), ownerDir.end(), chan) !=
1794 auto ownerDirCount = [](
ReadView const& view,
1802 Env env{*
this, features};
1803 env.fund(
XRP(10000), alice, bob);
1804 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1806 auto const [chan, chanSle] =
1808 BEAST_EXPECT(inOwnerDir(*env.current(), alice, chanSle));
1809 BEAST_EXPECT(ownerDirCount(*env.current(), alice) == 1);
1810 BEAST_EXPECT(inOwnerDir(*env.current(), bob, chanSle));
1811 BEAST_EXPECT(ownerDirCount(*env.current(), bob) == 1);
1815 BEAST_EXPECT(!inOwnerDir(*env.current(), alice, chanSle));
1816 BEAST_EXPECT(ownerDirCount(*env.current(), alice) == 0);
1817 BEAST_EXPECT(!inOwnerDir(*env.current(), bob, chanSle));
1818 BEAST_EXPECT(ownerDirCount(*env.current(), bob) == 0);
1824 Env env(*
this, features);
1825 env.
fund(
XRP(10000), alice, bob);
1827 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1829 auto const [chan, chanSle] =
1831 BEAST_EXPECT(inOwnerDir(*env.
current(), alice, chanSle));
1832 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 1);
1833 BEAST_EXPECT(inOwnerDir(*env.
current(), bob, chanSle));
1834 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 1);
1838 BEAST_EXPECT(!inOwnerDir(*env.
current(), alice, chanSle));
1839 BEAST_EXPECT(ownerDirCount(*env.
current(), alice) == 0);
1840 BEAST_EXPECT(!inOwnerDir(*env.
current(), bob, chanSle));
1841 BEAST_EXPECT(ownerDirCount(*env.
current(), bob) == 0);
1849 using namespace test::jtx;
1851 auto rmAccount = [
this](
1858 for (
auto minRmSeq = env.
seq(toRm) + 257;
1859 env.
current()->seq() < minRmSeq;
1873 auto const alice =
Account(
"alice");
1874 auto const bob =
Account(
"bob");
1875 auto const carol =
Account(
"carol");
1878 Env env{*
this, features};
1879 env.
fund(
XRP(10000), alice, bob, carol);
1883 auto const pk = alice.pk();
1884 auto const settleDelay = 100s;
1885 auto const chan =
channel(alice, bob, env.
seq(alice));
1886 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1894 auto const feeDrops = env.
current()->fees().base;
1897 BEAST_EXPECT(chanBal ==
XRP(0));
1898 BEAST_EXPECT(chanAmt ==
XRP(1000));
1900 auto preBob = env.
balance(bob);
1901 auto const delta =
XRP(50);
1902 auto reqBal = chanBal + delta;
1903 auto authAmt = reqBal +
XRP(100);
1904 assert(reqBal <= chanAmt);
1906 env(
claim(alice, chan, reqBal, authAmt));
1910 BEAST_EXPECT(env.
balance(bob) == preBob + delta);
1913 auto const preAlice = env.
balance(alice);
1914 env(
fund(alice, chan,
XRP(1000)));
1916 BEAST_EXPECT(env.
balance(alice) == preAlice -
XRP(1000) - feeDrops);
1919 chanAmt = chanAmt +
XRP(1000);
1927 auto const closeTime = env.
current()->info().parentCloseTime;
1928 auto const minExpiration = closeTime + settleDelay;
1929 env.
close(minExpiration);
1940 using namespace jtx;
1942 Env env{*
this, features};
1943 auto const alice =
Account(
"alice");
1944 auto const bob =
Account(
"bob");
1945 auto USDA = alice[
"USD"];
1946 env.fund(
XRP(10000), alice, bob);
1959 auto const pk = alice.pk();
1960 auto const settleDelay = 100s;
1961 auto const chan =
channel(alice, bob, aliceTicketSeq);
1963 env(
create(alice, bob,
XRP(1000), settleDelay, pk),
1966 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1967 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1973 auto const preAlice = env.balance(alice);
1976 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1977 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1979 auto const feeDrops = env.current()->fees().base;
1980 BEAST_EXPECT(env.balance(alice) == preAlice -
XRP(1000) - feeDrops);
1985 BEAST_EXPECT(chanBal ==
XRP(0));
1986 BEAST_EXPECT(chanAmt ==
XRP(2000));
1990 auto const preBob = env.balance(bob);
1991 auto const delta =
XRP(500);
1992 auto const reqBal = chanBal + delta;
1993 auto const authAmt = reqBal +
XRP(100);
1994 assert(reqBal <= chanAmt);
1995 env(
claim(alice, chan, reqBal, authAmt),
1998 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1999 BEAST_EXPECT(env.seq(alice) == aliceSeq);
2002 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
2003 BEAST_EXPECT(env.balance(bob) == preBob + delta);
2008 auto preBob = env.balance(bob);
2009 auto const delta =
XRP(500);
2010 auto const reqBal = chanBal + delta;
2011 auto const authAmt = reqBal +
XRP(100);
2012 assert(reqBal <= chanAmt);
2015 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()),
2018 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2019 BEAST_EXPECT(env.seq(bob) == bobSeq);
2022 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
2023 auto const feeDrops = env.current()->fees().base;
2024 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
2028 preBob = env.balance(bob);
2030 env(
claim(bob, chan, reqBal, authAmt,
Slice(
sig), alice.pk()),
2034 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2035 BEAST_EXPECT(env.seq(bob) == bobSeq);
2038 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
2039 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
2043 auto const preBob = env.balance(bob);
2046 assert(reqAmt <= chanAmt);
2051 env(
claim(bob, chan, reqAmt, authAmt,
Slice(
sig), alice.pk()),
2055 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2056 BEAST_EXPECT(env.seq(bob) == bobSeq);
2059 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
2060 BEAST_EXPECT(env.balance(bob) == preBob);
2064 env(
fund(bob, chan,
XRP(1000)),
2068 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2069 BEAST_EXPECT(env.seq(bob) == bobSeq);
2072 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
2076 auto const preAlice = env.balance(alice);
2077 auto const preBob = env.balance(bob);
2078 env(
claim(bob, chan),
2082 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2083 BEAST_EXPECT(env.seq(bob) == bobSeq);
2086 auto const feeDrops = env.current()->fees().base;
2087 auto const delta = chanAmt - chanBal;
2088 assert(delta > beast::zero);
2089 BEAST_EXPECT(env.balance(alice) == preAlice + delta);
2090 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
2092 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
2093 BEAST_EXPECT(env.seq(alice) == aliceSeq);
2094 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
2095 BEAST_EXPECT(env.seq(bob) == bobSeq);
2128 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)
@ lsfDisallowIncomingPayChan
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)
FeatureBitset const disallowIncoming
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)