55 using namespace test::jtx;
60 BEAST_EXPECT(env.current()->info().seq == 4);
65 jvParams[jss::ledger_index] = 1;
67 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
68 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
69 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
74 jvParams[jss::ledger_index] =
"1";
76 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
77 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
78 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
83 auto const jrr = env.rpc(
"ledger",
"current")[jss::result];
84 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
false);
86 jrr[jss::ledger][jss::ledger_index] ==
89 jrr[jss::ledger_current_index] == env.current()->info().seq);
252 using namespace test::jtx;
255 cfg->FEES.reference_fee = 10;
259 env.fund(
XRP(10000),
"alice");
261 env.fund(
XRP(10000),
"bob");
263 env.fund(
XRP(10000),
"jim");
265 env.fund(
XRP(10000),
"jill");
270 jvParams[jss::ledger] =
"closed";
272 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
273 BEAST_EXPECT(jrr.isMember(jss::ledger));
274 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
275 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
277 jvParams[jss::ledger] =
"validated";
278 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
279 BEAST_EXPECT(jrr.isMember(jss::ledger));
280 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
281 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
283 jvParams[jss::ledger] =
"current";
284 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
285 BEAST_EXPECT(jrr.isMember(jss::ledger));
286 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
289 jvParams[jss::ledger] =
"invalid";
290 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
291 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
292 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerIndexMalformed");
295 jvParams[jss::ledger] = 4;
296 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
297 BEAST_EXPECT(jrr.isMember(jss::ledger));
298 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
299 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"4");
302 jvParams[jss::ledger] = 20;
303 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
304 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
305 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
310 "E86DE7F3D7A4D9CE17EF7C8BA08A8F4D"
311 "8F643B9552F0D895A31CDA78F541DE4E"};
314 jvParams[jss::ledger_hash] = hash3;
316 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
317 BEAST_EXPECT(jrr.isMember(jss::ledger));
318 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
319 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"3");
322 jvParams[jss::ledger_hash] =
"DEADBEEF" + hash3;
323 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
324 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
325 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashMalformed");
328 jvParams[jss::ledger_hash] = 2;
329 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
330 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
331 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashNotString");
334 jvParams[jss::ledger_hash] =
335 "2E81FC6EC0DD943197EGC7E3FBE9AE30"
336 "7F2775F2F7485BB37307984C3C0F2340";
337 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
338 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
339 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashMalformed");
342 jvParams[jss::ledger_hash] =
343 "8C3EEDB3124D92E49E75D81A8826A2E6"
344 "5A75FD71FC3FD6F36FEB803C5F1D812D";
345 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
346 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
347 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
353 jvParams[jss::ledger_index] =
"closed";
355 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
356 BEAST_EXPECT(jrr.isMember(jss::ledger));
357 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
358 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
359 BEAST_EXPECT(jrr.isMember(jss::ledger_index));
361 jvParams[jss::ledger_index] =
"validated";
362 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
363 BEAST_EXPECT(jrr.isMember(jss::ledger));
364 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
365 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
367 jvParams[jss::ledger_index] =
"current";
368 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
369 BEAST_EXPECT(jrr.isMember(jss::ledger));
370 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
371 BEAST_EXPECT(jrr.isMember(jss::ledger_current_index));
374 jvParams[jss::ledger_index] =
"invalid";
375 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
376 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
377 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerIndexMalformed");
380 for (
auto i : {1, 2, 3, 4, 5, 6})
382 jvParams[jss::ledger_index] = i;
384 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
385 BEAST_EXPECT(jrr.isMember(jss::ledger));
387 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
393 jvParams[jss::ledger_index] = 7;
394 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
395 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
396 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
419 testcase(
"Ledger with Queued Transactions");
420 using namespace test::jtx;
422 auto& section = cfg->section(
"transaction_queue");
423 section.set(
"minimum_txn_in_ledger_standalone",
"3");
424 section.set(
"normal_consensus_increase_percent",
"0");
428 cfg->FEES.reference_fee = 10;
429 Env env(*
this, std::move(cfg));
432 jv[jss::ledger_index] =
"current";
433 jv[jss::queue] =
true;
434 jv[jss::expand] =
true;
438 Account const charlie{
"charlie"};
447 auto jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
448 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
454 if (metrics.openLedgerFeeLevel > metrics.minProcessingFeeLevel)
459 BEAST_EXPECT(env.
current()->info().seq == 5);
462 auto aliceSeq = env.
seq(alice);
463 env(
pay(alice,
"george",
XRP(1000)),
466 env(
offer(alice,
XRP(50000), alice[
"USD"](5000)),
472 auto aSeq = env.
seq(a);
474 for (
int i = 0; i < 10; ++i)
485 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
486 BEAST_EXPECT(jrr[jss::queue_data].size() == 33);
492 BEAST_EXPECT(env.
current()->info().seq == 8);
494 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
495 BEAST_EXPECT(jrr[jss::queue_data].size() == 11);
499 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
501 auto const& parentHash = env.
current()->info().parentHash;
502 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
505 auto const& txj = jrr[jss::queue_data][1u];
506 BEAST_EXPECT(txj[jss::account] == alice.human());
507 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
508 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
509 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
510 BEAST_EXPECT(txj.isMember(jss::tx));
511 auto const& tx = txj[jss::tx];
512 BEAST_EXPECT(tx[jss::Account] == alice.human());
513 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
514 return tx[jss::hash].asString();
517 auto const& txj = jrr[jss::queue_data][0u];
518 BEAST_EXPECT(txj[jss::account] == alice.human());
519 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
520 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
521 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
522 BEAST_EXPECT(txj.isMember(jss::tx));
523 auto const& tx = txj[jss::tx];
524 BEAST_EXPECT(tx[jss::Account] == alice.human());
525 BEAST_EXPECT(tx[jss::TransactionType] == jss::OfferCreate);
526 auto const txid0 = tx[jss::hash].asString();
530 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
538 jv[jss::expand] =
false;
540 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
541 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
543 auto const& parentHash = env.
current()->info().parentHash;
544 auto const txid1 = [&]() {
545 auto const& txj = jrr[jss::queue_data][1u];
546 BEAST_EXPECT(txj[jss::account] == alice.human());
547 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
548 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
549 BEAST_EXPECT(txj.isMember(jss::tx));
550 return txj[jss::tx].asString();
552 auto const& txj = jrr[jss::queue_data][0u];
553 BEAST_EXPECT(txj[jss::account] == alice.human());
554 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
555 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
556 BEAST_EXPECT(txj[
"retries_remaining"] == 9);
557 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
558 BEAST_EXPECT(txj.isMember(jss::tx));
559 BEAST_EXPECT(txj[jss::tx] == txid0);
563 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
568 jv[jss::expand] =
true;
569 jv[jss::binary] =
true;
571 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
572 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
574 auto const& txj = jrr[jss::queue_data][1u];
575 BEAST_EXPECT(txj[jss::account] == alice.human());
576 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
577 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
578 BEAST_EXPECT(txj[
"retries_remaining"] == 8);
579 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
580 BEAST_EXPECT(txj.isMember(jss::tx));
581 BEAST_EXPECT(txj[jss::tx].isMember(jss::tx_blob));
583 auto const& txj2 = jrr[jss::queue_data][0u];
584 BEAST_EXPECT(txj2[jss::account] == alice.human());
585 BEAST_EXPECT(txj2[jss::fee_level] ==
"256");
586 BEAST_EXPECT(txj2[
"preflight_result"] ==
"tesSUCCESS");
587 BEAST_EXPECT(txj2[
"retries_remaining"] == 10);
588 BEAST_EXPECT(!txj2.isMember(
"last_result"));
589 BEAST_EXPECT(txj2.isMember(jss::tx));
590 BEAST_EXPECT(txj2[jss::tx].isMember(jss::tx_blob));
593 for (
int i = 0; i != 9; ++i)
598 jv[jss::expand] =
false;
599 jv[jss::binary] =
false;
601 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
603 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
605 auto const& txj = jrr[jss::queue_data][0u];
606 BEAST_EXPECT(txj[jss::account] == alice.human());
607 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
608 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
609 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
610 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
611 BEAST_EXPECT(txj.isMember(jss::tx));
612 BEAST_EXPECT(txj[jss::tx] != txid0);
613 return txj[jss::tx].asString();
618 jv[jss::full] =
true;
620 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
621 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
623 auto const& txj = jrr[jss::queue_data][0u];
624 BEAST_EXPECT(txj[jss::account] == alice.human());
625 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
626 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
627 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
628 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
629 BEAST_EXPECT(txj.isMember(jss::tx));
630 auto const& tx = txj[jss::tx];
631 BEAST_EXPECT(tx[jss::Account] == alice.human());
632 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
633 BEAST_EXPECT(tx[jss::hash] == txid2);
640 testcase(
"Ledger Request, Accounts Hashes");
641 using namespace test::jtx;
648 int hashesLedgerEntryIndex = -1;
651 jvParams[jss::ledger_index] = 3u;
652 jvParams[jss::accounts] =
true;
653 jvParams[jss::expand] =
true;
654 jvParams[jss::type] =
"hashes";
656 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
657 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
658 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
660 for (
auto i = 0; i < jrr[jss::ledger][jss::accountState].size();
662 if (jrr[jss::ledger][jss::accountState][i][
"LedgerEntryType"] ==
665 index = jrr[jss::ledger][jss::accountState][i][
"index"]
667 hashesLedgerEntryIndex = i;
670 for (
auto const&
object : jrr[jss::ledger][jss::accountState])
671 if (
object[
"LedgerEntryType"] == jss::LedgerHashes)
672 index =
object[
"index"].asString();
676 jrr.isMember(jss::warnings) && jrr[jss::warnings].isArray() &&
677 jrr[jss::warnings].size() == 1 &&
678 jrr[jss::warnings][0u][jss::id].asInt() ==
683 jvParams[jss::ledger_index] = 3u;
684 jvParams[jss::accounts] =
true;
685 jvParams[jss::expand] =
false;
686 jvParams[jss::type] =
"hashes";
688 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
689 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
690 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
692 hashesLedgerEntryIndex > 0 &&
693 jrr[jss::ledger][jss::accountState][hashesLedgerEntryIndex] ==
698 jrr.isMember(jss::warnings) && jrr[jss::warnings].isArray() &&
699 jrr[jss::warnings].size() == 1 &&
700 jrr[jss::warnings][0u][jss::id].asInt() ==