94 using namespace test::jtx;
97 cfg->FEES.reference_fee = 10;
111 return j.isMember(jss::result) && (j[jss::result][jss::status] ==
"success") &&
112 (j[jss::result][jss::transactions].size() == 2) &&
113 (j[jss::result][jss::transactions][0u][jss::tx][jss::TransactionType] ==
115 (j[jss::result][jss::transactions][1u][jss::tx][jss::TransactionType] ==
117 (j[jss::result][jss::transactions][1u][jss::tx][jss::DeliverMax] ==
119 (j[jss::result][jss::transactions][1u][jss::tx][jss::Amount] ==
120 j[jss::result][jss::transactions][1u][jss::tx][jss::DeliverMax]);
123 if (j.isMember(jss::result) && (j[jss::result][jss::status] ==
"success") &&
124 (j[jss::result][jss::transactions].size() == 2) &&
125 (j[jss::result][jss::transactions][0u][jss::tx_json]
126 [jss::TransactionType] == jss::AccountSet))
128 auto const& payment = j[jss::result][jss::transactions][1u];
130 return (payment.isMember(jss::tx_json)) &&
131 (payment[jss::tx_json][jss::TransactionType] == jss::Payment) &&
132 (payment[jss::tx_json][jss::DeliverMax] ==
"10000000010") &&
133 (!payment[jss::tx_json].isMember(jss::Amount)) &&
134 (!payment[jss::tx_json].isMember(jss::hash)) &&
135 (payment[jss::hash] ==
136 "9F3085D85F472D1CC29627F260DF68EDE59D42D1D0C33E345"
137 "ECF0D4CE981D0A8") &&
138 (payment[jss::validated] ==
true) &&
139 (payment[jss::ledger_index] == 3) &&
140 (payment[jss::ledger_hash] ==
141 "5476DCD816EA04CBBA57D47BBF1FC58A5217CC93A5ADD79CB"
142 "580A5AFDD727E33") &&
143 (payment[jss::close_time_iso] ==
"2000-01-01T00:00:10Z");
156 return j.isMember(jss::result) && (j[jss::result][jss::status] ==
"success") &&
157 (j[jss::result][jss::transactions].size() == 0);
166 jParams[jss::api_version] = apiVersion;
170 jParams[jss::account] =
"0xDEADBEEF";
174 jParams[jss::account] = A1.human();
175 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(jParams))));
180 p[jss::ledger_index_min] = -1;
181 p[jss::ledger_index_max] = -1;
182 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
184 p[jss::ledger_index_min] = 0;
185 p[jss::ledger_index_max] = 100;
188 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
196 p[jss::ledger_index_min] = 1;
197 p[jss::ledger_index_max] = 2;
200 BEAST_EXPECT(noTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
208 p[jss::ledger_index_min] = 2;
209 p[jss::ledger_index_max] = 1;
217 p[jss::ledger_index_min] = -1;
218 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
220 p[jss::ledger_index_min] = 1;
223 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
231 p[jss::ledger_index_min] = env.
current()->header().seq;
240 p[jss::ledger_index_max] = -1;
241 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
243 p[jss::ledger_index_max] = env.
current()->header().seq;
246 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
254 p[jss::ledger_index_max] = 3;
255 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
257 p[jss::ledger_index_max] = env.
closed()->header().seq;
258 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
260 p[jss::ledger_index_max] = env.
closed()->header().seq - 1;
261 BEAST_EXPECT(noTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
268 p[jss::ledger_index] = env.
closed()->header().seq;
269 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
271 p[jss::ledger_index] = env.
closed()->header().seq - 1;
272 BEAST_EXPECT(noTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
274 p[jss::ledger_index] = env.
current()->header().seq;
277 p[jss::ledger_index] = env.
current()->header().seq + 1;
286 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
289 BEAST_EXPECT(noTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
295 jParams[jss::account] =
"0xDEADBEEF";
296 jParams[jss::account] = A1.human();
299 p[jss::ledger_index_max] = -1;
300 p[jss::ledger_index_min] = -1;
301 p[jss::ledger_index] = -1;
305 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
316 p[jss::ledger_index_max] = env.
current()->header().seq;
319 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
329 auto testInvalidAccountParam = [&](
auto const& param) {
331 params[jss::account] = param;
332 auto jrr = env.
rpc(
"json",
"account_tx",
to_string(params))[jss::result];
333 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
334 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'account'.");
337 testInvalidAccountParam(1);
338 testInvalidAccountParam(1.1);
339 testInvalidAccountParam(
true);
347 p[jss::binary] =
"asdf";
351 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
358 p[jss::binary] =
true;
360 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
362 p[jss::forward] =
"true";
365 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
372 p[jss::forward] =
false;
374 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
387 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
391 p[jss::limit] =
"10";
393 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
397 p[jss::limit] =
true;
399 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
403 p[jss::limit] =
false;
405 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
411 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
417 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
423 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
427 p[jss::limit] =
"malformed";
429 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
434 p[jss::limit].append(
"limit");
436 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
442 p[jss::limit][jss::limit] = 10;
444 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
450 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::status] ==
"success");
461 using namespace test::jtx;
462 using namespace std::chrono_literals;
468 auto const USD{gw[
"USD"]};
470 env.
fund(
XRP(1000000), alice, gw);
477 env(
pay(alice, gw,
XRP(100)));
484 env(
trust(alice, USD(200)),
sig(alie));
493 env(
signers(alice, 1, {{
"bogie", 1}, {
"demon", 1}}),
sig(alie));
500 escrow[jss::TransactionType] = jss::EscrowCreate;
501 escrow[jss::Account] = account.human();
502 escrow[jss::Destination] = to.human();
510 escrowWithFinish[sfFinishAfter.jsonName] = nextTime.time_since_epoch().count();
513 env(escrowWithFinish,
sig(alie));
516 escrowWithCancel[sfFinishAfter.jsonName] = nextTime.time_since_epoch().count();
517 escrowWithCancel[sfCancelAfter.jsonName] = nextTime.time_since_epoch().count() + 1;
520 env(escrowWithCancel,
sig(alie));
525 escrowFinish[jss::TransactionType] = jss::EscrowFinish;
526 escrowFinish[jss::Account] = alice.human();
527 escrowFinish[sfOwner.jsonName] = alice.human();
528 escrowFinish[sfOfferSequence.jsonName] = escrowFinishSeq;
529 env(escrowFinish,
sig(alie));
533 escrowCancel[jss::TransactionType] = jss::EscrowCancel;
534 escrowCancel[jss::Account] = alice.human();
535 escrowCancel[sfOwner.jsonName] = alice.human();
536 escrowCancel[sfOfferSequence.jsonName] = escrowCancelSeq;
537 env(escrowCancel,
sig(alie));
546 payChanCreate[jss::TransactionType] = jss::PaymentChannelCreate;
547 payChanCreate[jss::Account] = alice.human();
548 payChanCreate[jss::Destination] = gw.human();
551 payChanCreate[sfPublicKey.jsonName] =
strHex(alice.pk().slice());
552 env(payChanCreate,
sig(alie));
559 payChanFund[jss::TransactionType] = jss::PaymentChannelFund;
560 payChanFund[jss::Account] = alice.human();
561 payChanFund[sfChannel.jsonName] = payChanIndex;
563 env(payChanFund,
sig(alie));
568 payChanClaim[jss::TransactionType] = jss::PaymentChannelClaim;
569 payChanClaim[jss::Flags] = tfClose;
570 payChanClaim[jss::Account] = gw.human();
571 payChanClaim[sfChannel.jsonName] = payChanIndex;
572 payChanClaim[sfPublicKey.jsonName] =
strHex(alice.pk().slice());
603 params[jss::account] = alice.human();
604 params[jss::ledger_index_min] = -1;
605 params[jss::ledger_index_max] = -1;
609 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
610 BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
612 Json::Value const& txs{result[jss::result][jss::transactions]};
619 {0, jss::DepositPreauth, {jss::DepositPreauth}, {jss::Ticket}, {jss::AccountRoot, jss::DirectoryNode}},
620 {1, jss::TicketCreate, {jss::Ticket}, {}, {jss::AccountRoot, jss::DirectoryNode}},
621 {2, jss::CheckCancel, {}, {jss::Check}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
622 {3, jss::CheckCash, {}, {jss::Check}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
623 {4, jss::CheckCreate, {jss::Check}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
624 {5, jss::CheckCreate, {jss::Check}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
625 {6, jss::PaymentChannelClaim, {}, {jss::PayChannel}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
626 {7, jss::PaymentChannelFund, {}, {}, {jss::AccountRoot, jss::PayChannel}},
627 {8, jss::PaymentChannelCreate, {jss::PayChannel}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
628 {9, jss::EscrowCancel, {}, {jss::Escrow}, {jss::AccountRoot, jss::DirectoryNode}},
629 {10, jss::EscrowFinish, {}, {jss::Escrow}, {jss::AccountRoot, jss::DirectoryNode}},
630 {11, jss::EscrowCreate, {jss::Escrow}, {}, {jss::AccountRoot, jss::DirectoryNode}},
631 {12, jss::EscrowCreate, {jss::Escrow}, {}, {jss::AccountRoot, jss::DirectoryNode}},
632 {13, jss::SignerListSet, {jss::SignerList}, {}, {jss::AccountRoot, jss::DirectoryNode}},
633 {14, jss::OfferCancel, {}, {jss::Offer, jss::DirectoryNode}, {jss::AccountRoot, jss::DirectoryNode}},
634 {15, jss::OfferCreate, {jss::Offer, jss::DirectoryNode}, {}, {jss::AccountRoot, jss::DirectoryNode}},
635 {16, jss::TrustSet, {jss::RippleState, jss::DirectoryNode, jss::DirectoryNode}, {}, {jss::AccountRoot, jss::AccountRoot}},
636 {17, jss::SetRegularKey, {}, {}, {jss::AccountRoot}},
637 {18, jss::Payment, {}, {}, {jss::AccountRoot, jss::AccountRoot}},
638 {19, jss::AccountSet, {}, {}, {jss::AccountRoot}},
639 {20, jss::AccountSet, {}, {}, {jss::AccountRoot}},
640 {21, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}},
644 BEAST_EXPECT(
std::size(sanity) == result[jss::result][jss::transactions].size());
646 for (
unsigned int index{0}; index <
std::size(sanity); ++index)
660 using namespace test::jtx;
661 using namespace std::chrono_literals;
667 env.
fund(
XRP(10000), alice, becky);
672 BEAST_EXPECT(env.
closed()->exists(beckyAcctKey));
683 auto const beckyPreDelBalance{env.
balance(becky)};
685 auto const acctDelFee{
drops(env.
current()->fees().increment)};
690 BEAST_EXPECT(!env.
closed()->exists(beckyAcctKey));
702 { 0, jss::Payment, {}, {}, {jss::AccountRoot, jss::AccountRoot}},
703 { 1, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}},
704 { 2, jss::AccountDelete, {}, {jss::AccountRoot}, {jss::AccountRoot}},
705 { 3, jss::AccountSet, {}, {}, {jss::AccountRoot}},
706 { 4, jss::AccountSet, {}, {}, {jss::AccountRoot}},
707 { 5, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}}
715 params[jss::account] = becky.human();
716 params[jss::ledger_index_min] = -1;
717 params[jss::ledger_index_max] = -1;
721 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
722 BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
725 constexpr unsigned int beckyDeletedOffset = 2;
728 result[jss::result][jss::transactions].size() + beckyDeletedOffset);
730 Json::Value const& txs{result[jss::result][jss::transactions]};
732 for (
unsigned int index = beckyDeletedOffset; index <
std::size(sanity); ++index)
734 checkSanity(txs[index - beckyDeletedOffset], sanity[index]);
745 env(
pay(alice, becky,
XRP(45)));
749 BEAST_EXPECT(env.
closed()->exists(beckyAcctKey));
753 env(
pay(becky, alice,
XRP(20)));
759 params[jss::account] = becky.human();
760 params[jss::ledger_index_min] = -1;
761 params[jss::ledger_index_max] = -1;
765 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
766 BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
768 BEAST_EXPECT(
std::size(sanity) == result[jss::result][jss::transactions].size());
770 Json::Value const& txs{result[jss::result][jss::transactions]};
772 for (
unsigned int index = 0; index <
std::size(sanity); ++index)
783 using namespace test::jtx;
784 using namespace std::chrono_literals;
787 cfg->FEES.reference_fee = 10;
788 Env env(*
this, std::move(cfg));
794 MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
799 params[jss::account] = alice.human();
800 params[jss::limit] = 100;
801 auto const jv = env.
rpc(
"json",
"account_tx",
to_string(params))[jss::result];
803 BEAST_EXPECT(jv[jss::transactions].size() == size);
804 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
805 BEAST_EXPECT(tx0[jss::TransactionType] == txType);
808 BEAST_EXPECT(tx0[jss::hash] == txHash);
815 .flags = tfMPTCanClawback | tfMPTRequireAuth | tfMPTCanTransfer});
817 checkAliceAcctTx(3, jss::MPTokenIssuanceCreate);
820 mptAlice.authorize({.account = bob});
821 checkAliceAcctTx(4, jss::MPTokenAuthorize);
834 mptAlice.authorize({.account = alice, .holder = bob});
835 checkAliceAcctTx(5, jss::MPTokenAuthorize);
838 mptAlice.authorize({.account = carol});
839 checkAliceAcctTx(6, jss::MPTokenAuthorize);
842 mptAlice.authorize({.account = alice, .holder = carol});
843 checkAliceAcctTx(7, jss::MPTokenAuthorize);
846 mptAlice.pay(alice, bob, 100);
847 checkAliceAcctTx(8, jss::Payment);
850 mptAlice.pay(bob, carol, 10);
851 checkAliceAcctTx(9, jss::Payment);