109 auto const usd = gw[
"USD"];
114 env.
trust(usd(1000), bob);
120 jvParams[jss::ledger_index] =
"potato";
121 auto const jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
123 jrr,
"invalidParams",
"Invalid field 'ledger_index', not string or number.");
129 jvParams[jss::ledger_index] = -1;
130 auto const jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
132 jrr,
"invalidParams",
"Invalid field 'ledger_index', not string or number.");
138 jvParams[jss::ledger_index] = 10u;
139 auto const jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
145 auto const jrr = env.
rpc(
"ledger",
"arbitrary_text")[jss::result];
152 jvParams[jss::ledger_index] =
"validated";
153 jvParams[jss::queue] =
true;
154 auto const jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
160 auto const ret = env.
rpc(
"json",
"ledger",
"{ \"ledger_index\" : 2e15 }");
162 BEAST_EXPECT(ret[jss::error_message] ==
"Invalid parameters.");
167 auto const ret = env.
rpc(
"json",
"ledger",
"{ \"ledger_index\" : 1000000000000000 }");
175 jvParams[field] =
"blah";
176 auto const jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
179 testBooleanField(jss::full);
180 testBooleanField(jss::accounts);
181 testBooleanField(jss::transactions);
182 testBooleanField(jss::expand);
183 testBooleanField(jss::binary);
184 testBooleanField(jss::owner_funds);
185 testBooleanField(jss::queue);
272 cfg->fees.referenceFee = 10;
286 jvParams[jss::ledger] =
"closed";
287 auto 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] =
"validated";
293 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
294 BEAST_EXPECT(jrr.isMember(jss::ledger));
295 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
296 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
298 jvParams[jss::ledger] =
"current";
299 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
300 BEAST_EXPECT(jrr.isMember(jss::ledger));
301 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
304 jvParams[jss::ledger] =
"invalid";
305 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
306 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
308 jrr[jss::error_message] ==
"Invalid field 'ledger', not string or number.");
311 jvParams[jss::ledger] = 4;
312 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
313 BEAST_EXPECT(jrr.isMember(jss::ledger));
314 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
315 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"4");
318 jvParams[jss::ledger] = 20;
319 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
320 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
321 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
326 "0F1A9E0C109ADEF6DA2BDE19217C12BBEC57174CBDBD212B0EBDC1CEDB8531"
330 jvParams[jss::ledger_hash] = hash3;
331 auto jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
332 BEAST_EXPECT(jrr.isMember(jss::ledger));
333 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
334 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"3");
337 jvParams[jss::ledger_hash] =
"DEADBEEF" + hash3;
338 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
339 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
340 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'ledger_hash', not hex string.");
343 jvParams[jss::ledger_hash] = 2;
344 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
345 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
346 BEAST_EXPECT(jrr[jss::error_message] ==
"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");
354 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'ledger_hash', not hex string.");
357 jvParams[jss::ledger_hash] =
358 "8C3EEDB3124D92E49E75D81A8826A2E6"
359 "5A75FD71FC3FD6F36FEB803C5F1D812D";
360 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
361 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
362 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
368 jvParams[jss::ledger_index] =
"closed";
369 auto jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
370 BEAST_EXPECT(jrr.isMember(jss::ledger));
371 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
372 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
373 BEAST_EXPECT(jrr.isMember(jss::ledger_index));
375 jvParams[jss::ledger_index] =
"validated";
376 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
377 BEAST_EXPECT(jrr.isMember(jss::ledger));
378 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
379 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
381 jvParams[jss::ledger_index] =
"current";
382 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
383 BEAST_EXPECT(jrr.isMember(jss::ledger));
384 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
385 BEAST_EXPECT(jrr.isMember(jss::ledger_current_index));
388 jvParams[jss::ledger_index] =
"invalid";
389 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
390 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
392 jrr[jss::error_message] ==
"Invalid field 'ledger_index', not string or number.");
395 for (
auto i : {1, 2, 3, 4, 5, 6})
397 jvParams[jss::ledger_index] = i;
398 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
399 BEAST_EXPECT(jrr.isMember(jss::ledger));
401 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
402 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
std::to_string(i));
406 jvParams[jss::ledger_index] = 7;
407 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
408 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
409 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
432 testcase(
"Ledger with Queued Transactions");
441 cfg->fees.referenceFee = 10;
442 Env env(*
this, std::move(cfg));
445 jv[jss::ledger_index] =
"current";
446 jv[jss::queue] =
true;
447 jv[jss::expand] =
true;
451 Account const charlie{
"charlie"};
460 auto jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
461 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
472 BEAST_EXPECT(env.
current()->header().seq == 5);
475 auto aliceSeq = env.
seq(alice);
481 auto aSeq = env.
seq(a);
483 for (
int i = 0; i < 10; ++i)
494 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
495 BEAST_EXPECT(jrr[jss::queue_data].size() == 33);
501 BEAST_EXPECT(env.
current()->header().seq == 8);
503 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
504 BEAST_EXPECT(jrr[jss::queue_data].size() == 11);
508 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
510 auto const& parentHash = env.
current()->header().parentHash;
511 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
514 auto const& txj = jrr[jss::queue_data][1u];
515 BEAST_EXPECT(txj[jss::account] == alice.
human());
516 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
517 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
518 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
519 BEAST_EXPECT(txj.isMember(jss::tx));
520 auto const& tx = txj[jss::tx];
521 BEAST_EXPECT(tx[jss::Account] == alice.
human());
522 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
523 return tx[jss::hash].asString();
526 auto const& txj = jrr[jss::queue_data][0u];
527 BEAST_EXPECT(txj[jss::account] == alice.
human());
528 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
529 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
530 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
531 BEAST_EXPECT(txj.isMember(jss::tx));
532 auto const& tx = txj[jss::tx];
533 BEAST_EXPECT(tx[jss::Account] == alice.
human());
534 BEAST_EXPECT(tx[jss::TransactionType] == jss::OfferCreate);
535 auto const txid0 = tx[jss::hash].asString();
539 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
547 jv[jss::expand] =
false;
549 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
550 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
552 auto const& parentHash = env.
current()->header().parentHash;
553 auto const txid1 = [&]() {
554 auto const& txj = jrr[jss::queue_data][1u];
555 BEAST_EXPECT(txj[jss::account] == alice.
human());
556 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
557 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
558 BEAST_EXPECT(txj.isMember(jss::tx));
559 return txj[jss::tx].asString();
561 auto const& txj = jrr[jss::queue_data][0u];
562 BEAST_EXPECT(txj[jss::account] == alice.
human());
563 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
564 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
565 BEAST_EXPECT(txj[
"retries_remaining"] == 9);
566 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
567 BEAST_EXPECT(txj.isMember(jss::tx));
568 BEAST_EXPECT(txj[jss::tx] == txid0);
572 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
577 jv[jss::expand] =
true;
578 jv[jss::binary] =
true;
580 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
581 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
583 auto const& txj = jrr[jss::queue_data][1u];
584 BEAST_EXPECT(txj[jss::account] == alice.
human());
585 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
586 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
587 BEAST_EXPECT(txj[
"retries_remaining"] == 8);
588 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
589 BEAST_EXPECT(txj.isMember(jss::tx));
590 BEAST_EXPECT(txj[jss::tx].isMember(jss::tx_blob));
592 auto const& txj2 = jrr[jss::queue_data][0u];
593 BEAST_EXPECT(txj2[jss::account] == alice.
human());
594 BEAST_EXPECT(txj2[jss::fee_level] ==
"256");
595 BEAST_EXPECT(txj2[
"preflight_result"] ==
"tesSUCCESS");
596 BEAST_EXPECT(txj2[
"retries_remaining"] == 10);
597 BEAST_EXPECT(!txj2.isMember(
"last_result"));
598 BEAST_EXPECT(txj2.isMember(jss::tx));
599 BEAST_EXPECT(txj2[jss::tx].isMember(jss::tx_blob));
602 for (
int i = 0; i != 9; ++i)
607 jv[jss::expand] =
false;
608 jv[jss::binary] =
false;
610 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
612 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
614 auto const& txj = jrr[jss::queue_data][0u];
615 BEAST_EXPECT(txj[jss::account] == alice.
human());
616 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
617 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
618 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
619 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
620 BEAST_EXPECT(txj.isMember(jss::tx));
621 BEAST_EXPECT(txj[jss::tx] != txid0);
622 return txj[jss::tx].asString();
627 jv[jss::full] =
true;
629 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
630 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
632 auto const& txj = jrr[jss::queue_data][0u];
633 BEAST_EXPECT(txj[jss::account] == alice.
human());
634 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
635 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
636 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
637 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
638 BEAST_EXPECT(txj.isMember(jss::tx));
639 auto const& tx = txj[jss::tx];
640 BEAST_EXPECT(tx[jss::Account] == alice.
human());
641 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
642 BEAST_EXPECT(tx[jss::hash] == txid2);
649 testcase(
"Ledger Request, Accounts Hashes");
657 int hashesLedgerEntryIndex = -1;
660 jvParams[jss::ledger_index] = 3u;
661 jvParams[jss::accounts] =
true;
662 jvParams[jss::expand] =
true;
663 jvParams[jss::type] =
"hashes";
664 auto const jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
665 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
666 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
668 for (
auto i = 0; i < jrr[jss::ledger][jss::accountState].size(); i++)
670 if (jrr[jss::ledger][jss::accountState][i][
"LedgerEntryType"] == jss::LedgerHashes)
672 index = jrr[jss::ledger][jss::accountState][i][
"index"].asString();
673 hashesLedgerEntryIndex = i;
677 for (
auto const&
object : jrr[jss::ledger][jss::accountState])
679 if (
object[
"LedgerEntryType"] == jss::LedgerHashes)
680 index =
object[
"index"].asString();
685 jrr.isMember(jss::warnings) && jrr[jss::warnings].isArray() &&
686 jrr[jss::warnings].size() == 1 &&
691 jvParams[jss::ledger_index] = 3u;
692 jvParams[jss::accounts] =
true;
693 jvParams[jss::expand] =
false;
694 jvParams[jss::type] =
"hashes";
695 auto const jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
696 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
697 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
699 hashesLedgerEntryIndex > 0 &&
700 jrr[jss::ledger][jss::accountState][hashesLedgerEntryIndex] == index);
704 jrr.isMember(jss::warnings) && jrr[jss::warnings].isArray() &&
705 jrr[jss::warnings].size() == 1 &&