134 cfg->fees.referenceFee = 10;
138 env.fund(
XRP(10000), a1);
148 return j.isMember(jss::result) && (j[jss::result][jss::status] ==
"success") &&
149 (j[jss::result][jss::transactions].size() == 2) &&
150 (j[jss::result][jss::transactions][0u][jss::tx][jss::TransactionType] ==
152 (j[jss::result][jss::transactions][1u][jss::tx][jss::TransactionType] ==
154 (j[jss::result][jss::transactions][1u][jss::tx][jss::DeliverMax] ==
156 (j[jss::result][jss::transactions][1u][jss::tx][jss::Amount] ==
157 j[jss::result][jss::transactions][1u][jss::tx][jss::DeliverMax]);
160 if (j.isMember(jss::result) && (j[jss::result][jss::status] ==
"success") &&
161 (j[jss::result][jss::transactions].size() == 2) &&
162 (j[jss::result][jss::transactions][0u][jss::tx_json]
163 [jss::TransactionType] == jss::AccountSet))
165 auto const& payment = j[jss::result][jss::transactions][1u];
167 return (payment.isMember(jss::tx_json)) &&
168 (payment[jss::tx_json][jss::TransactionType] == jss::Payment) &&
169 (payment[jss::tx_json][jss::DeliverMax] ==
"10000000010") &&
170 (!payment[jss::tx_json].isMember(jss::Amount)) &&
171 (!payment[jss::tx_json].isMember(jss::hash)) &&
172 (payment[jss::hash] ==
173 "9F3085D85F472D1CC29627F260DF68EDE59D42D1D0C33E345"
174 "ECF0D4CE981D0A8") &&
175 (payment[jss::validated] ==
true) &&
176 (payment[jss::ledger_index] == 3) &&
177 (payment[jss::ledger_hash] ==
178 "5476DCD816EA04CBBA57D47BBF1FC58A5217CC93A5ADD79CB"
179 "580A5AFDD727E33") &&
180 (payment[jss::close_time_iso] ==
"2000-01-01T00:00:10Z");
193 return j.isMember(jss::result) && (j[jss::result][jss::status] ==
"success") &&
194 (j[jss::result][jss::transactions].size() == 0);
203 jParams[jss::api_version] = apiVersion;
207 jParams[jss::account] =
"0xDEADBEEF";
211 jParams[jss::account] = a1.human();
212 BEAST_EXPECT(hasTxs(env.rpc(apiVersion,
"json",
"account_tx",
to_string(jParams))));
217 p[jss::ledger_index_min] = -1;
218 p[jss::ledger_index_max] = -1;
219 BEAST_EXPECT(hasTxs(env.rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
221 p[jss::ledger_index_min] = 0;
222 p[jss::ledger_index_max] = 100;
225 BEAST_EXPECT(hasTxs(env.rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
233 p[jss::ledger_index_min] = 1;
234 p[jss::ledger_index_max] = 2;
237 BEAST_EXPECT(noTxs(env.rpc(
"json",
"account_tx",
to_string(p))));
245 p[jss::ledger_index_min] = 2;
246 p[jss::ledger_index_max] = 1;
248 env.rpc(
"json",
"account_tx",
to_string(p)),
254 p[jss::ledger_index_min] = -1;
255 BEAST_EXPECT(hasTxs(env.rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
257 p[jss::ledger_index_min] = 1;
260 BEAST_EXPECT(hasTxs(env.rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
268 p[jss::ledger_index_min] = env.current()->header().seq;
270 env.rpc(
"json",
"account_tx",
to_string(p)),
277 p[jss::ledger_index_max] = -1;
278 BEAST_EXPECT(hasTxs(env.rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
280 p[jss::ledger_index_max] = env.current()->header().seq;
283 BEAST_EXPECT(hasTxs(env.rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
291 p[jss::ledger_index_max] = 3;
292 BEAST_EXPECT(hasTxs(env.rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
294 p[jss::ledger_index_max] = env.closed()->header().seq;
295 BEAST_EXPECT(hasTxs(env.rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
297 p[jss::ledger_index_max] = env.closed()->header().seq - 1;
298 BEAST_EXPECT(noTxs(env.rpc(
"json",
"account_tx",
to_string(p))));
305 p[jss::ledger_index] = env.closed()->header().seq;
306 BEAST_EXPECT(hasTxs(env.rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
308 p[jss::ledger_index] = env.closed()->header().seq - 1;
309 BEAST_EXPECT(noTxs(env.rpc(
"json",
"account_tx",
to_string(p))));
311 p[jss::ledger_index] = env.current()->header().seq;
314 p[jss::ledger_index] = env.current()->header().seq + 1;
322 p[jss::ledger_hash] =
to_string(env.closed()->header().hash);
323 BEAST_EXPECT(hasTxs(env.rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
325 p[jss::ledger_hash] =
to_string(env.closed()->header().parentHash);
326 BEAST_EXPECT(noTxs(env.rpc(
"json",
"account_tx",
to_string(p))));
332 jParams[jss::account] =
"0xDEADBEEF";
333 jParams[jss::account] = a1.human();
336 p[jss::ledger_index_max] = -1;
337 p[jss::ledger_index_min] = -1;
338 p[jss::ledger_index] = -1;
342 BEAST_EXPECT(hasTxs(env.rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
353 p[jss::ledger_index_max] = env.current()->header().seq;
356 BEAST_EXPECT(hasTxs(env.rpc(apiVersion,
"json",
"account_tx",
to_string(p))));
366 auto testInvalidAccountParam = [&](
auto const& param) {
368 params[jss::account] = param;
369 auto jrr = env.rpc(
"json",
"account_tx",
to_string(params))[jss::result];
370 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
371 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'account'.");
374 testInvalidAccountParam(1);
375 testInvalidAccountParam(1.1);
376 testInvalidAccountParam(
true);
384 p[jss::binary] =
"asdf";
388 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
395 p[jss::binary] =
true;
397 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
399 p[jss::forward] =
"true";
402 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
409 p[jss::forward] =
false;
410 result = env.rpc(
"json",
"account_tx",
to_string(p));
411 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
424 env.rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
428 p[jss::limit] =
"10";
430 env.rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
434 p[jss::limit] =
true;
436 env.rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
440 p[jss::limit] =
false;
442 env.rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
448 env.rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
454 env.rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
460 env.rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
464 p[jss::limit] =
"malformed";
466 env.rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
471 p[jss::limit].
append(
"limit");
473 env.rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
479 p[jss::limit][jss::limit] = 10;
481 env.rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::error_message] ==
487 env.rpc(
"json",
"account_tx",
to_string(p))[jss::result][jss::status] ==
"success");
499 using namespace std::chrono_literals;
505 auto const usd{gw[
"USD"]};
507 env.
fund(
XRP(1000000), alice, gw);
514 env(
pay(alice, gw,
XRP(100)));
521 env(
trust(alice, usd(200)),
Sig(alie));
530 env(
signers(alice, 1, {{
"bogie", 1}, {
"demon", 1}}),
Sig(alie));
537 escrow[jss::TransactionType] = jss::EscrowCreate;
538 escrow[jss::Account] = account.human();
539 escrow[jss::Destination] = to.human();
547 escrowWithFinish[sfFinishAfter.jsonName] = nextTime.
time_since_epoch().count();
550 env(escrowWithFinish,
Sig(alie));
553 escrowWithCancel[sfFinishAfter.jsonName] = nextTime.
time_since_epoch().count();
554 escrowWithCancel[sfCancelAfter.jsonName] = nextTime.
time_since_epoch().count() + 1;
557 env(escrowWithCancel,
Sig(alie));
562 escrowFinish[jss::TransactionType] = jss::EscrowFinish;
563 escrowFinish[jss::Account] = alice.
human();
564 escrowFinish[sfOwner.jsonName] = alice.
human();
565 escrowFinish[sfOfferSequence.jsonName] = escrowFinishSeq;
566 env(escrowFinish,
Sig(alie));
570 escrowCancel[jss::TransactionType] = jss::EscrowCancel;
571 escrowCancel[jss::Account] = alice.
human();
572 escrowCancel[sfOwner.jsonName] = alice.
human();
573 escrowCancel[sfOfferSequence.jsonName] = escrowCancelSeq;
574 env(escrowCancel,
Sig(alie));
583 payChanCreate[jss::TransactionType] = jss::PaymentChannelCreate;
584 payChanCreate[jss::Account] = alice.
human();
585 payChanCreate[jss::Destination] = gw.
human();
588 payChanCreate[sfPublicKey.jsonName] =
strHex(alice.
pk().
slice());
589 env(payChanCreate,
Sig(alie));
596 payChanFund[jss::TransactionType] = jss::PaymentChannelFund;
597 payChanFund[jss::Account] = alice.
human();
598 payChanFund[sfChannel.jsonName] = payChanIndex;
600 env(payChanFund,
Sig(alie));
605 payChanClaim[jss::TransactionType] = jss::PaymentChannelClaim;
606 payChanClaim[jss::Flags] = tfClose;
607 payChanClaim[jss::Account] = gw.
human();
608 payChanClaim[sfChannel.jsonName] = payChanIndex;
609 payChanClaim[sfPublicKey.jsonName] =
strHex(alice.
pk().
slice());
640 params[jss::account] = alice.
human();
641 params[jss::ledger_index_min] = -1;
642 params[jss::ledger_index_max] = -1;
646 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
647 BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
649 json::Value const& txs{result[jss::result][jss::transactions]};
656 {0, jss::DepositPreauth, {jss::DepositPreauth}, {jss::Ticket}, {jss::AccountRoot, jss::DirectoryNode}},
657 {1, jss::TicketCreate, {jss::Ticket}, {}, {jss::AccountRoot, jss::DirectoryNode}},
658 {2, jss::CheckCancel, {}, {jss::Check}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
659 {3, jss::CheckCash, {}, {jss::Check}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
660 {4, jss::CheckCreate, {jss::Check}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
661 {5, jss::CheckCreate, {jss::Check}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
662 {6, jss::PaymentChannelClaim, {}, {jss::PayChannel}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
663 {7, jss::PaymentChannelFund, {}, {}, {jss::AccountRoot, jss::PayChannel}},
664 {8, jss::PaymentChannelCreate, {jss::PayChannel}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
665 {9, jss::EscrowCancel, {}, {jss::Escrow}, {jss::AccountRoot, jss::DirectoryNode}},
666 {10, jss::EscrowFinish, {}, {jss::Escrow}, {jss::AccountRoot, jss::DirectoryNode}},
667 {11, jss::EscrowCreate, {jss::Escrow}, {}, {jss::AccountRoot, jss::DirectoryNode}},
668 {12, jss::EscrowCreate, {jss::Escrow}, {}, {jss::AccountRoot, jss::DirectoryNode}},
669 {13, jss::SignerListSet, {jss::SignerList}, {}, {jss::AccountRoot, jss::DirectoryNode}},
670 {14, jss::OfferCancel, {}, {jss::Offer, jss::DirectoryNode}, {jss::AccountRoot, jss::DirectoryNode}},
671 {15, jss::OfferCreate, {jss::Offer, jss::DirectoryNode}, {}, {jss::AccountRoot, jss::DirectoryNode}},
672 {16, jss::TrustSet, {jss::RippleState, jss::DirectoryNode, jss::DirectoryNode}, {}, {jss::AccountRoot, jss::AccountRoot}},
673 {17, jss::SetRegularKey, {}, {}, {jss::AccountRoot}},
674 {18, jss::Payment, {}, {}, {jss::AccountRoot, jss::AccountRoot}},
675 {19, jss::AccountSet, {}, {}, {jss::AccountRoot}},
676 {20, jss::AccountSet, {}, {}, {jss::AccountRoot}},
677 {21, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}},
681 BEAST_EXPECT(
std::size(kSanity) == result[jss::result][jss::transactions].size());
683 for (
unsigned int index{0}; index <
std::size(kSanity); ++index)
698 using namespace std::chrono_literals;
704 env.
fund(
XRP(10000), alice, becky);
709 BEAST_EXPECT(env.
closed()->exists(beckyAcctKey));
720 auto const beckyPreDelBalance{env.
balance(becky)};
722 auto const acctDelFee{
drops(env.
current()->fees().increment)};
727 BEAST_EXPECT(!env.
closed()->exists(beckyAcctKey));
739 { 0, jss::Payment, {}, {}, {jss::AccountRoot, jss::AccountRoot}},
740 { 1, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}},
741 { 2, jss::AccountDelete, {}, {jss::AccountRoot}, {jss::AccountRoot}},
742 { 3, jss::AccountSet, {}, {}, {jss::AccountRoot}},
743 { 4, jss::AccountSet, {}, {}, {jss::AccountRoot}},
744 { 5, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}}
752 params[jss::account] = becky.
human();
753 params[jss::ledger_index_min] = -1;
754 params[jss::ledger_index_max] = -1;
758 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
759 BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
762 static constexpr unsigned int kBeckyDeletedOffset = 2;
765 result[jss::result][jss::transactions].size() + kBeckyDeletedOffset);
767 json::Value const& txs{result[jss::result][jss::transactions]};
769 for (
unsigned int index = kBeckyDeletedOffset; index <
std::size(kSanity); ++index)
771 checkSanity(txs[index - kBeckyDeletedOffset], kSanity[index]);
782 env(
pay(alice, becky,
XRP(45)));
786 BEAST_EXPECT(env.
closed()->exists(beckyAcctKey));
790 env(
pay(becky, alice,
XRP(20)));
796 params[jss::account] = becky.
human();
797 params[jss::ledger_index_min] = -1;
798 params[jss::ledger_index_max] = -1;
802 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
803 BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
805 BEAST_EXPECT(
std::size(kSanity) == result[jss::result][jss::transactions].size());
807 json::Value const& txs{result[jss::result][jss::transactions]};
809 for (
unsigned int index = 0; index <
std::size(kSanity); ++index)
821 using namespace std::chrono_literals;
824 cfg->fees.referenceFee = 10;
825 Env env(*
this, std::move(cfg));
831 MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
836 params[jss::account] = alice.
human();
837 params[jss::limit] = 100;
838 auto const jv = env.
rpc(
"json",
"account_tx",
to_string(params))[jss::result];
840 BEAST_EXPECT(jv[jss::transactions].size() == size);
841 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
842 BEAST_EXPECT(tx0[jss::TransactionType] == txType);
846 BEAST_EXPECT(tx0[jss::hash] == txHash);
853 .flags = tfMPTCanClawback | tfMPTRequireAuth | tfMPTCanTransfer});
855 checkAliceAcctTx(3, jss::MPTokenIssuanceCreate);
858 mptAlice.authorize({.account = bob});
859 checkAliceAcctTx(4, jss::MPTokenAuthorize);
872 mptAlice.authorize({.account = alice, .holder = bob});
873 checkAliceAcctTx(5, jss::MPTokenAuthorize);
876 mptAlice.authorize({.account = carol});
877 checkAliceAcctTx(6, jss::MPTokenAuthorize);
880 mptAlice.authorize({.account = alice, .holder = carol});
881 checkAliceAcctTx(7, jss::MPTokenAuthorize);
884 mptAlice.pay(alice, bob, 100);
885 checkAliceAcctTx(8, jss::Payment);
888 mptAlice.pay(bob, carol, 10);
889 checkAliceAcctTx(9, jss::Payment);