2#include <test/jtx/Account.h>
3#include <test/jtx/Env.h>
4#include <test/jtx/TestHelpers.h>
5#include <test/jtx/acctdelete.h>
6#include <test/jtx/amount.h>
7#include <test/jtx/balance.h>
8#include <test/jtx/credentials.h>
9#include <test/jtx/deposit.h>
10#include <test/jtx/fee.h>
11#include <test/jtx/flags.h>
12#include <test/jtx/ter.h>
13#include <test/jtx/ticket.h>
14#include <test/jtx/txflags.h>
16#include <xrpl/basics/Buffer.h>
17#include <xrpl/basics/Slice.h>
18#include <xrpl/basics/base_uint.h>
19#include <xrpl/basics/chrono.h>
20#include <xrpl/basics/strHex.h>
21#include <xrpl/beast/unit_test/suite.h>
22#include <xrpl/beast/utility/Zero.h>
23#include <xrpl/core/ServiceRegistry.h>
24#include <xrpl/json/json_value.h>
25#include <xrpl/json/to_string.h>
26#include <xrpl/ledger/Dir.h>
27#include <xrpl/ledger/ReadView.h>
28#include <xrpl/protocol/ApiVersion.h>
29#include <xrpl/protocol/Feature.h>
30#include <xrpl/protocol/Indexes.h>
31#include <xrpl/protocol/KeyType.h>
32#include <xrpl/protocol/LedgerFormats.h>
33#include <xrpl/protocol/PayChan.h>
34#include <xrpl/protocol/PublicKey.h>
35#include <xrpl/protocol/SField.h>
36#include <xrpl/protocol/STAmount.h>
37#include <xrpl/protocol/SecretKey.h>
38#include <xrpl/protocol/Serializer.h>
39#include <xrpl/protocol/TER.h>
40#include <xrpl/protocol/TxFlags.h>
41#include <xrpl/protocol/jss.h>
66 return {k.key, view.
read(k)};
84 auto const slep = view.
read({ltPAYCHAN, chan});
87 return (*slep)[sfAmount];
93 auto const slep = view.
read({ltPAYCHAN, chan});
96 if (
auto const r = (*slep)[~sfExpiration])
107 Env env{*
this, features};
108 auto const alice =
Account(
"alice");
109 auto const bob =
Account(
"bob");
110 auto usda = alice[
"USD"];
111 env.
fund(
XRP(10000), alice, bob);
112 auto const pk = alice.pk();
113 auto const settleDelay = 100s;
114 auto const chan =
channel(alice, bob, env.
seq(alice));
115 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
120 auto const preAlice = env.
balance(alice);
121 env(
fund(alice, chan,
XRP(1000)));
122 auto const feeDrops = env.
current()->fees().base;
123 BEAST_EXPECT(env.
balance(alice) == preAlice -
XRP(1000) - feeDrops);
128 BEAST_EXPECT(chanBal ==
XRP(0));
129 BEAST_EXPECT(chanAmt ==
XRP(2000));
152 auto const iou = usda(100).value();
153 auto const negXRP =
XRP(-100).value();
154 auto const posXRP =
XRP(100).value();
164 auto const delta =
XRP(500);
165 auto const reqBal = chanBal + delta;
166 auto const authAmt = reqBal +
XRP(-100);
167 assert(reqBal <= chanAmt);
172 auto const preBob = env.
balance(bob);
173 auto const delta =
XRP(500);
174 auto const reqBal = chanBal + delta;
175 auto const authAmt = reqBal +
XRP(100);
176 assert(reqBal <= chanAmt);
177 env(
claim(alice, chan, reqBal, authAmt));
180 BEAST_EXPECT(env.
balance(bob) == preBob + delta);
185 auto preBob = env.
balance(bob);
186 auto const delta =
XRP(500);
187 auto const reqBal = chanBal + delta;
188 auto const authAmt = reqBal +
XRP(100);
189 assert(reqBal <= chanAmt);
190 auto const sig =
signClaimAuth(alice.pk(), alice.sk(), chan, authAmt);
191 env(
claim(bob, chan, reqBal, authAmt,
Slice(sig), alice.pk()));
194 auto const feeDrops = env.
current()->fees().base;
195 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
200 env(
claim(bob, chan, reqBal, authAmt,
Slice(sig), alice.pk()),
204 BEAST_EXPECT(env.
balance(bob) == preBob - feeDrops);
208 auto const preBob = env.
balance(bob);
211 assert(reqAmt <= chanAmt);
212 auto const sig =
signClaimAuth(alice.pk(), alice.sk(), chan, authAmt);
216 BEAST_EXPECT(env.
balance(bob) == preBob);
227 env(
claim(bob, chan,
XRP(1500).value(),
XRP(1500).value(),
Slice(sig), bob.pk()),
235 env(
claim(bob, chan,
XRP(1500).value(),
XRP(1500).value(),
Slice(sig), alice.pk()),
242 auto const preAlice = env.
balance(alice);
243 auto const preBob = env.
balance(bob);
246 auto const feeDrops = env.
current()->fees().base;
247 auto const delta = chanAmt - chanBal;
248 assert(delta > beast::kZero);
249 BEAST_EXPECT(env.
balance(alice) == preAlice + delta);
250 BEAST_EXPECT(env.
balance(bob) == preBob - feeDrops);
261 Env env{*
this, features};
262 auto const alice =
Account(
"alice");
263 auto const bob =
Account(
"bob");
264 auto const cho =
Account(
"cho");
265 env.
fund(
XRP(10000), alice, bob, cho);
266 auto const pk = alice.pk();
267 auto const settleDelay = 100s;
270 env(
fset(bob, asfDisallowIncomingPayChan));
275 auto const chan =
channel(alice, bob, env.
seq(alice));
281 env(
fset(alice, asfDisallowIncomingPayChan));
286 auto const chan =
channel(bob, alice, env.
seq(bob));
292 env(
fclear(bob, asfDisallowIncomingPayChan));
297 auto const chan =
channel(alice, bob, env.
seq(alice));
304 auto const chan =
channel(cho, alice, env.
seq(cho));
310 env(
fclear(alice, asfDisallowIncomingPayChan));
315 auto const chan =
channel(cho, alice, env.
seq(cho));
327 auto const alice =
Account(
"alice");
328 auto const bob =
Account(
"bob");
329 auto const carol =
Account(
"carol");
332 Env env{*
this, features};
333 env.
fund(
XRP(10000), alice, bob);
334 auto const pk = alice.pk();
335 auto const settleDelay = 100s;
337 env.
current()->header().parentCloseTime + 3600s;
338 auto const channelFunds =
XRP(1000);
339 auto const chan =
channel(alice, bob, env.
seq(alice));
340 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
342 env.
close(cancelAfter);
347 auto preAlice = env.
balance(alice);
348 auto preBob = env.
balance(bob);
349 auto const delta =
XRP(500);
350 auto const reqBal = chanBal + delta;
351 auto const authAmt = reqBal +
XRP(100);
352 assert(reqBal <= chanAmt);
353 auto const sig =
signClaimAuth(alice.pk(), alice.sk(), chan, authAmt);
354 env(
claim(bob, chan, reqBal, authAmt,
Slice(sig), alice.pk()));
355 auto const feeDrops = env.
current()->fees().base;
357 BEAST_EXPECT(env.
balance(bob) == preBob - feeDrops);
358 BEAST_EXPECT(env.
balance(alice) == preAlice + channelFunds);
363 Env env{*
this, features};
364 env.
fund(
XRP(10000), alice, bob, carol);
365 auto const pk = alice.pk();
366 auto const settleDelay = 100s;
368 env.
current()->header().parentCloseTime + 3600s;
369 auto const channelFunds =
XRP(1000);
370 auto const chan =
channel(alice, bob, env.
seq(alice));
371 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
376 env.
close(cancelAfter);
378 auto const preAlice = env.
balance(alice);
381 BEAST_EXPECT(env.
balance(alice) == preAlice + channelFunds);
386 for (
bool const withFixPayChan : {
true,
false})
388 auto const amend = withFixPayChan ? features : features - fixPayChanCancelAfter;
389 Env env{*
this, amend};
390 env.
fund(
XRP(10000), alice, bob);
393 auto const pk = alice.pk();
394 auto const settleDelay = 100s;
395 auto const channelFunds =
XRP(1000);
397 env.
current()->header().parentCloseTime - 1s;
399 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter), txResult);
405 for (
bool const withFixPayChan : {
true,
false})
407 auto const amend = withFixPayChan ? features : features - fixPayChanCancelAfter;
408 Env env{*
this, amend};
409 env.
fund(
XRP(10000), alice, bob);
412 auto const pk = alice.pk();
413 auto const settleDelay = 100s;
414 auto const channelFunds =
XRP(1000);
416 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter),
428 Env env{*
this, features};
429 auto const alice =
Account(
"alice");
430 auto const bob =
Account(
"bob");
431 auto const carol =
Account(
"carol");
432 env.
fund(
XRP(10000), alice, bob, carol);
433 auto const pk = alice.pk();
434 auto const settleDelay = 3600s;
435 auto const closeTime = env.
current()->header().parentCloseTime;
436 auto const minExpiration = closeTime + settleDelay;
438 auto const channelFunds =
XRP(1000);
439 auto const chan =
channel(alice, bob, env.
seq(alice));
440 env(
create(alice, bob, channelFunds, settleDelay, pk, cancelAfter));
445 auto counts = [](
auto const& t) {
return t.time_since_epoch().count(); };
471 env.
close(minExpiration);
483 Env env{*
this, features};
484 auto const alice =
Account(
"alice");
485 auto const bob =
Account(
"bob");
486 env.
fund(
XRP(10000), alice, bob);
487 auto const pk = alice.pk();
488 auto const settleDelay = 3600s;
490 env.
current()->header().parentCloseTime + settleDelay;
491 auto const channelFunds =
XRP(1000);
492 auto const chan =
channel(alice, bob, env.
seq(alice));
493 env(
create(alice, bob, channelFunds, settleDelay, pk));
498 env.
close(settleTimepoint - settleDelay / 2);
503 auto preBob = env.
balance(bob);
504 auto const delta =
XRP(500);
505 auto const reqBal = chanBal + delta;
506 auto const authAmt = reqBal +
XRP(100);
507 assert(reqBal <= chanAmt);
508 auto const sig =
signClaimAuth(alice.pk(), alice.sk(), chan, authAmt);
509 env(
claim(bob, chan, reqBal, authAmt,
Slice(sig), alice.pk()));
512 auto const feeDrops = env.
current()->fees().base;
513 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
515 env.
close(settleTimepoint);
520 auto const preAlice = env.
balance(alice);
521 auto preBob = env.
balance(bob);
522 auto const delta =
XRP(500);
523 auto const reqBal = chanBal + delta;
524 auto const authAmt = reqBal +
XRP(100);
525 assert(reqBal <= chanAmt);
526 auto const sig =
signClaimAuth(alice.pk(), alice.sk(), chan, authAmt);
527 env(
claim(bob, chan, reqBal, authAmt,
Slice(sig), alice.pk()));
529 auto const feeDrops = env.
current()->fees().base;
530 BEAST_EXPECT(env.
balance(alice) == preAlice + chanAmt - chanBal);
531 BEAST_EXPECT(env.
balance(bob) == preBob - feeDrops);
541 Env env{*
this, features};
542 auto const alice =
Account(
"alice");
543 auto const bob =
Account(
"bob");
544 env.
fund(
XRP(10000), alice, bob);
545 auto const pk = alice.pk();
546 auto const settleDelay = 3600s;
547 auto const channelFunds =
XRP(1000);
548 auto const chan =
channel(alice, bob, env.
seq(alice));
549 env(
create(alice, bob, channelFunds, settleDelay, pk));
556 auto const preBob = env.
balance(bob);
557 env(
claim(alice, chan, channelFunds.value(), channelFunds.value()));
559 BEAST_EXPECT(env.
balance(bob) == preBob + channelFunds);
561 auto const preAlice = env.
balance(alice);
565 auto const feeDrops = env.
current()->fees().base;
566 BEAST_EXPECT(env.
balance(alice) == preAlice - feeDrops);
576 Env env{*
this, features};
577 auto const alice =
Account(
"alice");
578 auto const bob =
Account(
"bob");
579 env.
fund(
XRP(10000), alice, bob);
580 auto const pk = alice.pk();
581 auto const settleDelay = 3600s;
582 auto const channelFunds =
XRP(1000);
583 auto const chan =
channel(alice, bob, env.
seq(alice));
584 env(
create(alice, bob, channelFunds, settleDelay, pk));
592 auto const preBob = env.
balance(bob);
594 auto const delta =
XRP(500);
595 auto const reqBal = chanBal + delta;
596 assert(reqBal <= chanAmt);
597 auto const sig =
signClaimAuth(alice.pk(), alice.sk(), chan, reqBal);
598 env(
claim(bob, chan, reqBal, std::nullopt,
Slice(sig), alice.pk()));
600 auto const feeDrops = env.
current()->fees().base;
601 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
608 auto const preBob = env.
balance(bob);
610 auto const delta =
XRP(500);
611 auto const reqBal = chanBal + delta;
612 assert(reqBal <= chanAmt);
613 auto const sig =
signClaimAuth(alice.pk(), alice.sk(), chan, reqBal);
614 env(
claim(bob, chan, reqBal, std::nullopt,
Slice(sig), alice.pk()));
616 auto const feeDrops = env.
current()->fees().base;
617 BEAST_EXPECT(env.
balance(bob) == preBob + delta - feeDrops);
630 auto const alice =
Account(
"alice");
631 auto const bob =
Account(
"bob");
635 Env env{*
this, features};
636 env.
fund(
XRP(10000), alice, bob);
637 env(
fset(bob, asfDisallowXRP));
638 auto const chan =
channel(alice, bob, env.
seq(alice));
639 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
647 Env env{*
this, features};
648 env.
fund(
XRP(10000), alice, bob);
649 auto const chan =
channel(alice, bob, env.
seq(alice));
650 env(
create(alice, bob,
XRP(1000), 3600s, alice.pk()));
653 env(
fset(bob, asfDisallowXRP));
654 auto const reqBal =
XRP(500).value();
655 env(
claim(alice, chan, reqBal, reqBal));
667 Env env{*
this, features};
668 auto const alice =
Account(
"alice");
669 auto const bob =
Account(
"bob");
670 env.
fund(
XRP(10000), alice, bob);
671 env(
fset(bob, asfRequireDest));
672 auto const pk = alice.pk();
673 auto const settleDelay = 3600s;
674 auto const channelFunds =
XRP(1000);
676 auto const chan =
channel(alice, bob, env.
seq(alice));
681 auto const chan =
channel(alice, bob, env.
seq(alice));
682 env(
create(alice, bob, channelFunds, settleDelay, pk, std::nullopt, 1));
694 auto const alice =
Account(
"alice");
695 auto const bob =
Account(
"bob");
696 auto const carol =
Account(
"carol");
697 auto usda = alice[
"USD"];
699 Env env{*
this, features};
700 env.
fund(
XRP(10000), alice, bob, carol);
702 env(
fset(bob, asfDepositAuth));
705 auto const pk = alice.pk();
706 auto const settleDelay = 100s;
707 auto const chan =
channel(alice, bob, env.
seq(alice));
708 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
716 env(
fund(alice, chan,
XRP(1000)));
724 auto const baseFee = env.
current()->fees().base;
725 auto const preBob = env.
balance(bob);
727 auto const delta =
XRP(500).value();
734 BEAST_EXPECT(env.
balance(bob) == preBob);
744 env(
claim(bob, chan, delta, delta,
Slice(sig), pk));
746 BEAST_EXPECT(env.
balance(bob) == preBob + delta - baseFee);
750 auto const delta =
XRP(600).value();
775 env(
claim(alice, chan, delta, delta,
Slice(sig), pk));
778 BEAST_EXPECT(env.
balance(bob) == preBob + delta - (3 * baseFee));
783 auto const delta =
XRP(800).value();
793 env(
fclear(bob, asfDepositAuth));
797 env(
claim(alice, chan, delta, delta));
799 BEAST_EXPECT(env.
balance(bob) == preBob +
XRP(800) - (5 * baseFee));
807 testcase(
"Deposit Authorization with Credentials");
811 char const credType[] =
"abcde";
816 Account const dillon(
"dillon");
821 env.
fund(
XRP(10000), alice, bob, carol, dillon, zelda);
823 auto const pk = alice.
pk();
824 auto const settleDelay = 100s;
825 auto const chan =
channel(alice, bob, env.
seq(alice));
826 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
830 env(
fund(alice, chan,
XRP(1000)));
834 "D007AE4B6E1274B4AF872588267B810C2F82716726351D1C7D38D3E5499FC6"
837 auto const delta =
XRP(500).value();
842 env.
current()->header().parentCloseTime.time_since_epoch().count() + 100;
843 jv[sfExpiration.jsonName] = t;
849 std::string const credIdx = jv[jss::result][jss::index].asString();
852 env(
fset(bob, asfDepositAuth));
856 env(
claim(alice, chan, delta, delta),
865 env(
claim(alice, chan, delta, delta),
875 env(
claim(dillon, chan, delta, delta),
883 env(
claim(alice, chan, delta, delta),
894 for (
int i = 0; i < 10; ++i)
908 std::string const credIdx = jv[jss::result][jss::index].asString();
917 env.
fund(
XRP(10000), alice, bob, carol, dillon, zelda);
919 auto const pk = alice.
pk();
920 auto const settleDelay = 100s;
921 auto const chan =
channel(alice, bob, env.
seq(alice));
922 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
926 env(
fund(alice, chan,
XRP(1000)));
929 auto const delta =
XRP(500).value();
939 std::string const credIdx = jv[jss::result][jss::index].asString();
949 env.
fund(
XRP(5000),
"alice",
"bob");
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));
958 env(
fund(alice, chan,
XRP(1000)));
961 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
965 env(
fset(bob, asfDepositAuth));
970 env(
claim(alice, chan,
XRP(500).value(),
XRP(500).value()),
980 testcase(
"Multiple channels to the same account");
983 Env env{*
this, features};
984 auto const alice =
Account(
"alice");
985 auto const bob =
Account(
"bob");
986 env.
fund(
XRP(10000), alice, bob);
987 auto const pk = alice.pk();
988 auto const settleDelay = 3600s;
989 auto const channelFunds =
XRP(1000);
990 auto const chan1 =
channel(alice, bob, env.
seq(alice));
991 env(
create(alice, bob, channelFunds, settleDelay, pk));
993 auto const chan2 =
channel(alice, bob, env.
seq(alice));
994 env(
create(alice, bob, channelFunds, settleDelay, pk));
996 BEAST_EXPECT(chan1 != chan2);
1004 using namespace jtx;
1006 Env env{*
this, features};
1007 auto const alice =
Account(
"alice");
1008 auto const bob =
Account(
"bob");
1010 env.
fund(
XRP(10000), alice, bob, charlie);
1011 auto const pk = alice.pk();
1012 auto const settleDelay = 3600s;
1013 auto const channelFunds =
XRP(1000);
1015 env(
create(alice, bob, channelFunds, settleDelay, pk));
1019 auto testInvalidAccountParam = [&](
auto const& param) {
1021 params[jss::account] = param;
1023 env.
rpc(
"json",
"account_channels",
to_string(params))[jss::result];
1024 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1025 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'account'.");
1028 testInvalidAccountParam(1);
1029 testInvalidAccountParam(1.1);
1030 testInvalidAccountParam(
true);
1037 auto testInvalidDestAccountParam = [&](
auto const& param) {
1039 params[jss::account] = alice.human();
1040 params[jss::destination_account] = param;
1042 env.
rpc(
"json",
"account_channels",
to_string(params))[jss::result];
1043 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1044 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'destination_account'.");
1047 testInvalidDestAccountParam(1);
1048 testInvalidDestAccountParam(1.1);
1049 testInvalidDestAccountParam(
true);
1055 auto const r = env.
rpc(
"account_channels", alice.human(), bob.human());
1056 BEAST_EXPECT(r[jss::result][jss::channels].
size() == 1);
1057 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1058 BEAST_EXPECT(r[jss::result][jss::validated]);
1061 auto const r = env.
rpc(
"account_channels", alice.human());
1062 BEAST_EXPECT(r[jss::result][jss::channels].
size() == 1);
1063 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1064 BEAST_EXPECT(r[jss::result][jss::validated]);
1067 auto const r = env.
rpc(
"account_channels", bob.human(), alice.human());
1068 BEAST_EXPECT(r[jss::result][jss::channels].
size() == 0);
1069 BEAST_EXPECT(r[jss::result][jss::validated]);
1072 env(
create(alice, bob, channelFunds, settleDelay, pk));
1075 auto const r = env.
rpc(
"account_channels", alice.human(), bob.human());
1076 BEAST_EXPECT(r[jss::result][jss::channels].
size() == 2);
1077 BEAST_EXPECT(r[jss::result][jss::validated]);
1078 BEAST_EXPECT(chan1Str != chan2Str);
1079 for (
auto const& c : {chan1Str, chan2Str})
1082 r[jss::result][jss::channels][0u][jss::channel_id] == c ||
1083 r[jss::result][jss::channels][1u][jss::channel_id] == c);
1091 testcase(
"Account channels RPC markers");
1096 auto const alice =
Account(
"alice");
1101 for (
int i = 0; i < n; ++i)
1108 Env env{*
this, features};
1110 for (
auto const& a : bobs)
1118 auto const settleDelay = 3600s;
1119 auto const channelFunds =
XRP(1);
1120 for (
auto const& b : bobs)
1122 env(
create(alice, b, channelFunds, settleDelay, alice.pk()));
1132 jvc[jss::account] = src.human();
1134 jvc[jss::destination_account] = dst->human();
1136 jvc[jss::limit] = *limit;
1138 jvc[jss::marker] = marker;
1140 return env.
rpc(
"json",
"account_channels",
to_string(jvc))[jss::result];
1145 auto const r = testLimit(env, alice);
1146 BEAST_EXPECT(r.isMember(jss::channels));
1147 BEAST_EXPECT(r[jss::channels].
size() == bobs.size());
1152 for (
auto const& a : bobs)
1157 for (
int limit = 1; limit < bobs.size() + 1; ++limit)
1159 auto leftToFind = bobsB58;
1160 auto const numFull = bobs.size() / limit;
1161 auto const numNonFull = ((bobs.size() % limit) != 0u) ? 1 : 0;
1165 auto const testIt = [&](
bool expectMarker,
int expectedBatchSize) {
1166 auto const r = testLimit(env, alice, limit, marker);
1167 BEAST_EXPECT(!expectMarker || r.isMember(jss::marker));
1168 if (r.isMember(jss::marker))
1169 marker = r[jss::marker];
1170 BEAST_EXPECT(r[jss::channels].
size() == expectedBatchSize);
1171 auto const c = r[jss::channels];
1172 auto const s = r[jss::channels].size();
1173 for (
int j = 0; j < s; ++j)
1175 auto const dstAcc = c[j][jss::destination_account].asString();
1176 BEAST_EXPECT(leftToFind.count(dstAcc));
1177 leftToFind.erase(dstAcc);
1181 for (
int i = 0; i < numFull; ++i)
1183 bool const expectMarker = (numNonFull != 0 || i < numFull - 1);
1184 testIt(expectMarker, limit);
1187 if (numNonFull != 0)
1189 testIt(
false, bobs.size() % limit);
1191 BEAST_EXPECT(leftToFind.empty());
1196 auto const r = testLimit(env, alice, 0);
1197 BEAST_EXPECT(r.isMember(jss::error_message));
1206 testcase(
"Account channels RPC owner only");
1211 auto const alice =
Account(
"alice");
1212 auto const bob =
Account(
"bob");
1213 Env env{*
this, features};
1214 env.
fund(
XRP(10000), alice, bob);
1219 auto const settleDelay = 3600s;
1220 auto const channelFunds =
XRP(1000);
1221 env(
create(alice, bob, channelFunds, settleDelay, alice.pk()));
1222 env(
create(bob, alice, channelFunds, settleDelay, bob.pk()));
1224 auto const r = [&] {
1226 jvc[jss::account] = alice.human();
1228 return env.
rpc(
"json",
"account_channels",
to_string(jvc))[jss::result];
1230 BEAST_EXPECT(r.isMember(jss::channels));
1231 BEAST_EXPECT(r[jss::channels].
size() == 1);
1232 BEAST_EXPECT(r[jss::channels][0u][jss::destination_account].asString() == bob.human());
1238 using namespace jtx;
1241 Env env{*
this, features};
1242 auto const alice =
Account(
"alice");
1243 auto const bob =
Account(
"bob");
1245 env.
fund(
XRP(10000), alice, bob, charlie);
1246 auto const pk = alice.pk();
1247 auto const settleDelay = 3600s;
1248 auto const channelFunds =
XRP(1000);
1250 env(
create(alice, bob, channelFunds, settleDelay, pk));
1254 args[jss::channel_id] = chan1Str;
1255 args[jss::key_type] =
"ed255191";
1256 args[jss::seed] =
"snHq1rzQoN2qiUkC3XF5RyxBzUtN";
1257 args[jss::amount] = 51110000;
1262 args[jss::api_version] = apiVersion;
1265 auto const error = apiVersion < 2u ?
"invalidParams" :
"badKeyType";
1266 BEAST_EXPECT(rs[jss::error] == error);
1273 testcase(
"PayChan Auth/Verify RPC");
1274 using namespace jtx;
1276 Env env{*
this, features};
1277 auto const alice =
Account(
"alice");
1278 auto const bob =
Account(
"bob");
1280 env.
fund(
XRP(10000), alice, bob, charlie);
1281 auto const pk = alice.pk();
1282 auto const settleDelay = 3600s;
1283 auto const channelFunds =
XRP(1000);
1285 env(
create(alice, bob, channelFunds, settleDelay, pk));
1289 auto const r = env.
rpc(
"account_channels", alice.human(), bob.human());
1290 BEAST_EXPECT(r[jss::result][jss::channels].
size() == 1);
1291 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1292 BEAST_EXPECT(r[jss::result][jss::validated]);
1293 chan1PkStr = r[jss::result][jss::channels][0u][jss::public_key].asString();
1296 auto const r = env.
rpc(
"account_channels", alice.human());
1297 BEAST_EXPECT(r[jss::result][jss::channels].
size() == 1);
1298 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::channel_id] == chan1Str);
1299 BEAST_EXPECT(r[jss::result][jss::validated]);
1300 chan1PkStr = r[jss::result][jss::channels][0u][jss::public_key].asString();
1303 auto const r = env.
rpc(
"account_channels", bob.human(), alice.human());
1304 BEAST_EXPECT(r[jss::result][jss::channels].
size() == 0);
1305 BEAST_EXPECT(r[jss::result][jss::validated]);
1308 env(
create(alice, bob, channelFunds, settleDelay, pk));
1311 auto const r = env.
rpc(
"account_channels", alice.human(), bob.human());
1312 BEAST_EXPECT(r[jss::result][jss::channels].
size() == 2);
1313 BEAST_EXPECT(r[jss::result][jss::validated]);
1314 BEAST_EXPECT(chan1Str != chan2Str);
1315 for (
auto const& c : {chan1Str, chan2Str})
1318 r[jss::result][jss::channels][0u][jss::channel_id] == c ||
1319 r[jss::result][jss::channels][1u][jss::channel_id] == c);
1328 s +=
"0123456789ABCDEF"[((
slice[i] & 0xf0) >> 4)];
1329 s +=
"0123456789ABCDEF"[((
slice[i] & 0x0f) >> 0)];
1336 auto const rs = env.
rpc(
"channel_authorize",
"alice", chan1Str,
"1000");
1337 auto const sig = rs[jss::result][jss::signature].
asString();
1338 BEAST_EXPECT(!sig.empty());
1340 auto const rv = env.
rpc(
"channel_verify", chan1PkStr, chan1Str,
"1000", sig);
1341 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1347 auto const rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"1000", sig);
1348 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1353 auto rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"1000x", sig);
1354 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1355 rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"1000 ", sig);
1356 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1357 rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"x1000", sig);
1358 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1359 rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"x", sig);
1360 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1361 rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
" ", sig);
1362 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1363 rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"1000 1000", sig);
1364 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1365 rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"1,000", sig);
1366 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1367 rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
" 1000", sig);
1368 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1369 rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"", sig);
1370 BEAST_EXPECT(rv[jss::error] ==
"channelAmtMalformed");
1375 auto chan1StrBad = chan1Str;
1376 chan1StrBad.pop_back();
1377 auto rv = env.
rpc(
"channel_verify", pkAsHex, chan1StrBad,
"1000", sig);
1378 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1379 rv = env.
rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1380 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1382 chan1StrBad = chan1Str;
1383 chan1StrBad.push_back(
'0');
1384 rv = env.
rpc(
"channel_verify", pkAsHex, chan1StrBad,
"1000", sig);
1385 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1386 rv = env.
rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1387 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1389 chan1StrBad = chan1Str;
1390 chan1StrBad.back() =
'x';
1391 rv = env.
rpc(
"channel_verify", pkAsHex, chan1StrBad,
"1000", sig);
1392 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1393 rv = env.
rpc(
"channel_authorize",
"alice", chan1StrBad,
"1000");
1394 BEAST_EXPECT(rv[jss::error] ==
"channelMalformed");
1398 auto illFormedPk = chan1PkStr.
substr(0, chan1PkStr.
size() - 1);
1399 auto const rv = env.
rpc(
"channel_verify", illFormedPk, chan1Str,
"1000", sig);
1400 BEAST_EXPECT(!rv[jss::result][jss::signature_verified].asBool());
1405 auto illFormedPk = pkAsHex.substr(0, chan1PkStr.
size() - 1);
1406 auto const rv = env.
rpc(
"channel_verify", illFormedPk, chan1Str,
"1000", sig);
1407 BEAST_EXPECT(!rv[jss::result][jss::signature_verified].asBool());
1412 auto const rs = env.
rpc(
"channel_authorize",
"alice", chan2Str,
"1000");
1413 auto const sig = rs[jss::result][jss::signature].
asString();
1414 BEAST_EXPECT(!sig.empty());
1416 auto const rv = env.
rpc(
"channel_verify", chan1PkStr, chan1Str,
"1000", sig);
1417 BEAST_EXPECT(!rv[jss::result][jss::signature_verified].asBool());
1422 auto const rv = env.
rpc(
"channel_verify", pkAsHex, chan1Str,
"1000", sig);
1423 BEAST_EXPECT(!rv[jss::result][jss::signature_verified].asBool());
1429 env(
create(charlie, alice, channelFunds, settleDelay, charlie.pk()));
1434 auto const r = env.
rpc(
"account_channels", charlie.human(), alice.human());
1435 BEAST_EXPECT(r[jss::result][jss::channels].
size() == 1);
1436 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1437 BEAST_EXPECT(r[jss::result][jss::validated]);
1438 cpk = r[jss::result][jss::channels][0u][jss::public_key].asString();
1442 auto const rs = env.
rpc(
"channel_authorize",
"charlie", chan,
"1000");
1443 auto const sig = rs[jss::result][jss::signature].
asString();
1444 BEAST_EXPECT(!sig.empty());
1446 auto const rv = env.
rpc(
"channel_verify", cpk, chan,
"1000", sig);
1447 BEAST_EXPECT(!rv[jss::result][jss::signature_verified].asBool());
1451 auto const rs1 = env.
rpc(
"channel_authorize",
"charlie",
"nyx", chan,
"1000");
1452 BEAST_EXPECT(rs1[jss::error] ==
"badKeyType");
1456 auto const rs2 = env.
rpc(
"channel_authorize",
"charlie",
"secp256k1", chan,
"1000");
1457 auto const sig2 = rs2[jss::result][jss::signature].
asString();
1458 BEAST_EXPECT(!sig2.empty());
1460 auto const rv = env.
rpc(
"channel_verify", cpk, chan,
"1000", sig2);
1461 BEAST_EXPECT(!rv[jss::result][jss::signature_verified].asBool());
1465 auto const rs3 = env.
rpc(
"channel_authorize",
"charlie",
"ed25519", chan,
"1000");
1466 auto const sig3 = rs3[jss::result][jss::signature].
asString();
1467 BEAST_EXPECT(!sig3.empty());
1469 auto const rv = env.
rpc(
"channel_verify", cpk, chan,
"1000", sig3);
1470 BEAST_EXPECT(rv[jss::result][jss::signature_verified].asBool());
1476 auto rs = env.
rpc(
"channel_authorize",
"alice", chan1Str,
"1000x");
1477 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1478 rs = env.
rpc(
"channel_authorize",
"alice", chan1Str,
"x1000");
1479 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1480 rs = env.
rpc(
"channel_authorize",
"alice", chan1Str,
"x");
1481 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1485 args[jss::amount] =
"2000";
1486 args[jss::key_type] =
"secp256k1";
1487 args[jss::passphrase] =
"passphrase_can_be_anything";
1489 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1494 args[jss::channel_id] = chan1Str;
1495 args[jss::key_type] =
"secp256k1";
1496 args[jss::passphrase] =
"passphrase_can_be_anything";
1498 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1503 args[jss::amount] =
"2000";
1504 args[jss::channel_id] = chan1Str;
1505 args[jss::passphrase] =
"passphrase_can_be_anything";
1507 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1512 args[jss::amount] =
"2000";
1513 args[jss::channel_id] = chan1Str;
1514 args[jss::key_type] =
"secp256k1";
1515 args[jss::passphrase] =
"passphrase_can_be_anything";
1516 args[jss::seed] =
"seed can be anything";
1518 BEAST_EXPECT(rs[jss::error] ==
"invalidParams");
1523 args[jss::amount] =
"2000";
1524 args[jss::channel_id] = chan1Str +
"1";
1525 args[jss::key_type] =
"secp256k1";
1526 args[jss::passphrase] =
"passphrase_can_be_anything";
1528 BEAST_EXPECT(rs[jss::error] ==
"channelMalformed");
1533 args[jss::amount] = 2000;
1534 args[jss::channel_id] = chan1Str;
1535 args[jss::key_type] =
"secp256k1";
1536 args[jss::passphrase] =
"passphrase_can_be_anything";
1538 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1543 args[jss::amount] =
"TwoThousand";
1544 args[jss::channel_id] = chan1Str;
1545 args[jss::key_type] =
"secp256k1";
1546 args[jss::passphrase] =
"passphrase_can_be_anything";
1548 BEAST_EXPECT(rs[jss::error] ==
"channelAmtMalformed");
1557 using namespace jtx;
1559 Env env{*
this, features};
1560 auto const alice =
Account(
"alice");
1561 auto const bob =
Account(
"bob");
1562 auto const carol =
Account(
"carol");
1563 auto const dan =
Account(
"dan");
1564 env.
fund(
XRP(10000), alice, bob, carol, dan);
1565 auto const pk = alice.pk();
1566 auto const settleDelay = 3600s;
1567 auto const channelFunds =
XRP(1000);
1573 env(
create(alice, bob, channelFunds, settleDelay, pk));
1574 auto const r = env.
rpc(
"account_channels", alice.human(), bob.human());
1575 BEAST_EXPECT(r[jss::result][jss::channels].
size() == 1);
1576 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1577 BEAST_EXPECT(!r[jss::result][jss::channels][0u].isMember(jss::destination_tag));
1582 env(
create(alice, carol, channelFunds, settleDelay, pk, cancelAfter, dstTag));
1583 auto const r = env.
rpc(
"account_channels", alice.human(), carol.human());
1584 BEAST_EXPECT(r[jss::result][jss::channels].
size() == 1);
1585 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::channel_id] == chan);
1586 BEAST_EXPECT(r[jss::result][jss::channels][0u][jss::destination_tag] == dstTag);
1594 using namespace jtx;
1596 Env env{*
this, features};
1597 auto const alice =
Account(
"alice");
1598 auto const bob =
Account(
"bob");
1599 auto usda = alice[
"USD"];
1600 env.
fund(
XRP(10000), alice, bob);
1601 auto const pk = alice.pk();
1602 auto const settleDelay = 100s;
1604 auto const chan =
channel(alice, bob, env.
seq(alice));
1605 auto jv =
create(alice, bob,
XRP(1000), settleDelay, pk);
1606 auto const pkHex =
strHex(pk.slice());
1607 jv[
"PublicKey"] = pkHex.substr(2, pkHex.size() - 2);
1609 jv[
"PublicKey"] = pkHex.substr(0, pkHex.size() - 2);
1611 auto badPrefix = pkHex;
1614 jv[
"PublicKey"] = badPrefix;
1617 jv[
"PublicKey"] = pkHex;
1620 auto const authAmt =
XRP(100);
1621 auto const sig =
signClaimAuth(alice.pk(), alice.sk(), chan, authAmt);
1622 jv =
claim(bob, chan, authAmt.value(), authAmt.value(),
Slice(sig), alice.pk());
1623 jv[
"PublicKey"] = pkHex.substr(2, pkHex.size() - 2);
1625 jv[
"PublicKey"] = pkHex.substr(0, pkHex.size() - 2);
1630 jv[
"PublicKey"] = badPrefix;
1634 jv.removeMember(
"PublicKey");
1638 auto const txn = R
"*(
1641 "channel_id":"5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
1643 "304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064",
1645 "aKijDDiC2q2gXjMpM7i4BUS6cmixgsEe18e7CjsUxwihKfuoFgS5",
1649 auto const r = env.
rpc(
"json",
"channel_verify", txn);
1650 BEAST_EXPECT(r[
"result"][
"error"] ==
"publicMalformed");
1659 using namespace jtx;
1662 auto const alice =
Account(
"alice");
1663 auto const bob =
Account(
"bob");
1664 auto const settleDelay = 100s;
1665 auto const pk = alice.pk();
1671 return std::find(ownerDir.begin(), ownerDir.end(), chan) != ownerDir.end();
1681 Env env{*
this, features};
1682 env.
fund(
XRP(10000), alice, bob);
1683 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1686 BEAST_EXPECT(inOwnerDir(*env.current(), alice, chanSle));
1687 BEAST_EXPECT(ownerDirCount(*env.current(), alice) == 1);
1688 BEAST_EXPECT(inOwnerDir(*env.current(), bob, chanSle));
1689 BEAST_EXPECT(ownerDirCount(*env.current(), bob) == 1);
1691 env(
claim(bob, chan), Txflags(tfClose));
1693 BEAST_EXPECT(!inOwnerDir(*env.current(), alice, chanSle));
1694 BEAST_EXPECT(ownerDirCount(*env.current(), alice) == 0);
1695 BEAST_EXPECT(!inOwnerDir(*env.current(), bob, chanSle));
1696 BEAST_EXPECT(ownerDirCount(*env.current(), bob) == 0);
1702 Env env(*
this, features);
1703 env.fund(
XRP(10000), alice, bob);
1705 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1708 BEAST_EXPECT(inOwnerDir(*env.current(), alice, chanSle));
1709 BEAST_EXPECT(ownerDirCount(*env.current(), alice) == 1);
1710 BEAST_EXPECT(inOwnerDir(*env.current(), bob, chanSle));
1711 BEAST_EXPECT(ownerDirCount(*env.current(), bob) == 1);
1715 BEAST_EXPECT(!inOwnerDir(*env.current(), alice, chanSle));
1716 BEAST_EXPECT(ownerDirCount(*env.current(), alice) == 0);
1717 BEAST_EXPECT(!inOwnerDir(*env.current(), bob, chanSle));
1718 BEAST_EXPECT(ownerDirCount(*env.current(), bob) == 0);
1733 for (
auto minRmSeq = env.seq(toRm) + 257; env.current()->seq() < minRmSeq;
1739 Fee(
drops(env.current()->fees().increment)),
1746 auto const alice =
Account(
"alice");
1747 auto const bob =
Account(
"bob");
1748 auto const carol =
Account(
"carol");
1751 Env env{*
this, features};
1752 env.fund(
XRP(10000), alice, bob, carol);
1756 auto const pk = alice.pk();
1757 auto const settleDelay = 100s;
1758 auto const chan =
channel(alice, bob, env.seq(alice));
1759 env(
create(alice, bob,
XRP(1000), settleDelay, pk));
1767 auto const feeDrops = env.current()->fees().base;
1770 BEAST_EXPECT(chanBal ==
XRP(0));
1771 BEAST_EXPECT(chanAmt ==
XRP(1000));
1773 auto preBob = env.balance(bob);
1774 auto const delta =
XRP(50);
1775 auto reqBal = chanBal + delta;
1776 auto authAmt = reqBal +
XRP(100);
1777 assert(reqBal <= chanAmt);
1779 env(
claim(alice, chan, reqBal, authAmt));
1782 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
1783 BEAST_EXPECT(env.balance(bob) == preBob + delta);
1786 auto const preAlice = env.balance(alice);
1787 env(
fund(alice, chan,
XRP(1000)));
1789 BEAST_EXPECT(env.balance(alice) == preAlice -
XRP(1000) - feeDrops);
1791 chanAmt = chanAmt +
XRP(1000);
1795 env(
claim(alice, chan), Txflags(tfClose));
1799 auto const closeTime = env.current()->header().parentCloseTime;
1800 auto const minExpiration = closeTime + settleDelay;
1801 env.close(minExpiration);
1812 using namespace jtx;
1814 Env env{*
this, features};
1815 auto const alice =
Account(
"alice");
1816 auto const bob =
Account(
"bob");
1817 auto usda = alice[
"USD"];
1818 env.fund(
XRP(10000), alice, bob);
1823 std::uint32_t aliceTicketSeq{env.seq(alice) + 1};
1825 std::uint32_t
const aliceSeq{env.seq(alice)};
1827 std::uint32_t bobTicketSeq{env.seq(bob) + 1};
1829 std::uint32_t
const bobSeq{env.seq(bob)};
1831 auto const pk = alice.pk();
1832 auto const settleDelay = 100s;
1833 auto const chan =
channel(alice, bob, aliceTicketSeq);
1835 env(
create(alice, bob,
XRP(1000), settleDelay, pk), ticket::Use(aliceTicketSeq++));
1837 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1838 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1844 auto const preAlice = env.balance(alice);
1845 env(
fund(alice, chan,
XRP(1000)), ticket::Use(aliceTicketSeq++));
1847 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1848 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1850 auto const feeDrops = env.current()->fees().base;
1851 BEAST_EXPECT(env.balance(alice) == preAlice -
XRP(1000) - feeDrops);
1856 BEAST_EXPECT(chanBal ==
XRP(0));
1857 BEAST_EXPECT(chanAmt ==
XRP(2000));
1861 auto const preBob = env.balance(bob);
1862 auto const delta =
XRP(500);
1863 auto const reqBal = chanBal + delta;
1864 auto const authAmt = reqBal +
XRP(100);
1865 assert(reqBal <= chanAmt);
1866 env(
claim(alice, chan, reqBal, authAmt), ticket::Use(aliceTicketSeq++));
1868 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1869 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1872 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
1873 BEAST_EXPECT(env.balance(bob) == preBob + delta);
1878 auto preBob = env.balance(bob);
1879 auto const delta =
XRP(500);
1880 auto const reqBal = chanBal + delta;
1881 auto const authAmt = reqBal +
XRP(100);
1882 assert(reqBal <= chanAmt);
1883 auto const sig =
signClaimAuth(alice.pk(), alice.sk(), chan, authAmt);
1884 env(
claim(bob, chan, reqBal, authAmt, Slice(sig), alice.pk()),
1885 ticket::Use(bobTicketSeq++));
1887 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
1888 BEAST_EXPECT(env.seq(bob) == bobSeq);
1891 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
1892 auto const feeDrops = env.current()->fees().base;
1893 BEAST_EXPECT(env.balance(bob) == preBob + delta - feeDrops);
1897 preBob = env.balance(bob);
1899 env(
claim(bob, chan, reqBal, authAmt, Slice(sig), alice.pk()),
1900 ticket::Use(bobTicketSeq++),
1903 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
1904 BEAST_EXPECT(env.seq(bob) == bobSeq);
1907 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
1908 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
1912 auto const preBob = env.balance(bob);
1913 STAmount
const authAmt = chanBal +
XRP(500);
1914 STAmount
const reqAmt = authAmt +
drops(1);
1915 assert(reqAmt <= chanAmt);
1918 auto const sig =
signClaimAuth(alice.pk(), alice.sk(), chan, authAmt);
1919 env(
claim(bob, chan, reqAmt, authAmt, Slice(sig), alice.pk()),
1920 ticket::Use(bobTicketSeq),
1923 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
1924 BEAST_EXPECT(env.seq(bob) == bobSeq);
1927 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
1928 BEAST_EXPECT(env.balance(bob) == preBob);
1934 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
1935 BEAST_EXPECT(env.seq(bob) == bobSeq);
1938 BEAST_EXPECT(
channelAmount(*env.current(), chan) == chanAmt);
1942 auto const preAlice = env.balance(alice);
1943 auto const preBob = env.balance(bob);
1944 env(
claim(bob, chan), Txflags(tfClose), ticket::Use(bobTicketSeq++));
1946 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
1947 BEAST_EXPECT(env.seq(bob) == bobSeq);
1950 auto const feeDrops = env.current()->fees().base;
1951 auto const delta = chanAmt - chanBal;
1952 assert(delta > beast::kZero);
1953 BEAST_EXPECT(env.balance(alice) == preAlice + delta);
1954 BEAST_EXPECT(env.balance(bob) == preBob - feeDrops);
1956 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1957 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1958 env.require(
tickets(bob, env.seq(bob) - bobTicketSeq));
1959 BEAST_EXPECT(env.seq(bob) == bobSeq);
TestcaseT testcase
Memberspace for declaring test cases.
std::string toStyledString() const
std::string asString() const
Returns the unquoted string value.
Like std::vector<char> but better.
A class that simplifies iterating ledger directory pages.
std::chrono::time_point< NetClock > time_point
virtual SLE::const_pointer read(Keylet const &k) const =0
Return the state item associated with a key.
std::shared_ptr< STLedgerEntry const > const & const_ref
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.
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.
json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Set the expected result code for a JTx The test will fail if the code doesn't match.
T emplace_back(T... args)
@ Array
array value (ordered list)
@ Object
object value (collection of name/value pairs).
Keylet payChannel(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
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 create(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 authCredentials(jtx::Account const &account, std::vector< AuthorizeCredentials > const &auth)
json::Value auth(Account const &account, Account const &auth)
Preauthorize for deposit.
json::Value unauth(Account const &account, Account const &unauth)
Remove pre-authorization for deposit.
STAmount channelBalance(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)
bool channelExists(ReadView const &view, uint256 const &chan)
json::Value create(Account const &account, std::uint32_t count)
Create one of more tickets.
std::vector< STAmount > fund(jtx::Env &env, jtx::Account const &gw, std::vector< jtx::Account > const &accounts, std::vector< STAmount > const &amts, Fund how)
XrpT const XRP
Converts to XRP Issue or STAmount.
json::Value fclear(Account const &account, std::uint32_t off)
Remove account flag.
FeatureBitset testableAmendments()
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.
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
OwnerCount< ltTICKET > tickets
Match the number of tickets on the account.
json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
constexpr XRPAmount
Convert XRP to drops (integral types).
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::string strHex(FwdIt begin, FwdIt end)
void serializePayChanAuthorization(Serializer &msg, uint256 const &key, XRPAmount const &amt)
std::string to_string(BaseUInt< Bits, Tag > const &a)
void forAllApiVersions(Fn const &fn, Args &&... args)
static std::string sliceToHex(Slice const &slice)
bool isTesSuccess(TER x) noexcept
TERSubset< CanCvtToTER > TER
void testSettleDelay(FeatureBitset features)
void testOptionalFields(FeatureBitset features)
void testSimple(FeatureBitset features)
void testMetaAndOwnership(FeatureBitset features)
void testMultiple(FeatureBitset features)
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)
static std::pair< uint256, SLE::const_pointer > channelKeyAndSle(ReadView const &view, jtx::Account const &account, jtx::Account const &dst)
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)