98 using namespace test::jtx;
101 cfg->FEES.reference_fee = 10;
115 return j.isMember(jss::result) &&
116 (j[jss::result][jss::status] ==
"success") &&
117 (j[jss::result][jss::transactions].size() == 2) &&
118 (j[jss::result][jss::transactions][0u][jss::tx]
119 [jss::TransactionType] == jss::AccountSet) &&
120 (j[jss::result][jss::transactions][1u][jss::tx]
121 [jss::TransactionType] == jss::Payment) &&
122 (j[jss::result][jss::transactions][1u][jss::tx]
123 [jss::DeliverMax] ==
"10000000010") &&
124 (j[jss::result][jss::transactions][1u][jss::tx]
126 j[jss::result][jss::transactions][1u][jss::tx]
130 if (j.isMember(jss::result) &&
131 (j[jss::result][jss::status] ==
"success") &&
132 (j[jss::result][jss::transactions].size() == 2) &&
133 (j[jss::result][jss::transactions][0u][jss::tx_json]
134 [jss::TransactionType] == jss::AccountSet))
136 auto const& payment =
137 j[jss::result][jss::transactions][1u];
139 return (payment.isMember(jss::tx_json)) &&
140 (payment[jss::tx_json][jss::TransactionType] ==
142 (payment[jss::tx_json][jss::DeliverMax] ==
144 (!payment[jss::tx_json].isMember(jss::Amount)) &&
145 (!payment[jss::tx_json].isMember(jss::hash)) &&
146 (payment[jss::hash] ==
147 "9F3085D85F472D1CC29627F260DF68EDE59D42D1D0C33E345"
148 "ECF0D4CE981D0A8") &&
149 (payment[jss::validated] ==
true) &&
150 (payment[jss::ledger_index] == 3) &&
151 (payment[jss::ledger_hash] ==
152 "5476DCD816EA04CBBA57D47BBF1FC58A5217CC93A5ADD79CB"
153 "580A5AFDD727E33") &&
154 (payment[jss::close_time_iso] ==
155 "2000-01-01T00:00:10Z");
166 return j.isMember(jss::result) &&
167 (j[jss::result][jss::status] ==
"success") &&
168 (j[jss::result][jss::transactions].size() == 0);
173 j[jss::result].
isMember(jss::error) &&
178 jParams[jss::api_version] = apiVersion;
184 jParams[jss::account] =
"0xDEADBEEF";
190 jParams[jss::account] = A1.human();
192 env.
rpc(apiVersion,
"json",
"account_tx",
to_string(jParams))));
197 p[jss::ledger_index_min] = -1;
198 p[jss::ledger_index_max] = -1;
200 env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
202 p[jss::ledger_index_min] = 0;
203 p[jss::ledger_index_max] = 100;
206 env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
212 p[jss::ledger_index_min] = 1;
213 p[jss::ledger_index_max] = 2;
222 p[jss::ledger_index_min] = 2;
223 p[jss::ledger_index_max] = 1;
232 p[jss::ledger_index_min] = -1;
234 env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
236 p[jss::ledger_index_min] = 1;
239 env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
245 p[jss::ledger_index_min] = env.
current()->info().seq;
255 p[jss::ledger_index_max] = -1;
257 env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
259 p[jss::ledger_index_max] = env.
current()->info().seq;
262 env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
268 p[jss::ledger_index_max] = 3;
270 env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
272 p[jss::ledger_index_max] = env.
closed()->info().seq;
274 env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
276 p[jss::ledger_index_max] = env.
closed()->info().seq - 1;
277 BEAST_EXPECT(noTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
284 p[jss::ledger_index] = env.
closed()->info().seq;
286 env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
288 p[jss::ledger_index] = env.
closed()->info().seq - 1;
289 BEAST_EXPECT(noTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
291 p[jss::ledger_index] = env.
current()->info().seq;
296 p[jss::ledger_index] = env.
current()->info().seq + 1;
307 env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
310 BEAST_EXPECT(noTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
316 jParams[jss::account] =
"0xDEADBEEF";
317 jParams[jss::account] = A1.human();
320 p[jss::ledger_index_max] = -1;
321 p[jss::ledger_index_min] = -1;
322 p[jss::ledger_index] = -1;
326 env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
336 p[jss::ledger_index_max] = env.
current()->info().seq;
339 env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
347 auto testInvalidAccountParam = [&](
auto const& param) {
349 params[jss::account] = param;
351 "json",
"account_tx",
to_string(params))[jss::result];
352 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
354 jrr[jss::error_message] ==
"Invalid field 'account'.");
357 testInvalidAccountParam(1);
358 testInvalidAccountParam(1.1);
359 testInvalidAccountParam(
true);
367 p[jss::binary] =
"asdf";
371 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
378 p[jss::binary] =
true;
380 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
382 p[jss::forward] =
"true";
384 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
390 p[jss::forward] =
false;
392 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
410 to_string(p))[jss::result][jss::error_message] ==
414 p[jss::limit] =
"10";
419 to_string(p))[jss::result][jss::error_message] ==
423 p[jss::limit] =
true;
428 to_string(p))[jss::result][jss::error_message] ==
432 p[jss::limit] =
false;
437 to_string(p))[jss::result][jss::error_message] ==
446 to_string(p))[jss::result][jss::error_message] ==
455 to_string(p))[jss::result][jss::error_message] ==
464 to_string(p))[jss::result][jss::error_message] ==
468 p[jss::limit] =
"malformed";
473 to_string(p))[jss::result][jss::error_message] ==
478 p[jss::limit].append(
"limit");
483 to_string(p))[jss::result][jss::error_message] ==
489 p[jss::limit][jss::limit] = 10;
494 to_string(p))[jss::result][jss::error_message] ==
503 to_string(p))[jss::result][jss::status] ==
"success");
514 using namespace test::jtx;
515 using namespace std::chrono_literals;
521 auto const USD{gw[
"USD"]};
523 env.
fund(
XRP(1000000), alice, gw);
530 env(
pay(alice, gw,
XRP(100)));
537 env(
trust(alice, USD(200)),
sig(alie));
546 env(
signers(alice, 1, {{
"bogie", 1}, {
"demon", 1}}),
sig(alie));
551 auto escrow = [](
Account const& account,
555 escro[jss::TransactionType] = jss::EscrowCreate;
556 escro[jss::Account] = account.human();
557 escro[jss::Destination] = to.human();
565 escrowWithFinish[sfFinishAfter.jsonName] =
566 nextTime.time_since_epoch().count();
569 env(escrowWithFinish,
sig(alie));
572 escrowWithCancel[sfFinishAfter.jsonName] =
573 nextTime.time_since_epoch().count();
574 escrowWithCancel[sfCancelAfter.jsonName] =
575 nextTime.time_since_epoch().count() + 1;
578 env(escrowWithCancel,
sig(alie));
583 escrowFinish[jss::TransactionType] = jss::EscrowFinish;
584 escrowFinish[jss::Account] = alice.human();
585 escrowFinish[sfOwner.jsonName] = alice.human();
586 escrowFinish[sfOfferSequence.jsonName] = escrowFinishSeq;
587 env(escrowFinish,
sig(alie));
591 escrowCancel[jss::TransactionType] = jss::EscrowCancel;
592 escrowCancel[jss::Account] = alice.human();
593 escrowCancel[sfOwner.jsonName] = alice.human();
594 escrowCancel[sfOfferSequence.jsonName] = escrowCancelSeq;
595 env(escrowCancel,
sig(alie));
604 payChanCreate[jss::TransactionType] = jss::PaymentChannelCreate;
605 payChanCreate[jss::Account] = alice.human();
606 payChanCreate[jss::Destination] = gw.human();
607 payChanCreate[jss::Amount] =
609 payChanCreate[sfSettleDelay.jsonName] =
611 payChanCreate[sfPublicKey.jsonName] =
strHex(alice.pk().slice());
612 env(payChanCreate,
sig(alie));
620 payChanFund[jss::TransactionType] = jss::PaymentChannelFund;
621 payChanFund[jss::Account] = alice.human();
622 payChanFund[sfChannel.jsonName] = payChanIndex;
623 payChanFund[jss::Amount] =
625 env(payChanFund,
sig(alie));
630 payChanClaim[jss::TransactionType] = jss::PaymentChannelClaim;
631 payChanClaim[jss::Flags] =
tfClose;
632 payChanClaim[jss::Account] = gw.human();
633 payChanClaim[sfChannel.jsonName] = payChanIndex;
634 payChanClaim[sfPublicKey.jsonName] =
strHex(alice.pk().slice());
665 params[jss::account] = alice.human();
666 params[jss::ledger_index_min] = -1;
667 params[jss::ledger_index_max] = -1;
672 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
673 BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
675 Json::Value const& txs{result[jss::result][jss::transactions]};
682 {0, jss::DepositPreauth, {jss::DepositPreauth}, {jss::Ticket}, {jss::AccountRoot, jss::DirectoryNode}},
683 {1, jss::TicketCreate, {jss::Ticket}, {}, {jss::AccountRoot, jss::DirectoryNode}},
684 {2, jss::CheckCancel, {}, {jss::Check}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
685 {3, jss::CheckCash, {}, {jss::Check}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
686 {4, jss::CheckCreate, {jss::Check}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
687 {5, jss::CheckCreate, {jss::Check}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
688 {6, jss::PaymentChannelClaim, {}, {jss::PayChannel}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
689 {7, jss::PaymentChannelFund, {}, {}, {jss::AccountRoot, jss::PayChannel}},
690 {8, jss::PaymentChannelCreate, {jss::PayChannel}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
691 {9, jss::EscrowCancel, {}, {jss::Escrow}, {jss::AccountRoot, jss::DirectoryNode}},
692 {10, jss::EscrowFinish, {}, {jss::Escrow}, {jss::AccountRoot, jss::DirectoryNode}},
693 {11, jss::EscrowCreate, {jss::Escrow}, {}, {jss::AccountRoot, jss::DirectoryNode}},
694 {12, jss::EscrowCreate, {jss::Escrow}, {}, {jss::AccountRoot, jss::DirectoryNode}},
695 {13, jss::SignerListSet, {jss::SignerList}, {}, {jss::AccountRoot, jss::DirectoryNode}},
696 {14, jss::OfferCancel, {}, {jss::Offer, jss::DirectoryNode}, {jss::AccountRoot, jss::DirectoryNode}},
697 {15, jss::OfferCreate, {jss::Offer, jss::DirectoryNode}, {}, {jss::AccountRoot, jss::DirectoryNode}},
698 {16, jss::TrustSet, {jss::RippleState, jss::DirectoryNode, jss::DirectoryNode}, {}, {jss::AccountRoot, jss::AccountRoot}},
699 {17, jss::SetRegularKey, {}, {}, {jss::AccountRoot}},
700 {18, jss::Payment, {}, {}, {jss::AccountRoot, jss::AccountRoot}},
701 {19, jss::AccountSet, {}, {}, {jss::AccountRoot}},
702 {20, jss::AccountSet, {}, {}, {jss::AccountRoot}},
703 {21, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}},
708 std::size(sanity) == result[jss::result][jss::transactions].size());
710 for (
unsigned int index{0}; index <
std::size(sanity); ++index)
724 using namespace test::jtx;
725 using namespace std::chrono_literals;
731 env.
fund(
XRP(10000), alice, becky);
736 BEAST_EXPECT(env.
closed()->exists(beckyAcctKey));
748 auto const beckyPreDelBalance{env.
balance(becky)};
750 auto const acctDelFee{
drops(env.
current()->fees().increment)};
755 BEAST_EXPECT(!env.
closed()->exists(beckyAcctKey));
767 { 0, jss::Payment, {}, {}, {jss::AccountRoot, jss::AccountRoot}},
768 { 1, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}},
769 { 2, jss::AccountDelete, {}, {jss::AccountRoot}, {jss::AccountRoot}},
770 { 3, jss::AccountSet, {}, {}, {jss::AccountRoot}},
771 { 4, jss::AccountSet, {}, {}, {jss::AccountRoot}},
772 { 5, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}}
780 params[jss::account] = becky.human();
781 params[jss::ledger_index_min] = -1;
782 params[jss::ledger_index_max] = -1;
787 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
788 BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
791 constexpr unsigned int beckyDeletedOffest = 2;
794 result[jss::result][jss::transactions].size() +
797 Json::Value const& txs{result[jss::result][jss::transactions]};
799 for (
unsigned int index = beckyDeletedOffest;
803 checkSanity(txs[index - beckyDeletedOffest], sanity[index]);
816 env(
pay(alice, becky,
XRP(45)));
820 BEAST_EXPECT(env.
closed()->exists(beckyAcctKey));
824 env(
pay(becky, alice,
XRP(20)));
830 params[jss::account] = becky.human();
831 params[jss::ledger_index_min] = -1;
832 params[jss::ledger_index_max] = -1;
837 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
838 BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
841 std::size(sanity) == result[jss::result][jss::transactions].size());
843 Json::Value const& txs{result[jss::result][jss::transactions]};
845 for (
unsigned int index = 0; index <
std::size(sanity); ++index)
856 using namespace test::jtx;
857 using namespace std::chrono_literals;
860 cfg->FEES.reference_fee = 10;
861 Env env(*
this, std::move(cfg));
867 MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
870 auto const checkAliceAcctTx = [&](
size_t size,
873 params[jss::account] = alice.human();
874 params[jss::limit] = 100;
876 env.
rpc(
"json",
"account_tx",
to_string(params))[jss::result];
878 BEAST_EXPECT(jv[jss::transactions].size() == size);
879 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
880 BEAST_EXPECT(tx0[jss::TransactionType] == txType);
884 BEAST_EXPECT(tx0[jss::hash] == txHash);
893 checkAliceAcctTx(3, jss::MPTokenIssuanceCreate);
896 mptAlice.authorize({.account = bob});
897 checkAliceAcctTx(4, jss::MPTokenAuthorize);
910 mptAlice.authorize({.account = alice, .holder = bob});
911 checkAliceAcctTx(5, jss::MPTokenAuthorize);
914 mptAlice.authorize({.account = carol});
915 checkAliceAcctTx(6, jss::MPTokenAuthorize);
918 mptAlice.authorize({.account = alice, .holder = carol});
919 checkAliceAcctTx(7, jss::MPTokenAuthorize);
922 mptAlice.pay(alice, bob, 100);
923 checkAliceAcctTx(8, jss::Payment);
926 mptAlice.pay(bob, carol, 10);
927 checkAliceAcctTx(9, jss::Payment);