52 using namespace test::jtx;
57 BEAST_EXPECT(env.current()->header().seq == 4);
62 jvParams[jss::ledger_index] = 1;
63 auto const jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
64 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
65 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
70 jvParams[jss::ledger_index] =
"1";
71 auto const jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
72 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
73 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
78 auto const jrr = env.rpc(
"ledger",
"current")[jss::result];
79 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
false);
80 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
std::to_string(env.current()->header().seq));
81 BEAST_EXPECT(jrr[jss::ledger_current_index] == env.current()->header().seq);
233 using namespace test::jtx;
236 cfg->FEES.reference_fee = 10;
239 env.fund(
XRP(10000),
"alice");
241 env.fund(
XRP(10000),
"bob");
243 env.fund(
XRP(10000),
"jim");
245 env.fund(
XRP(10000),
"jill");
250 jvParams[jss::ledger] =
"closed";
251 auto jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
252 BEAST_EXPECT(jrr.isMember(jss::ledger));
253 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
254 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
256 jvParams[jss::ledger] =
"validated";
257 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
258 BEAST_EXPECT(jrr.isMember(jss::ledger));
259 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
260 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
262 jvParams[jss::ledger] =
"current";
263 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
264 BEAST_EXPECT(jrr.isMember(jss::ledger));
265 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
268 jvParams[jss::ledger] =
"invalid";
269 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
270 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
271 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'ledger', not string or number.");
274 jvParams[jss::ledger] = 4;
275 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
276 BEAST_EXPECT(jrr.isMember(jss::ledger));
277 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
278 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"4");
281 jvParams[jss::ledger] = 20;
282 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
283 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
284 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
289 "0F1A9E0C109ADEF6DA2BDE19217C12BBEC57174CBDBD212B0EBDC1CEDB8531"
293 jvParams[jss::ledger_hash] = hash3;
294 auto jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
295 BEAST_EXPECT(jrr.isMember(jss::ledger));
296 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
297 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"3");
300 jvParams[jss::ledger_hash] =
"DEADBEEF" + hash3;
301 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
302 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
303 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'ledger_hash', not hex string.");
306 jvParams[jss::ledger_hash] = 2;
307 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
308 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
309 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'ledger_hash', not hex string.");
312 jvParams[jss::ledger_hash] =
313 "2E81FC6EC0DD943197EGC7E3FBE9AE30"
314 "7F2775F2F7485BB37307984C3C0F2340";
315 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
316 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
317 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'ledger_hash', not hex string.");
320 jvParams[jss::ledger_hash] =
321 "8C3EEDB3124D92E49E75D81A8826A2E6"
322 "5A75FD71FC3FD6F36FEB803C5F1D812D";
323 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
324 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
325 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
331 jvParams[jss::ledger_index] =
"closed";
332 auto jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
333 BEAST_EXPECT(jrr.isMember(jss::ledger));
334 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
335 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
336 BEAST_EXPECT(jrr.isMember(jss::ledger_index));
338 jvParams[jss::ledger_index] =
"validated";
339 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
340 BEAST_EXPECT(jrr.isMember(jss::ledger));
341 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
342 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
344 jvParams[jss::ledger_index] =
"current";
345 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
346 BEAST_EXPECT(jrr.isMember(jss::ledger));
347 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
348 BEAST_EXPECT(jrr.isMember(jss::ledger_current_index));
351 jvParams[jss::ledger_index] =
"invalid";
352 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
353 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
354 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'ledger_index', not string or number.");
357 for (
auto i : {1, 2, 3, 4, 5, 6})
359 jvParams[jss::ledger_index] = i;
360 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
361 BEAST_EXPECT(jrr.isMember(jss::ledger));
363 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
364 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
std::to_string(i));
368 jvParams[jss::ledger_index] = 7;
369 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
370 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
371 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
394 testcase(
"Ledger with Queued Transactions");
395 using namespace test::jtx;
397 auto& section = cfg->section(
"transaction_queue");
398 section.set(
"minimum_txn_in_ledger_standalone",
"3");
399 section.set(
"normal_consensus_increase_percent",
"0");
403 cfg->FEES.reference_fee = 10;
404 Env env(*
this, std::move(cfg));
407 jv[jss::ledger_index] =
"current";
408 jv[jss::queue] =
true;
409 jv[jss::expand] =
true;
413 Account const charlie{
"charlie"};
422 auto jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
423 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
429 if (metrics.openLedgerFeeLevel > metrics.minProcessingFeeLevel)
434 BEAST_EXPECT(env.
current()->header().seq == 5);
437 auto aliceSeq = env.
seq(alice);
443 auto aSeq = env.
seq(a);
445 for (
int i = 0; i < 10; ++i)
456 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
457 BEAST_EXPECT(jrr[jss::queue_data].size() == 33);
463 BEAST_EXPECT(env.
current()->header().seq == 8);
465 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
466 BEAST_EXPECT(jrr[jss::queue_data].size() == 11);
470 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
472 auto const& parentHash = env.
current()->header().parentHash;
473 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
476 auto const& txj = jrr[jss::queue_data][1u];
477 BEAST_EXPECT(txj[jss::account] == alice.human());
478 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
479 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
480 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
481 BEAST_EXPECT(txj.isMember(jss::tx));
482 auto const& tx = txj[jss::tx];
483 BEAST_EXPECT(tx[jss::Account] == alice.human());
484 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
485 return tx[jss::hash].asString();
488 auto const& txj = jrr[jss::queue_data][0u];
489 BEAST_EXPECT(txj[jss::account] == alice.human());
490 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
491 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
492 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
493 BEAST_EXPECT(txj.isMember(jss::tx));
494 auto const& tx = txj[jss::tx];
495 BEAST_EXPECT(tx[jss::Account] == alice.human());
496 BEAST_EXPECT(tx[jss::TransactionType] == jss::OfferCreate);
497 auto const txid0 = tx[jss::hash].asString();
501 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
509 jv[jss::expand] =
false;
511 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
512 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
514 auto const& parentHash = env.
current()->header().parentHash;
515 auto const txid1 = [&]() {
516 auto const& txj = jrr[jss::queue_data][1u];
517 BEAST_EXPECT(txj[jss::account] == alice.human());
518 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
519 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
520 BEAST_EXPECT(txj.isMember(jss::tx));
521 return txj[jss::tx].asString();
523 auto const& txj = jrr[jss::queue_data][0u];
524 BEAST_EXPECT(txj[jss::account] == alice.human());
525 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
526 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
527 BEAST_EXPECT(txj[
"retries_remaining"] == 9);
528 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
529 BEAST_EXPECT(txj.isMember(jss::tx));
530 BEAST_EXPECT(txj[jss::tx] == txid0);
534 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
539 jv[jss::expand] =
true;
540 jv[jss::binary] =
true;
542 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
543 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
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[
"retries_remaining"] == 8);
550 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
551 BEAST_EXPECT(txj.isMember(jss::tx));
552 BEAST_EXPECT(txj[jss::tx].isMember(jss::tx_blob));
554 auto const& txj2 = jrr[jss::queue_data][0u];
555 BEAST_EXPECT(txj2[jss::account] == alice.human());
556 BEAST_EXPECT(txj2[jss::fee_level] ==
"256");
557 BEAST_EXPECT(txj2[
"preflight_result"] ==
"tesSUCCESS");
558 BEAST_EXPECT(txj2[
"retries_remaining"] == 10);
559 BEAST_EXPECT(!txj2.isMember(
"last_result"));
560 BEAST_EXPECT(txj2.isMember(jss::tx));
561 BEAST_EXPECT(txj2[jss::tx].isMember(jss::tx_blob));
564 for (
int i = 0; i != 9; ++i)
569 jv[jss::expand] =
false;
570 jv[jss::binary] =
false;
572 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
574 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
576 auto const& txj = jrr[jss::queue_data][0u];
577 BEAST_EXPECT(txj[jss::account] == alice.human());
578 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
579 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
580 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
581 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
582 BEAST_EXPECT(txj.isMember(jss::tx));
583 BEAST_EXPECT(txj[jss::tx] != txid0);
584 return txj[jss::tx].asString();
589 jv[jss::full] =
true;
591 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
592 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
594 auto const& txj = jrr[jss::queue_data][0u];
595 BEAST_EXPECT(txj[jss::account] == alice.human());
596 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
597 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
598 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
599 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
600 BEAST_EXPECT(txj.isMember(jss::tx));
601 auto const& tx = txj[jss::tx];
602 BEAST_EXPECT(tx[jss::Account] == alice.human());
603 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
604 BEAST_EXPECT(tx[jss::hash] == txid2);
611 testcase(
"Ledger Request, Accounts Hashes");
612 using namespace test::jtx;
619 int hashesLedgerEntryIndex = -1;
622 jvParams[jss::ledger_index] = 3u;
623 jvParams[jss::accounts] =
true;
624 jvParams[jss::expand] =
true;
625 jvParams[jss::type] =
"hashes";
626 auto const jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
627 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
628 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
630 for (
auto i = 0; i < jrr[jss::ledger][jss::accountState].size(); i++)
631 if (jrr[jss::ledger][jss::accountState][i][
"LedgerEntryType"] == jss::LedgerHashes)
633 index = jrr[jss::ledger][jss::accountState][i][
"index"].asString();
634 hashesLedgerEntryIndex = i;
637 for (
auto const&
object : jrr[jss::ledger][jss::accountState])
638 if (
object[
"LedgerEntryType"] == jss::LedgerHashes)
639 index =
object[
"index"].asString();
643 jrr.isMember(jss::warnings) && jrr[jss::warnings].isArray() && jrr[jss::warnings].size() == 1 &&
648 jvParams[jss::ledger_index] = 3u;
649 jvParams[jss::accounts] =
true;
650 jvParams[jss::expand] =
false;
651 jvParams[jss::type] =
"hashes";
652 auto const jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
653 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
654 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
656 hashesLedgerEntryIndex > 0 && jrr[jss::ledger][jss::accountState][hashesLedgerEntryIndex] == index);
660 jrr.isMember(jss::warnings) && jrr[jss::warnings].isArray() && jrr[jss::warnings].size() == 1 &&