55 using namespace test::jtx;
60 BEAST_EXPECT(env.current()->header().seq == 4);
65 jvParams[jss::ledger_index] = 1;
66 auto const jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
67 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
68 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
73 jvParams[jss::ledger_index] =
"1";
74 auto const jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
75 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
76 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
81 auto const jrr = env.rpc(
"ledger",
"current")[jss::result];
82 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
false);
84 jrr[jss::ledger][jss::ledger_index] ==
std::to_string(env.current()->header().seq));
85 BEAST_EXPECT(jrr[jss::ledger_current_index] == env.current()->header().seq);
239 using namespace test::jtx;
242 cfg->FEES.reference_fee = 10;
245 env.fund(
XRP(10000),
"alice");
247 env.fund(
XRP(10000),
"bob");
249 env.fund(
XRP(10000),
"jim");
251 env.fund(
XRP(10000),
"jill");
256 jvParams[jss::ledger] =
"closed";
257 auto 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] =
"validated";
263 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
264 BEAST_EXPECT(jrr.isMember(jss::ledger));
265 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
266 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
268 jvParams[jss::ledger] =
"current";
269 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
270 BEAST_EXPECT(jrr.isMember(jss::ledger));
271 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
274 jvParams[jss::ledger] =
"invalid";
275 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
276 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
278 jrr[jss::error_message] ==
"Invalid field 'ledger', not string or number.");
281 jvParams[jss::ledger] = 4;
282 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
283 BEAST_EXPECT(jrr.isMember(jss::ledger));
284 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
285 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"4");
288 jvParams[jss::ledger] = 20;
289 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
290 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
291 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
296 "0F1A9E0C109ADEF6DA2BDE19217C12BBEC57174CBDBD212B0EBDC1CEDB8531"
300 jvParams[jss::ledger_hash] = hash3;
301 auto jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
302 BEAST_EXPECT(jrr.isMember(jss::ledger));
303 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
304 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"3");
307 jvParams[jss::ledger_hash] =
"DEADBEEF" + hash3;
308 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
309 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
310 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'ledger_hash', not hex string.");
313 jvParams[jss::ledger_hash] = 2;
314 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
315 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
316 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'ledger_hash', not hex string.");
319 jvParams[jss::ledger_hash] =
320 "2E81FC6EC0DD943197EGC7E3FBE9AE30"
321 "7F2775F2F7485BB37307984C3C0F2340";
322 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
323 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
324 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'ledger_hash', not hex string.");
327 jvParams[jss::ledger_hash] =
328 "8C3EEDB3124D92E49E75D81A8826A2E6"
329 "5A75FD71FC3FD6F36FEB803C5F1D812D";
330 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
331 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
332 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
338 jvParams[jss::ledger_index] =
"closed";
339 auto 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");
343 BEAST_EXPECT(jrr.isMember(jss::ledger_index));
345 jvParams[jss::ledger_index] =
"validated";
346 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
347 BEAST_EXPECT(jrr.isMember(jss::ledger));
348 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
349 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
351 jvParams[jss::ledger_index] =
"current";
352 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
353 BEAST_EXPECT(jrr.isMember(jss::ledger));
354 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
355 BEAST_EXPECT(jrr.isMember(jss::ledger_current_index));
358 jvParams[jss::ledger_index] =
"invalid";
359 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
360 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
362 jrr[jss::error_message] ==
"Invalid field 'ledger_index', not string or number.");
365 for (
auto i : {1, 2, 3, 4, 5, 6})
367 jvParams[jss::ledger_index] = i;
368 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
369 BEAST_EXPECT(jrr.isMember(jss::ledger));
371 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
372 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
std::to_string(i));
376 jvParams[jss::ledger_index] = 7;
377 jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
378 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
379 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
402 testcase(
"Ledger with Queued Transactions");
403 using namespace test::jtx;
405 auto& section = cfg->section(
"transaction_queue");
406 section.set(
"minimum_txn_in_ledger_standalone",
"3");
407 section.set(
"normal_consensus_increase_percent",
"0");
411 cfg->FEES.reference_fee = 10;
412 Env env(*
this, std::move(cfg));
415 jv[jss::ledger_index] =
"current";
416 jv[jss::queue] =
true;
417 jv[jss::expand] =
true;
421 Account const charlie{
"charlie"};
430 auto jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
431 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
437 if (metrics.openLedgerFeeLevel > metrics.minProcessingFeeLevel)
442 BEAST_EXPECT(env.
current()->header().seq == 5);
445 auto aliceSeq = env.
seq(alice);
451 auto aSeq = env.
seq(a);
453 for (
int i = 0; i < 10; ++i)
464 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
465 BEAST_EXPECT(jrr[jss::queue_data].size() == 33);
471 BEAST_EXPECT(env.
current()->header().seq == 8);
473 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
474 BEAST_EXPECT(jrr[jss::queue_data].size() == 11);
478 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
480 auto const& parentHash = env.
current()->header().parentHash;
481 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
484 auto const& txj = jrr[jss::queue_data][1u];
485 BEAST_EXPECT(txj[jss::account] == alice.human());
486 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
487 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
488 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
489 BEAST_EXPECT(txj.isMember(jss::tx));
490 auto const& tx = txj[jss::tx];
491 BEAST_EXPECT(tx[jss::Account] == alice.human());
492 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
493 return tx[jss::hash].asString();
496 auto const& txj = jrr[jss::queue_data][0u];
497 BEAST_EXPECT(txj[jss::account] == alice.human());
498 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
499 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
500 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
501 BEAST_EXPECT(txj.isMember(jss::tx));
502 auto const& tx = txj[jss::tx];
503 BEAST_EXPECT(tx[jss::Account] == alice.human());
504 BEAST_EXPECT(tx[jss::TransactionType] == jss::OfferCreate);
505 auto const txid0 = tx[jss::hash].asString();
509 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
517 jv[jss::expand] =
false;
519 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
520 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
522 auto const& parentHash = env.
current()->header().parentHash;
523 auto const txid1 = [&]() {
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.isMember(jss::tx));
529 return txj[jss::tx].asString();
531 auto const& txj = jrr[jss::queue_data][0u];
532 BEAST_EXPECT(txj[jss::account] == alice.human());
533 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
534 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
535 BEAST_EXPECT(txj[
"retries_remaining"] == 9);
536 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
537 BEAST_EXPECT(txj.isMember(jss::tx));
538 BEAST_EXPECT(txj[jss::tx] == txid0);
542 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
547 jv[jss::expand] =
true;
548 jv[jss::binary] =
true;
550 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
551 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
553 auto const& txj = jrr[jss::queue_data][1u];
554 BEAST_EXPECT(txj[jss::account] == alice.human());
555 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
556 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
557 BEAST_EXPECT(txj[
"retries_remaining"] == 8);
558 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
559 BEAST_EXPECT(txj.isMember(jss::tx));
560 BEAST_EXPECT(txj[jss::tx].isMember(jss::tx_blob));
562 auto const& txj2 = jrr[jss::queue_data][0u];
563 BEAST_EXPECT(txj2[jss::account] == alice.human());
564 BEAST_EXPECT(txj2[jss::fee_level] ==
"256");
565 BEAST_EXPECT(txj2[
"preflight_result"] ==
"tesSUCCESS");
566 BEAST_EXPECT(txj2[
"retries_remaining"] == 10);
567 BEAST_EXPECT(!txj2.isMember(
"last_result"));
568 BEAST_EXPECT(txj2.isMember(jss::tx));
569 BEAST_EXPECT(txj2[jss::tx].isMember(jss::tx_blob));
572 for (
int i = 0; i != 9; ++i)
577 jv[jss::expand] =
false;
578 jv[jss::binary] =
false;
580 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
582 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
584 auto const& txj = jrr[jss::queue_data][0u];
585 BEAST_EXPECT(txj[jss::account] == alice.human());
586 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
587 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
588 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
589 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
590 BEAST_EXPECT(txj.isMember(jss::tx));
591 BEAST_EXPECT(txj[jss::tx] != txid0);
592 return txj[jss::tx].asString();
597 jv[jss::full] =
true;
599 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
600 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
602 auto const& txj = jrr[jss::queue_data][0u];
603 BEAST_EXPECT(txj[jss::account] == alice.human());
604 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
605 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
606 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
607 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
608 BEAST_EXPECT(txj.isMember(jss::tx));
609 auto const& tx = txj[jss::tx];
610 BEAST_EXPECT(tx[jss::Account] == alice.human());
611 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
612 BEAST_EXPECT(tx[jss::hash] == txid2);
619 testcase(
"Ledger Request, Accounts Hashes");
620 using namespace test::jtx;
627 int hashesLedgerEntryIndex = -1;
630 jvParams[jss::ledger_index] = 3u;
631 jvParams[jss::accounts] =
true;
632 jvParams[jss::expand] =
true;
633 jvParams[jss::type] =
"hashes";
634 auto const jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
635 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
636 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
638 for (
auto i = 0; i < jrr[jss::ledger][jss::accountState].size(); i++)
640 if (jrr[jss::ledger][jss::accountState][i][
"LedgerEntryType"] == jss::LedgerHashes)
642 index = jrr[jss::ledger][jss::accountState][i][
"index"].asString();
643 hashesLedgerEntryIndex = i;
647 for (
auto const&
object : jrr[jss::ledger][jss::accountState])
649 if (
object[
"LedgerEntryType"] == jss::LedgerHashes)
650 index =
object[
"index"].asString();
655 jrr.isMember(jss::warnings) && jrr[jss::warnings].isArray() &&
656 jrr[jss::warnings].size() == 1 &&
661 jvParams[jss::ledger_index] = 3u;
662 jvParams[jss::accounts] =
true;
663 jvParams[jss::expand] =
false;
664 jvParams[jss::type] =
"hashes";
665 auto const jrr = env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
666 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
667 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
669 hashesLedgerEntryIndex > 0 &&
670 jrr[jss::ledger][jss::accountState][hashesLedgerEntryIndex] == index);
674 jrr.isMember(jss::warnings) && jrr[jss::warnings].isArray() &&
675 jrr[jss::warnings].size() == 1 &&