58 using namespace test::jtx;
63 BEAST_EXPECT(env.current()->header().seq == 4);
68 jvParams[jss::ledger_index] = 1;
70 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
71 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
72 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
77 jvParams[jss::ledger_index] =
"1";
79 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
80 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
81 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
86 auto const jrr = env.rpc(
"ledger",
"current")[jss::result];
87 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
false);
89 jrr[jss::ledger][jss::ledger_index] ==
92 jrr[jss::ledger_current_index] == env.current()->header().seq);
261 using namespace test::jtx;
264 cfg->FEES.reference_fee = 10;
268 env.fund(
XRP(10000),
"alice");
270 env.fund(
XRP(10000),
"bob");
272 env.fund(
XRP(10000),
"jim");
274 env.fund(
XRP(10000),
"jill");
279 jvParams[jss::ledger] =
"closed";
281 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
282 BEAST_EXPECT(jrr.isMember(jss::ledger));
283 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
284 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
286 jvParams[jss::ledger] =
"validated";
287 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
288 BEAST_EXPECT(jrr.isMember(jss::ledger));
289 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
290 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
292 jvParams[jss::ledger] =
"current";
293 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
294 BEAST_EXPECT(jrr.isMember(jss::ledger));
295 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
298 jvParams[jss::ledger] =
"invalid";
299 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
300 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
302 jrr[jss::error_message] ==
303 "Invalid field 'ledger', not string or number.");
306 jvParams[jss::ledger] = 4;
307 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
308 BEAST_EXPECT(jrr.isMember(jss::ledger));
309 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
310 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"4");
313 jvParams[jss::ledger] = 20;
314 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
315 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
316 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
321 "0F1A9E0C109ADEF6DA2BDE19217C12BBEC57174CBDBD212B0EBDC1CEDB8531"
325 jvParams[jss::ledger_hash] = hash3;
327 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
328 BEAST_EXPECT(jrr.isMember(jss::ledger));
329 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
330 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"3");
333 jvParams[jss::ledger_hash] =
"DEADBEEF" + hash3;
334 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
335 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
337 jrr[jss::error_message] ==
338 "Invalid field 'ledger_hash', not hex string.");
341 jvParams[jss::ledger_hash] = 2;
342 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
343 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
345 jrr[jss::error_message] ==
346 "Invalid field 'ledger_hash', not hex string.");
349 jvParams[jss::ledger_hash] =
350 "2E81FC6EC0DD943197EGC7E3FBE9AE30"
351 "7F2775F2F7485BB37307984C3C0F2340";
352 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
353 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
355 jrr[jss::error_message] ==
356 "Invalid field 'ledger_hash', not hex string.");
359 jvParams[jss::ledger_hash] =
360 "8C3EEDB3124D92E49E75D81A8826A2E6"
361 "5A75FD71FC3FD6F36FEB803C5F1D812D";
362 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
363 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
364 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
370 jvParams[jss::ledger_index] =
"closed";
372 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
373 BEAST_EXPECT(jrr.isMember(jss::ledger));
374 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
375 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
376 BEAST_EXPECT(jrr.isMember(jss::ledger_index));
378 jvParams[jss::ledger_index] =
"validated";
379 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
380 BEAST_EXPECT(jrr.isMember(jss::ledger));
381 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
382 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
384 jvParams[jss::ledger_index] =
"current";
385 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
386 BEAST_EXPECT(jrr.isMember(jss::ledger));
387 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
388 BEAST_EXPECT(jrr.isMember(jss::ledger_current_index));
391 jvParams[jss::ledger_index] =
"invalid";
392 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
393 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
395 jrr[jss::error_message] ==
396 "Invalid field 'ledger_index', not string or number.");
399 for (
auto i : {1, 2, 3, 4, 5, 6})
401 jvParams[jss::ledger_index] = i;
403 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
404 BEAST_EXPECT(jrr.isMember(jss::ledger));
406 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
412 jvParams[jss::ledger_index] = 7;
413 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
414 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
415 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
438 testcase(
"Ledger with Queued Transactions");
439 using namespace test::jtx;
441 auto& section = cfg->section(
"transaction_queue");
442 section.set(
"minimum_txn_in_ledger_standalone",
"3");
443 section.set(
"normal_consensus_increase_percent",
"0");
447 cfg->FEES.reference_fee = 10;
448 Env env(*
this, std::move(cfg));
451 jv[jss::ledger_index] =
"current";
452 jv[jss::queue] =
true;
453 jv[jss::expand] =
true;
457 Account const charlie{
"charlie"};
466 auto jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
467 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
473 if (metrics.openLedgerFeeLevel > metrics.minProcessingFeeLevel)
478 BEAST_EXPECT(env.
current()->header().seq == 5);
481 auto aliceSeq = env.
seq(alice);
482 env(
pay(alice,
"george",
XRP(1000)),
485 env(
offer(alice,
XRP(50000), alice[
"USD"](5000)),
491 auto aSeq = env.
seq(a);
493 for (
int i = 0; i < 10; ++i)
504 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
505 BEAST_EXPECT(jrr[jss::queue_data].size() == 33);
511 BEAST_EXPECT(env.
current()->header().seq == 8);
513 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
514 BEAST_EXPECT(jrr[jss::queue_data].size() == 11);
518 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
520 auto const& parentHash = env.
current()->header().parentHash;
521 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
524 auto const& txj = jrr[jss::queue_data][1u];
525 BEAST_EXPECT(txj[jss::account] == alice.human());
526 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
527 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
528 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
529 BEAST_EXPECT(txj.isMember(jss::tx));
530 auto const& tx = txj[jss::tx];
531 BEAST_EXPECT(tx[jss::Account] == alice.human());
532 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
533 return tx[jss::hash].asString();
536 auto const& txj = jrr[jss::queue_data][0u];
537 BEAST_EXPECT(txj[jss::account] == alice.human());
538 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
539 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
540 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
541 BEAST_EXPECT(txj.isMember(jss::tx));
542 auto const& tx = txj[jss::tx];
543 BEAST_EXPECT(tx[jss::Account] == alice.human());
544 BEAST_EXPECT(tx[jss::TransactionType] == jss::OfferCreate);
545 auto const txid0 = tx[jss::hash].asString();
549 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
557 jv[jss::expand] =
false;
559 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
560 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
562 auto const& parentHash = env.
current()->header().parentHash;
563 auto const txid1 = [&]() {
564 auto const& txj = jrr[jss::queue_data][1u];
565 BEAST_EXPECT(txj[jss::account] == alice.human());
566 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
567 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
568 BEAST_EXPECT(txj.isMember(jss::tx));
569 return txj[jss::tx].asString();
571 auto const& txj = jrr[jss::queue_data][0u];
572 BEAST_EXPECT(txj[jss::account] == alice.human());
573 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
574 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
575 BEAST_EXPECT(txj[
"retries_remaining"] == 9);
576 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
577 BEAST_EXPECT(txj.isMember(jss::tx));
578 BEAST_EXPECT(txj[jss::tx] == txid0);
582 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
587 jv[jss::expand] =
true;
588 jv[jss::binary] =
true;
590 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
591 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
593 auto const& txj = jrr[jss::queue_data][1u];
594 BEAST_EXPECT(txj[jss::account] == alice.human());
595 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
596 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
597 BEAST_EXPECT(txj[
"retries_remaining"] == 8);
598 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
599 BEAST_EXPECT(txj.isMember(jss::tx));
600 BEAST_EXPECT(txj[jss::tx].isMember(jss::tx_blob));
602 auto const& txj2 = jrr[jss::queue_data][0u];
603 BEAST_EXPECT(txj2[jss::account] == alice.human());
604 BEAST_EXPECT(txj2[jss::fee_level] ==
"256");
605 BEAST_EXPECT(txj2[
"preflight_result"] ==
"tesSUCCESS");
606 BEAST_EXPECT(txj2[
"retries_remaining"] == 10);
607 BEAST_EXPECT(!txj2.isMember(
"last_result"));
608 BEAST_EXPECT(txj2.isMember(jss::tx));
609 BEAST_EXPECT(txj2[jss::tx].isMember(jss::tx_blob));
612 for (
int i = 0; i != 9; ++i)
617 jv[jss::expand] =
false;
618 jv[jss::binary] =
false;
620 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
622 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
624 auto const& txj = jrr[jss::queue_data][0u];
625 BEAST_EXPECT(txj[jss::account] == alice.human());
626 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
627 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
628 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
629 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
630 BEAST_EXPECT(txj.isMember(jss::tx));
631 BEAST_EXPECT(txj[jss::tx] != txid0);
632 return txj[jss::tx].asString();
637 jv[jss::full] =
true;
639 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
640 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
642 auto const& txj = jrr[jss::queue_data][0u];
643 BEAST_EXPECT(txj[jss::account] == alice.human());
644 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
645 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
646 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
647 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
648 BEAST_EXPECT(txj.isMember(jss::tx));
649 auto const& tx = txj[jss::tx];
650 BEAST_EXPECT(tx[jss::Account] == alice.human());
651 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
652 BEAST_EXPECT(tx[jss::hash] == txid2);
659 testcase(
"Ledger Request, Accounts Hashes");
660 using namespace test::jtx;
667 int hashesLedgerEntryIndex = -1;
670 jvParams[jss::ledger_index] = 3u;
671 jvParams[jss::accounts] =
true;
672 jvParams[jss::expand] =
true;
673 jvParams[jss::type] =
"hashes";
675 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
676 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
677 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
679 for (
auto i = 0; i < jrr[jss::ledger][jss::accountState].size();
681 if (jrr[jss::ledger][jss::accountState][i][
"LedgerEntryType"] ==
684 index = jrr[jss::ledger][jss::accountState][i][
"index"]
686 hashesLedgerEntryIndex = i;
689 for (
auto const&
object : jrr[jss::ledger][jss::accountState])
690 if (
object[
"LedgerEntryType"] == jss::LedgerHashes)
691 index =
object[
"index"].asString();
695 jrr.isMember(jss::warnings) && jrr[jss::warnings].isArray() &&
696 jrr[jss::warnings].size() == 1 &&
697 jrr[jss::warnings][0u][jss::id].asInt() ==
702 jvParams[jss::ledger_index] = 3u;
703 jvParams[jss::accounts] =
true;
704 jvParams[jss::expand] =
false;
705 jvParams[jss::type] =
"hashes";
707 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
708 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
709 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
711 hashesLedgerEntryIndex > 0 &&
712 jrr[jss::ledger][jss::accountState][hashesLedgerEntryIndex] ==
717 jrr.isMember(jss::warnings) && jrr[jss::warnings].isArray() &&
718 jrr[jss::warnings].size() == 1 &&
719 jrr[jss::warnings][0u][jss::id].asInt() ==