21 #include <ripple/app/ledger/LedgerMaster.h>
22 #include <ripple/app/reporting/P2pProxy.h>
23 #include <ripple/beast/unit_test.h>
24 #include <ripple/rpc/impl/Tuning.h>
27 #include <test/jtx/Env.h>
28 #include <test/jtx/envconfig.h>
29 #include <test/rpc/GRPCTestClientBase.h>
40 org::xrpl::rpc::v1::GetLedgerRequest
request;
41 org::xrpl::rpc::v1::GetLedgerResponse
reply;
57 testcase(
"GetLedger");
58 using namespace test::jtx;
61 Env env(*
this, std::move(config));
65 auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
67 BEAST_EXPECT(env.current()->info().seq == 4);
69 auto grpcLedger = [&grpcPort](
74 bool get_object_neighbors) {
77 grpcClient.request.mutable_ledger()->set_sequence(sequence);
78 grpcClient.request.set_transactions(transactions);
79 grpcClient.request.set_expand(expand);
80 grpcClient.request.set_get_objects(get_objects);
81 grpcClient.request.set_get_object_neighbors(get_object_neighbors);
83 grpcClient.GetLedger();
88 auto [status, reply] = grpcLedger(3,
false,
false,
false,
false);
90 BEAST_EXPECT(status.ok());
91 BEAST_EXPECT(reply.validated());
92 BEAST_EXPECT(!reply.has_hashes_list());
93 BEAST_EXPECT(!reply.has_transactions_list());
94 BEAST_EXPECT(!reply.skiplist_included());
95 BEAST_EXPECT(reply.ledger_objects().objects_size() == 0);
98 addRaw(ledger->info(), s,
true);
104 env.fund(
XRP(10000), alice);
105 env.fund(
XRP(10000), bob);
108 ledger = env.app().getLedgerMaster().getLedgerBySeq(4);
113 for (
auto& [sttx, meta] : ledger->txs)
115 hashes.
push_back(sttx->getTransactionID());
121 addRaw(ledger->info(), s,
true);
124 auto [status, reply] = grpcLedger(4,
true,
false,
false,
false);
125 BEAST_EXPECT(status.ok());
126 BEAST_EXPECT(reply.validated());
127 BEAST_EXPECT(reply.has_hashes_list());
128 BEAST_EXPECT(reply.hashes_list().hashes_size() == hashes.
size());
142 BEAST_EXPECT(!reply.has_transactions_list());
143 BEAST_EXPECT(!reply.skiplist_included());
144 BEAST_EXPECT(reply.ledger_objects().objects_size() == 0);
150 auto [status, reply] = grpcLedger(4,
true,
true,
false,
false);
152 BEAST_EXPECT(status.ok());
153 BEAST_EXPECT(reply.validated());
154 BEAST_EXPECT(!reply.has_hashes_list());
156 BEAST_EXPECT(reply.has_transactions_list());
157 BEAST_EXPECT(reply.transactions_list().transactions_size() == 4);
162 .transaction_blob()) ==
163 transactions[0]->getSerializer().slice());
169 metas[0]->getSerializer().slice());
174 .transaction_blob()) ==
175 transactions[1]->getSerializer().slice());
181 metas[1]->getSerializer().slice());
186 .transaction_blob()) ==
187 transactions[2]->getSerializer().slice());
193 metas[2]->getSerializer().slice());
198 .transaction_blob()) ==
199 transactions[3]->getSerializer().slice());
205 metas[3]->getSerializer().slice());
207 BEAST_EXPECT(!reply.skiplist_included());
208 BEAST_EXPECT(reply.ledger_objects().objects_size() == 0);
214 auto [status, reply] = grpcLedger(4,
true,
true,
true,
false);
216 BEAST_EXPECT(status.ok());
217 BEAST_EXPECT(reply.validated());
218 BEAST_EXPECT(!reply.has_hashes_list());
220 BEAST_EXPECT(reply.has_transactions_list());
221 BEAST_EXPECT(reply.transactions_list().transactions_size() == 4);
226 .transaction_blob()) ==
227 transactions[0]->getSerializer().slice());
233 metas[0]->getSerializer().slice());
238 .transaction_blob()) ==
239 transactions[1]->getSerializer().slice());
245 metas[1]->getSerializer().slice());
250 .transaction_blob()) ==
251 transactions[2]->getSerializer().slice());
257 metas[2]->getSerializer().slice());
262 .transaction_blob()) ==
263 transactions[3]->getSerializer().slice());
269 metas[3]->getSerializer().slice());
270 BEAST_EXPECT(reply.skiplist_included());
274 auto parent = env.app().getLedgerMaster().getLedgerBySeq(3);
280 bool res = parent->stateMap().compare(
281 ledger->stateMap(), differences, maxDifferences);
285 for (
auto& [k, v] : differences)
290 reply.ledger_objects().objects(idx).key().data()));
295 makeSlice(reply.ledger_objects().objects(idx).data()));
301 auto [status, reply] = grpcLedger(4,
true,
true,
true,
true);
303 BEAST_EXPECT(status.ok());
304 BEAST_EXPECT(reply.validated());
305 BEAST_EXPECT(!reply.has_hashes_list());
306 BEAST_EXPECT(reply.object_neighbors_included());
308 BEAST_EXPECT(reply.has_transactions_list());
309 BEAST_EXPECT(reply.transactions_list().transactions_size() == 4);
314 .transaction_blob()) ==
315 transactions[0]->getSerializer().slice());
321 metas[0]->getSerializer().slice());
326 .transaction_blob()) ==
327 transactions[1]->getSerializer().slice());
333 metas[1]->getSerializer().slice());
338 .transaction_blob()) ==
339 transactions[2]->getSerializer().slice());
345 metas[2]->getSerializer().slice());
350 .transaction_blob()) ==
351 transactions[3]->getSerializer().slice());
357 metas[3]->getSerializer().slice());
358 BEAST_EXPECT(reply.skiplist_included());
362 auto parent = env.app().getLedgerMaster().getLedgerBySeq(3);
368 bool res = parent->stateMap().compare(
369 ledger->stateMap(), differences, maxDifferences);
374 for (
auto& [k, v] : differences)
376 auto obj = reply.ledger_objects().objects(idx);
380 BEAST_EXPECT(v.second->slice() ==
makeSlice(obj.data()));
383 BEAST_EXPECT(obj.data().size() == 0);
385 if (!(v.first && v.second))
387 auto succ = ledger->stateMap().upper_bound(k);
388 auto pred = ledger->stateMap().lower_bound(k);
390 if (succ != ledger->stateMap().end())
395 BEAST_EXPECT(obj.successor().size() == 0);
396 if (pred != ledger->stateMap().end())
401 BEAST_EXPECT(obj.predecessor().size() == 0);
412 env.current()->seq() + 257 - env.seq(alice)};
417 auto const acctDelFee{
drops(env.current()->fees().increment)};
422 auto [status, reply] =
423 grpcLedger(env.closed()->seq(),
true,
true,
true,
true);
425 BEAST_EXPECT(status.ok());
426 BEAST_EXPECT(reply.validated());
428 env.app().getLedgerMaster().getLedgerBySeq(env.closed()->seq());
430 auto parent = env.app().getLedgerMaster().getLedgerBySeq(
431 env.closed()->seq() - 1);
437 bool res = parent->stateMap().compare(
438 base->stateMap(), differences, maxDifferences);
442 for (
auto& [k, v] : differences)
444 auto obj = reply.ledger_objects().objects(idx);
450 makeSlice(reply.ledger_objects().objects(idx).data()));
453 BEAST_EXPECT(obj.data().size() == 0);
454 if (!(v.first && v.second))
456 auto succ = base->stateMap().upper_bound(k);
457 auto pred = base->stateMap().lower_bound(k);
459 if (succ != base->stateMap().end())
464 BEAST_EXPECT(obj.successor().size() == 0);
465 if (pred != base->stateMap().end())
470 BEAST_EXPECT(obj.predecessor().size() == 0);
482 org::xrpl::rpc::v1::GetLedgerDataRequest
request;
483 org::xrpl::rpc::v1::GetLedgerDataResponse
reply;
499 testcase(
"GetLedgerData");
500 using namespace test::jtx;
503 Env env(*
this, std::move(config));
504 auto grpcLedgerData = [&grpcPort](
508 grpcClient.request.mutable_ledger()->set_sequence(sequence);
511 grpcClient.request.set_marker(marker);
514 grpcClient.GetLedgerData();
519 env.fund(
XRP(100000), alice);
521 int num_accounts = 10;
523 for (
auto i = 0; i < num_accounts; i++)
526 env.fund(
XRP(1000), bob);
531 auto [status, reply] = grpcLedgerData(env.closed()->seq());
532 BEAST_EXPECT(status.ok());
535 reply.ledger_objects().objects_size() == num_accounts + 3);
536 BEAST_EXPECT(reply.marker().size() == 0);
537 auto ledger = env.closed();
539 for (
auto& sle : ledger->sles)
542 sle->getSerializer().slice() ==
543 makeSlice(reply.ledger_objects().objects(idx).data()));
549 auto [status, reply] =
550 grpcLedgerData(env.closed()->seq(),
"bad marker");
551 BEAST_EXPECT(!status.ok());
553 status.error_code() == grpc::StatusCode::INVALID_ARGUMENT);
558 for (
auto i = 0; i < num_accounts; i++)
561 env.fund(
XRP(1000), cat);
568 auto [status, reply] = grpcLedgerData(env.closed()->seq());
569 BEAST_EXPECT(status.ok());
572 BEAST_EXPECT(reply.ledger_objects().objects_size() == maxLimit);
573 BEAST_EXPECT(reply.marker().size() != 0);
575 auto [status2, reply2] =
576 grpcLedgerData(env.closed()->seq(), reply.marker());
577 BEAST_EXPECT(status2.ok());
578 BEAST_EXPECT(reply2.marker().size() == 0);
580 auto ledger = env.closed();
582 for (
auto& sle : ledger->sles)
584 auto& obj = idx < maxLimit
585 ? reply.ledger_objects().objects(idx)
586 : reply2.ledger_objects().objects(idx - maxLimit);
589 sle->getSerializer().slice() ==
makeSlice(obj.data()));
594 reply.ledger_objects().objects_size() +
595 reply2.ledger_objects().objects_size());
603 org::xrpl::rpc::v1::GetLedgerDiffRequest
request;
604 org::xrpl::rpc::v1::GetLedgerDiffResponse
reply;
621 testcase(
"GetLedgerDiff");
622 using namespace test::jtx;
625 Env env(*
this, std::move(config));
627 auto grpcLedgerDiff = [&grpcPort](
628 auto baseSequence,
auto desiredSequence) {
631 grpcClient.request.mutable_base_ledger()->set_sequence(
633 grpcClient.request.mutable_desired_ledger()->set_sequence(
635 grpcClient.request.set_include_blobs(
true);
637 grpcClient.GetLedgerDiff();
641 int num_accounts = 20;
642 for (
auto i = 0; i < num_accounts; i++)
645 env.fund(
XRP(1000), cat);
651 auto compareDiffs = [&](
auto baseSequence,
auto desiredSequence) {
652 auto [status, reply] =
653 grpcLedgerDiff(baseSequence, desiredSequence);
655 BEAST_EXPECT(status.ok());
657 env.app().getLedgerMaster().getLedgerBySeq(desiredSequence);
660 env.app().getLedgerMaster().getLedgerBySeq(baseSequence);
666 bool res = base->stateMap().compare(
667 desired->stateMap(), differences, maxDifferences);
668 if (!BEAST_EXPECT(res))
672 for (
auto& [k, v] : differences)
677 reply.ledger_objects().objects(idx).key().data())))
684 reply.ledger_objects().objects(idx).data())))
695 compareDiffs(env.closed()->seq() - 1, env.closed()->seq()));
699 compareDiffs(env.closed()->seq() - 3, env.closed()->seq() - 2));
703 compareDiffs(env.closed()->seq() - 5, env.closed()->seq() - 1));
707 compareDiffs(env.closed()->seq(), env.closed()->seq() - 1));
711 compareDiffs(env.closed()->seq() - 1, env.closed()->seq() - 5));
718 org::xrpl::rpc::v1::GetLedgerEntryRequest
request;
719 org::xrpl::rpc::v1::GetLedgerEntryResponse
reply;
736 testcase(
"GetLedgerDiff");
737 using namespace test::jtx;
740 Env env(*
this, std::move(config));
742 auto grpcLedgerEntry = [&grpcPort](
auto sequence,
auto key) {
745 grpcClient.request.mutable_ledger()->set_sequence(sequence);
746 grpcClient.request.set_key(key.data(), key.size());
748 grpcClient.GetLedgerEntry();
753 env.fund(
XRP(1000), alice);
756 for (
auto& sle : env.closed()->sles)
758 auto [status, reply] =
759 grpcLedgerEntry(env.closed()->seq(), sle->key());
761 BEAST_EXPECT(status.ok());
767 makeSlice(reply.ledger_object().data()) ==
768 sle->getSerializer().slice());
775 testcase(
"NeedCurrentOrClosed");
777 org::xrpl::rpc::v1::GetAccountInfoRequest request;
778 request.mutable_ledger()->set_sequence(1);
780 request.mutable_ledger()->set_hash(
"");
782 request.mutable_ledger()->set_shortcut(
783 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
785 request.mutable_ledger()->set_shortcut(
786 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
788 request.mutable_ledger()->set_shortcut(
789 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
791 request.mutable_ledger()->set_shortcut(
792 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
797 org::xrpl::rpc::v1::GetLedgerRequest request;
798 request.mutable_ledger()->set_sequence(1);
800 request.mutable_ledger()->set_hash(
"");
802 request.mutable_ledger()->set_shortcut(
803 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
805 request.mutable_ledger()->set_shortcut(
806 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
808 request.mutable_ledger()->set_shortcut(
809 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
811 request.mutable_ledger()->set_shortcut(
812 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
817 org::xrpl::rpc::v1::GetLedgerDataRequest request;
818 request.mutable_ledger()->set_sequence(1);
820 request.mutable_ledger()->set_hash(
"");
822 request.mutable_ledger()->set_shortcut(
823 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
825 request.mutable_ledger()->set_shortcut(
826 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
828 request.mutable_ledger()->set_shortcut(
829 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
831 request.mutable_ledger()->set_shortcut(
832 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
837 org::xrpl::rpc::v1::GetLedgerEntryRequest request;
838 request.mutable_ledger()->set_sequence(1);
840 request.mutable_ledger()->set_hash(
"");
842 request.mutable_ledger()->set_shortcut(
843 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
845 request.mutable_ledger()->set_shortcut(
846 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
848 request.mutable_ledger()->set_shortcut(
849 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
851 request.mutable_ledger()->set_shortcut(
852 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
857 org::xrpl::rpc::v1::GetLedgerDiffRequest request;
861 request.mutable_base_ledger()->set_shortcut(
862 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
864 request.mutable_base_ledger()->set_sequence(1);
866 request.mutable_base_ledger()->set_hash(
"");
868 request.mutable_base_ledger()->set_shortcut(
869 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
871 request.mutable_base_ledger()->set_shortcut(
872 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
874 request.mutable_base_ledger()->set_shortcut(
875 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
877 request.mutable_base_ledger()->set_shortcut(
878 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
882 request.mutable_base_ledger()->set_shortcut(
883 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
885 request.mutable_desired_ledger()->set_sequence(1);
887 request.mutable_desired_ledger()->set_hash(
"");
889 request.mutable_desired_ledger()->set_shortcut(
890 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
892 request.mutable_desired_ledger()->set_shortcut(
893 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
895 request.mutable_desired_ledger()->set_shortcut(
896 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
898 request.mutable_desired_ledger()->set_shortcut(
899 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
903 request.mutable_base_ledger()->set_shortcut(
904 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
909 org::xrpl::rpc::v1::GetFeeRequest feeRequest;
912 org::xrpl::rpc::v1::GetAccountTransactionHistoryRequest
916 org::xrpl::rpc::v1::GetTransactionRequest txRequest;
924 testcase(
"SecureGateway");
925 using namespace test::jtx;
931 Env env(*
this, std::move(config));
935 auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
937 BEAST_EXPECT(env.current()->info().seq == 4);
939 auto grpcLedger = [&grpcPort](
945 grpcClient.request.mutable_ledger()->set_sequence(sequence);
946 grpcClient.request.set_client_ip(clientIp);
947 grpcClient.request.set_user(user);
949 grpcClient.GetLedger();
954 auto [status, reply] =
955 grpcLedger(env.current()->info().seq,
"",
"");
956 BEAST_EXPECT(!reply.is_unlimited());
957 BEAST_EXPECT(status.ok());
960 auto [status, reply] =
961 grpcLedger(env.current()->info().seq,
"",
"ETL");
962 BEAST_EXPECT(reply.is_unlimited());
963 BEAST_EXPECT(status.ok());
966 auto [status, reply] =
967 grpcLedger(env.current()->info().seq,
"",
"Reporting");
968 BEAST_EXPECT(reply.is_unlimited());
969 BEAST_EXPECT(status.ok());
972 auto [status, reply] =
973 grpcLedger(env.current()->info().seq,
"127.0.0.1",
"ETL");
974 BEAST_EXPECT(!reply.is_unlimited());
975 BEAST_EXPECT(status.ok());
978 auto [status, reply] =
979 grpcLedger(env.current()->info().seq,
"127.0.0.1",
"");
980 BEAST_EXPECT(!reply.is_unlimited());
981 BEAST_EXPECT(status.ok());
991 Env env(*
this, std::move(config));
995 auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
997 BEAST_EXPECT(env.current()->info().seq == 4);
999 auto grpcLedger = [&grpcPort](
1005 grpcClient.request.mutable_ledger()->set_sequence(sequence);
1006 grpcClient.request.set_client_ip(clientIp);
1007 grpcClient.request.set_user(user);
1009 grpcClient.GetLedger();
1014 auto [status, reply] =
1015 grpcLedger(env.current()->info().seq,
"",
"");
1016 BEAST_EXPECT(!reply.is_unlimited());
1017 BEAST_EXPECT(status.ok());
1020 auto [status, reply] =
1021 grpcLedger(env.current()->info().seq,
"",
"ETL");
1022 BEAST_EXPECT(!reply.is_unlimited());
1023 BEAST_EXPECT(status.ok());
1026 auto [status, reply] = grpcLedger(
1027 env.current()->info().seq, secureGatewayIp,
"ETL");
1028 BEAST_EXPECT(!reply.is_unlimited());
1029 BEAST_EXPECT(status.ok());
1032 auto [status, reply] =
1033 grpcLedger(env.current()->info().seq, secureGatewayIp,
"");
1034 BEAST_EXPECT(!reply.is_unlimited());
1035 BEAST_EXPECT(status.ok());
1044 Env env(*
this, std::move(config));
1048 auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
1050 BEAST_EXPECT(env.current()->info().seq == 4);
1051 auto grpcLedgerData = [&grpcPort](
1057 grpcClient.request.mutable_ledger()->set_sequence(sequence);
1058 grpcClient.request.set_client_ip(clientIp);
1059 grpcClient.request.set_user(user);
1061 grpcClient.GetLedgerData();
1065 auto [status, reply] =
1066 grpcLedgerData(env.current()->info().seq,
"",
"");
1067 BEAST_EXPECT(!reply.is_unlimited());
1068 BEAST_EXPECT(status.ok());
1071 auto [status, reply] =
1072 grpcLedgerData(env.current()->info().seq,
"",
"ETL");
1073 BEAST_EXPECT(reply.is_unlimited());
1074 BEAST_EXPECT(status.ok());
1077 auto [status, reply] =
1078 grpcLedgerData(env.current()->info().seq,
"",
"Reporting");
1079 BEAST_EXPECT(reply.is_unlimited());
1080 BEAST_EXPECT(status.ok());
1083 auto [status, reply] = grpcLedgerData(
1084 env.current()->info().seq,
"127.0.0.1",
"ETL");
1085 BEAST_EXPECT(!reply.is_unlimited());
1086 BEAST_EXPECT(status.ok());
1089 auto [status, reply] =
1090 grpcLedgerData(env.current()->info().seq,
"127.0.0.1",
"");
1091 BEAST_EXPECT(!reply.is_unlimited());
1092 BEAST_EXPECT(status.ok());
1101 Env env(*
this, std::move(config));
1105 auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
1107 BEAST_EXPECT(env.current()->info().seq == 4);
1109 auto grpcLedgerData = [&grpcPort](
1115 grpcClient.request.mutable_ledger()->set_sequence(sequence);
1116 grpcClient.request.set_client_ip(clientIp);
1117 grpcClient.request.set_user(user);
1119 grpcClient.GetLedgerData();
1124 auto [status, reply] =
1125 grpcLedgerData(env.current()->info().seq,
"",
"");
1126 BEAST_EXPECT(!reply.is_unlimited());
1127 BEAST_EXPECT(status.ok());
1130 auto [status, reply] =
1131 grpcLedgerData(env.current()->info().seq,
"",
"ETL");
1132 BEAST_EXPECT(!reply.is_unlimited());
1133 BEAST_EXPECT(status.ok());
1136 auto [status, reply] = grpcLedgerData(
1137 env.current()->info().seq, secureGatewayIp,
"ETL");
1138 BEAST_EXPECT(!reply.is_unlimited());
1139 BEAST_EXPECT(status.ok());
1142 auto [status, reply] = grpcLedgerData(
1143 env.current()->info().seq, secureGatewayIp,
"");
1144 BEAST_EXPECT(!reply.is_unlimited());
1145 BEAST_EXPECT(status.ok());