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);
274 cfg->fees.referenceFee = 10;
288 jvParams[jss::ledger] =
"closed";
289 auto jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
290 BEAST_EXPECT(jrr.isMember(jss::ledger));
291 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
292 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
294 jvParams[jss::ledger] =
"validated";
295 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
296 BEAST_EXPECT(jrr.isMember(jss::ledger));
297 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
298 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
300 jvParams[jss::ledger] =
"current";
301 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
302 BEAST_EXPECT(jrr.isMember(jss::ledger));
303 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
306 jvParams[jss::ledger] =
"invalid";
307 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
308 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
310 jrr[jss::error_message] ==
"Invalid field 'ledger', not string or number.");
313 jvParams[jss::ledger] = 4;
314 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
315 BEAST_EXPECT(jrr.isMember(jss::ledger));
316 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
317 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"4");
320 jvParams[jss::ledger] = 20;
321 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
322 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
323 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
328 "0F1A9E0C109ADEF6DA2BDE19217C12BBEC57174CBDBD212B0EBDC1CEDB8531"
332 jvParams[jss::ledger_hash] = hash3;
333 auto jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
334 BEAST_EXPECT(jrr.isMember(jss::ledger));
335 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
336 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"3");
339 jvParams[jss::ledger_hash] =
"DEADBEEF" + hash3;
340 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
341 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
342 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'ledger_hash', not hex string.");
345 jvParams[jss::ledger_hash] = 2;
346 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
347 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
348 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid field 'ledger_hash', not hex string.");
351 jvParams[jss::ledger_hash] =
352 "2E81FC6EC0DD943197EGC7E3FBE9AE30"
353 "7F2775F2F7485BB37307984C3C0F2340";
354 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
355 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
356 BEAST_EXPECT(jrr[jss::error_message] ==
"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";
371 auto jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
372 BEAST_EXPECT(jrr.isMember(jss::ledger));
373 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
374 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
375 BEAST_EXPECT(jrr.isMember(jss::ledger_index));
377 jvParams[jss::ledger_index] =
"validated";
378 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
379 BEAST_EXPECT(jrr.isMember(jss::ledger));
380 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
381 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
383 jvParams[jss::ledger_index] =
"current";
384 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
385 BEAST_EXPECT(jrr.isMember(jss::ledger));
386 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
387 BEAST_EXPECT(jrr.isMember(jss::ledger_current_index));
390 jvParams[jss::ledger_index] =
"invalid";
391 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
392 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
394 jrr[jss::error_message] ==
"Invalid field 'ledger_index', not string or number.");
397 for (
auto i : {1, 2, 3, 4, 5, 6})
399 jvParams[jss::ledger_index] = i;
400 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
401 BEAST_EXPECT(jrr.isMember(jss::ledger));
403 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
404 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
std::to_string(i));
408 jvParams[jss::ledger_index] = 7;
409 jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
410 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
411 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
434 testcase(
"Ledger with Queued Transactions");
443 cfg->fees.referenceFee = 10;
444 Env env(*
this, std::move(cfg));
447 jv[jss::ledger_index] =
"current";
448 jv[jss::queue] =
true;
449 jv[jss::expand] =
true;
453 Account const charlie{
"charlie"};
462 auto jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
463 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
474 BEAST_EXPECT(env.
current()->header().seq == 5);
477 auto aliceSeq = env.
seq(alice);
483 auto aSeq = env.
seq(a);
485 for (
int i = 0; i < 10; ++i)
496 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
497 BEAST_EXPECT(jrr[jss::queue_data].size() == 33);
503 BEAST_EXPECT(env.
current()->header().seq == 8);
505 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
506 BEAST_EXPECT(jrr[jss::queue_data].size() == 11);
510 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
512 auto const& parentHash = env.
current()->header().parentHash;
513 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
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[
"retries_remaining"] == 10);
521 BEAST_EXPECT(txj.isMember(jss::tx));
522 auto const& tx = txj[jss::tx];
523 BEAST_EXPECT(tx[jss::Account] == alice.
human());
524 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
525 return tx[jss::hash].asString();
528 auto const& txj = jrr[jss::queue_data][0u];
529 BEAST_EXPECT(txj[jss::account] == alice.
human());
530 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
531 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
532 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
533 BEAST_EXPECT(txj.isMember(jss::tx));
534 auto const& tx = txj[jss::tx];
535 BEAST_EXPECT(tx[jss::Account] == alice.
human());
536 BEAST_EXPECT(tx[jss::TransactionType] == jss::OfferCreate);
537 auto const txid0 = tx[jss::hash].asString();
541 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
549 jv[jss::expand] =
false;
551 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
552 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
554 auto const& parentHash = env.
current()->header().parentHash;
555 auto const txid1 = [&]() {
556 auto const& txj = jrr[jss::queue_data][1u];
557 BEAST_EXPECT(txj[jss::account] == alice.
human());
558 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
559 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
560 BEAST_EXPECT(txj.isMember(jss::tx));
561 return txj[jss::tx].asString();
563 auto const& txj = jrr[jss::queue_data][0u];
564 BEAST_EXPECT(txj[jss::account] == alice.
human());
565 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
566 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
567 BEAST_EXPECT(txj[
"retries_remaining"] == 9);
568 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
569 BEAST_EXPECT(txj.isMember(jss::tx));
570 BEAST_EXPECT(txj[jss::tx] == txid0);
574 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
579 jv[jss::expand] =
true;
580 jv[jss::binary] =
true;
582 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
583 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
585 auto const& txj = jrr[jss::queue_data][1u];
586 BEAST_EXPECT(txj[jss::account] == alice.
human());
587 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
588 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
589 BEAST_EXPECT(txj[
"retries_remaining"] == 8);
590 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
591 BEAST_EXPECT(txj.isMember(jss::tx));
592 BEAST_EXPECT(txj[jss::tx].isMember(jss::tx_blob));
594 auto const& txj2 = jrr[jss::queue_data][0u];
595 BEAST_EXPECT(txj2[jss::account] == alice.
human());
596 BEAST_EXPECT(txj2[jss::fee_level] ==
"256");
597 BEAST_EXPECT(txj2[
"preflight_result"] ==
"tesSUCCESS");
598 BEAST_EXPECT(txj2[
"retries_remaining"] == 10);
599 BEAST_EXPECT(!txj2.isMember(
"last_result"));
600 BEAST_EXPECT(txj2.isMember(jss::tx));
601 BEAST_EXPECT(txj2[jss::tx].isMember(jss::tx_blob));
604 for (
int i = 0; i != 9; ++i)
609 jv[jss::expand] =
false;
610 jv[jss::binary] =
false;
612 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
614 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
616 auto const& txj = jrr[jss::queue_data][0u];
617 BEAST_EXPECT(txj[jss::account] == alice.
human());
618 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
619 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
620 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
621 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
622 BEAST_EXPECT(txj.isMember(jss::tx));
623 BEAST_EXPECT(txj[jss::tx] != txid0);
624 return txj[jss::tx].asString();
629 jv[jss::full] =
true;
631 jrr = env.
rpc(
"json",
"ledger",
to_string(jv))[jss::result];
632 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
634 auto const& txj = jrr[jss::queue_data][0u];
635 BEAST_EXPECT(txj[jss::account] == alice.
human());
636 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
637 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
638 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
639 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
640 BEAST_EXPECT(txj.isMember(jss::tx));
641 auto const& tx = txj[jss::tx];
642 BEAST_EXPECT(tx[jss::Account] == alice.
human());
643 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
644 BEAST_EXPECT(tx[jss::hash] == txid2);
651 testcase(
"Ledger Request, Accounts Hashes");
659 int hashesLedgerEntryIndex = -1;
662 jvParams[jss::ledger_index] = 3u;
663 jvParams[jss::accounts] =
true;
664 jvParams[jss::expand] =
true;
665 jvParams[jss::type] =
"hashes";
666 auto const jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
667 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
668 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
670 for (
auto i = 0; i < jrr[jss::ledger][jss::accountState].size(); i++)
672 if (jrr[jss::ledger][jss::accountState][i][
"LedgerEntryType"] == jss::LedgerHashes)
674 index = jrr[jss::ledger][jss::accountState][i][
"index"].asString();
675 hashesLedgerEntryIndex = i;
679 for (
auto const&
object : jrr[jss::ledger][jss::accountState])
681 if (
object[
"LedgerEntryType"] == jss::LedgerHashes)
682 index =
object[
"index"].asString();
687 jrr.isMember(jss::warnings) && jrr[jss::warnings].isArray() &&
688 jrr[jss::warnings].size() == 1 &&
693 jvParams[jss::ledger_index] = 3u;
694 jvParams[jss::accounts] =
true;
695 jvParams[jss::expand] =
false;
696 jvParams[jss::type] =
"hashes";
697 auto const jrr = env.
rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
698 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
699 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
701 hashesLedgerEntryIndex > 0 &&
702 jrr[jss::ledger][jss::accountState][hashesLedgerEntryIndex] == index);
706 jrr.isMember(jss::warnings) && jrr[jss::warnings].isArray() &&
707 jrr[jss::warnings].size() == 1 &&