86 using namespace test::jtx;
89 cfg->FEES.reference_fee = 10;
103 return j.isMember(jss::result) && (j[jss::result][jss::status] ==
"success") &&
104 (j[jss::result][jss::transactions].size() == 2) &&
105 (j[jss::result][jss::transactions][0u][jss::tx][jss::TransactionType] == jss::AccountSet) &&
106 (j[jss::result][jss::transactions][1u][jss::tx][jss::TransactionType] == jss::Payment) &&
107 (j[jss::result][jss::transactions][1u][jss::tx][jss::DeliverMax] ==
"10000000010") &&
108 (j[jss::result][jss::transactions][1u][jss::tx][jss::Amount] ==
109 j[jss::result][jss::transactions][1u][jss::tx][jss::DeliverMax]);
112 if (j.isMember(jss::result) && (j[jss::result][jss::status] ==
"success") &&
113 (j[jss::result][jss::transactions].size() == 2) &&
114 (j[jss::result][jss::transactions][0u][jss::tx_json][jss::TransactionType] == jss::AccountSet))
116 auto const& payment = j[jss::result][jss::transactions][1u];
118 return (payment.isMember(jss::tx_json)) &&
119 (payment[jss::tx_json][jss::TransactionType] == jss::Payment) &&
120 (payment[jss::tx_json][jss::DeliverMax] ==
"10000000010") &&
121 (!payment[jss::tx_json].isMember(jss::Amount)) &&
122 (!payment[jss::tx_json].isMember(jss::hash)) &&
123 (payment[jss::hash] ==
124 "9F3085D85F472D1CC29627F260DF68EDE59D42D1D0C33E345"
125 "ECF0D4CE981D0A8") &&
126 (payment[jss::validated] ==
true) && (payment[jss::ledger_index] == 3) &&
127 (payment[jss::ledger_hash] ==
128 "5476DCD816EA04CBBA57D47BBF1FC58A5217CC93A5ADD79CB"
129 "580A5AFDD727E33") &&
130 (payment[jss::close_time_iso] ==
"2000-01-01T00:00:10Z");
141 return j.isMember(jss::result) && (j[jss::result][jss::status] ==
"success") &&
142 (j[jss::result][jss::transactions].size() == 0);
151 jParams[jss::api_version] = apiVersion;
155 jParams[jss::account] =
"0xDEADBEEF";
159 jParams[jss::account] = A1.human();
160 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(jParams))));
165 p[jss::ledger_index_min] = -1;
166 p[jss::ledger_index_max] = -1;
167 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
169 p[jss::ledger_index_min] = 0;
170 p[jss::ledger_index_max] = 100;
172 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
176 p[jss::ledger_index_min] = 1;
177 p[jss::ledger_index_max] = 2;
179 BEAST_EXPECT(noTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
183 p[jss::ledger_index_min] = 2;
184 p[jss::ledger_index_max] = 1;
192 p[jss::ledger_index_min] = -1;
193 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
195 p[jss::ledger_index_min] = 1;
197 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
201 p[jss::ledger_index_min] = env.
current()->header().seq;
210 p[jss::ledger_index_max] = -1;
211 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
213 p[jss::ledger_index_max] = env.
current()->header().seq;
215 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
219 p[jss::ledger_index_max] = 3;
220 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
222 p[jss::ledger_index_max] = env.
closed()->header().seq;
223 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
225 p[jss::ledger_index_max] = env.
closed()->header().seq - 1;
226 BEAST_EXPECT(noTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
233 p[jss::ledger_index] = env.
closed()->header().seq;
234 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
236 p[jss::ledger_index] = env.
closed()->header().seq - 1;
237 BEAST_EXPECT(noTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
239 p[jss::ledger_index] = env.
current()->header().seq;
242 p[jss::ledger_index] = env.
current()->header().seq + 1;
251 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
254 BEAST_EXPECT(noTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
260 jParams[jss::account] =
"0xDEADBEEF";
261 jParams[jss::account] = A1.human();
264 p[jss::ledger_index_max] = -1;
265 p[jss::ledger_index_min] = -1;
266 p[jss::ledger_index] = -1;
269 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
277 p[jss::ledger_index_max] = env.
current()->header().seq;
279 BEAST_EXPECT(hasTxs(env.
rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
285 auto testInvalidAccountParam = [&](
auto const& param) {
287 params[jss::account] = param;
288 auto jrr = env.
rpc(
"json",
"account_tx",
to_string(params))[jss::result];
289 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
290 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'account'.");
293 testInvalidAccountParam(1);
294 testInvalidAccountParam(1.1);
295 testInvalidAccountParam(
true);
303 p[jss::binary] =
"asdf";
307 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
312 p[jss::binary] =
true;
314 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
316 p[jss::forward] =
"true";
318 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
322 p[jss::forward] =
false;
324 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
337 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
341 p[jss::limit] =
"10";
343 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
347 p[jss::limit] =
true;
349 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
353 p[jss::limit] =
false;
355 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
361 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
367 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
373 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
377 p[jss::limit] =
"malformed";
379 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
384 p[jss::limit].append(
"limit");
386 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
392 p[jss::limit][jss::limit] = 10;
394 env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
399 BEAST_EXPECT(env.
rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::status] ==
"success");
410 using namespace test::jtx;
411 using namespace std::chrono_literals;
417 auto const USD{gw[
"USD"]};
419 env.
fund(
XRP(1000000), alice, gw);
426 env(
pay(alice, gw,
XRP(100)));
433 env(
trust(alice, USD(200)),
sig(alie));
442 env(
signers(alice, 1, {{
"bogie", 1}, {
"demon", 1}}),
sig(alie));
449 escrow[jss::TransactionType] = jss::EscrowCreate;
450 escrow[jss::Account] = account.human();
451 escrow[jss::Destination] = to.human();
459 escrowWithFinish[sfFinishAfter.jsonName] = nextTime.time_since_epoch().count();
462 env(escrowWithFinish,
sig(alie));
465 escrowWithCancel[sfFinishAfter.jsonName] = nextTime.time_since_epoch().count();
466 escrowWithCancel[sfCancelAfter.jsonName] = nextTime.time_since_epoch().count() + 1;
469 env(escrowWithCancel,
sig(alie));
474 escrowFinish[jss::TransactionType] = jss::EscrowFinish;
475 escrowFinish[jss::Account] = alice.human();
476 escrowFinish[sfOwner.jsonName] = alice.human();
477 escrowFinish[sfOfferSequence.jsonName] = escrowFinishSeq;
478 env(escrowFinish,
sig(alie));
482 escrowCancel[jss::TransactionType] = jss::EscrowCancel;
483 escrowCancel[jss::Account] = alice.human();
484 escrowCancel[sfOwner.jsonName] = alice.human();
485 escrowCancel[sfOfferSequence.jsonName] = escrowCancelSeq;
486 env(escrowCancel,
sig(alie));
495 payChanCreate[jss::TransactionType] = jss::PaymentChannelCreate;
496 payChanCreate[jss::Account] = alice.human();
497 payChanCreate[jss::Destination] = gw.human();
500 payChanCreate[sfPublicKey.jsonName] =
strHex(alice.pk().slice());
501 env(payChanCreate,
sig(alie));
508 payChanFund[jss::TransactionType] = jss::PaymentChannelFund;
509 payChanFund[jss::Account] = alice.human();
510 payChanFund[sfChannel.jsonName] = payChanIndex;
512 env(payChanFund,
sig(alie));
517 payChanClaim[jss::TransactionType] = jss::PaymentChannelClaim;
518 payChanClaim[jss::Flags] =
tfClose;
519 payChanClaim[jss::Account] = gw.human();
520 payChanClaim[sfChannel.jsonName] = payChanIndex;
521 payChanClaim[sfPublicKey.jsonName] =
strHex(alice.pk().slice());
552 params[jss::account] = alice.human();
553 params[jss::ledger_index_min] = -1;
554 params[jss::ledger_index_max] = -1;
558 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
559 BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
561 Json::Value const& txs{result[jss::result][jss::transactions]};
568 {0, jss::DepositPreauth, {jss::DepositPreauth}, {jss::Ticket}, {jss::AccountRoot, jss::DirectoryNode}},
569 {1, jss::TicketCreate, {jss::Ticket}, {}, {jss::AccountRoot, jss::DirectoryNode}},
570 {2, jss::CheckCancel, {}, {jss::Check}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
571 {3, jss::CheckCash, {}, {jss::Check}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
572 {4, jss::CheckCreate, {jss::Check}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
573 {5, jss::CheckCreate, {jss::Check}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
574 {6, jss::PaymentChannelClaim, {}, {jss::PayChannel}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
575 {7, jss::PaymentChannelFund, {}, {}, {jss::AccountRoot, jss::PayChannel}},
576 {8, jss::PaymentChannelCreate, {jss::PayChannel}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
577 {9, jss::EscrowCancel, {}, {jss::Escrow}, {jss::AccountRoot, jss::DirectoryNode}},
578 {10, jss::EscrowFinish, {}, {jss::Escrow}, {jss::AccountRoot, jss::DirectoryNode}},
579 {11, jss::EscrowCreate, {jss::Escrow}, {}, {jss::AccountRoot, jss::DirectoryNode}},
580 {12, jss::EscrowCreate, {jss::Escrow}, {}, {jss::AccountRoot, jss::DirectoryNode}},
581 {13, jss::SignerListSet, {jss::SignerList}, {}, {jss::AccountRoot, jss::DirectoryNode}},
582 {14, jss::OfferCancel, {}, {jss::Offer, jss::DirectoryNode}, {jss::AccountRoot, jss::DirectoryNode}},
583 {15, jss::OfferCreate, {jss::Offer, jss::DirectoryNode}, {}, {jss::AccountRoot, jss::DirectoryNode}},
584 {16, jss::TrustSet, {jss::RippleState, jss::DirectoryNode, jss::DirectoryNode}, {}, {jss::AccountRoot, jss::AccountRoot}},
585 {17, jss::SetRegularKey, {}, {}, {jss::AccountRoot}},
586 {18, jss::Payment, {}, {}, {jss::AccountRoot, jss::AccountRoot}},
587 {19, jss::AccountSet, {}, {}, {jss::AccountRoot}},
588 {20, jss::AccountSet, {}, {}, {jss::AccountRoot}},
589 {21, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}},
593 BEAST_EXPECT(
std::size(sanity) == result[jss::result][jss::transactions].size());
595 for (
unsigned int index{0}; index <
std::size(sanity); ++index)
609 using namespace test::jtx;
610 using namespace std::chrono_literals;
616 env.
fund(
XRP(10000), alice, becky);
621 BEAST_EXPECT(env.
closed()->exists(beckyAcctKey));
632 auto const beckyPreDelBalance{env.
balance(becky)};
634 auto const acctDelFee{
drops(env.
current()->fees().increment)};
639 BEAST_EXPECT(!env.
closed()->exists(beckyAcctKey));
651 { 0, jss::Payment, {}, {}, {jss::AccountRoot, jss::AccountRoot}},
652 { 1, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}},
653 { 2, jss::AccountDelete, {}, {jss::AccountRoot}, {jss::AccountRoot}},
654 { 3, jss::AccountSet, {}, {}, {jss::AccountRoot}},
655 { 4, jss::AccountSet, {}, {}, {jss::AccountRoot}},
656 { 5, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}}
664 params[jss::account] = becky.human();
665 params[jss::ledger_index_min] = -1;
666 params[jss::ledger_index_max] = -1;
670 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
671 BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
674 constexpr unsigned int beckyDeletedOffset = 2;
675 BEAST_EXPECT(
std::size(sanity) == result[jss::result][jss::transactions].size() + beckyDeletedOffset);
677 Json::Value const& txs{result[jss::result][jss::transactions]};
679 for (
unsigned int index = beckyDeletedOffset; index <
std::size(sanity); ++index)
681 checkSanity(txs[index - beckyDeletedOffset], sanity[index]);
691 env(
pay(alice, becky,
XRP(45)));
695 BEAST_EXPECT(env.
closed()->exists(beckyAcctKey));
699 env(
pay(becky, alice,
XRP(20)));
705 params[jss::account] = becky.human();
706 params[jss::ledger_index_min] = -1;
707 params[jss::ledger_index_max] = -1;
711 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
712 BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
714 BEAST_EXPECT(
std::size(sanity) == result[jss::result][jss::transactions].size());
716 Json::Value const& txs{result[jss::result][jss::transactions]};
718 for (
unsigned int index = 0; index <
std::size(sanity); ++index)
729 using namespace test::jtx;
730 using namespace std::chrono_literals;
733 cfg->FEES.reference_fee = 10;
734 Env env(*
this, std::move(cfg));
740 MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
745 params[jss::account] = alice.human();
746 params[jss::limit] = 100;
747 auto const jv = env.
rpc(
"json",
"account_tx",
to_string(params))[jss::result];
749 BEAST_EXPECT(jv[jss::transactions].size() == size);
750 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
751 BEAST_EXPECT(tx0[jss::TransactionType] == txType);
754 BEAST_EXPECT(tx0[jss::hash] == txHash);
761 checkAliceAcctTx(3, jss::MPTokenIssuanceCreate);
764 mptAlice.authorize({.account = bob});
765 checkAliceAcctTx(4, jss::MPTokenAuthorize);
778 mptAlice.authorize({.account = alice, .holder = bob});
779 checkAliceAcctTx(5, jss::MPTokenAuthorize);
782 mptAlice.authorize({.account = carol});
783 checkAliceAcctTx(6, jss::MPTokenAuthorize);
786 mptAlice.authorize({.account = alice, .holder = carol});
787 checkAliceAcctTx(7, jss::MPTokenAuthorize);
790 mptAlice.pay(alice, bob, 100);
791 checkAliceAcctTx(8, jss::Payment);
794 mptAlice.pay(bob, carol, 10);
795 checkAliceAcctTx(9, jss::Payment);