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 + 4);
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");
778 org::xrpl::rpc::v1::GetLedgerRequest request;
779 request.mutable_ledger()->set_sequence(1);
781 request.mutable_ledger()->set_hash(
"");
783 request.mutable_ledger()->set_shortcut(
784 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
786 request.mutable_ledger()->set_shortcut(
787 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
789 request.mutable_ledger()->set_shortcut(
790 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
792 request.mutable_ledger()->set_shortcut(
793 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
798 org::xrpl::rpc::v1::GetLedgerDataRequest request;
799 request.mutable_ledger()->set_sequence(1);
801 request.mutable_ledger()->set_hash(
"");
803 request.mutable_ledger()->set_shortcut(
804 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
806 request.mutable_ledger()->set_shortcut(
807 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
809 request.mutable_ledger()->set_shortcut(
810 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
812 request.mutable_ledger()->set_shortcut(
813 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
818 org::xrpl::rpc::v1::GetLedgerEntryRequest request;
819 request.mutable_ledger()->set_sequence(1);
821 request.mutable_ledger()->set_hash(
"");
823 request.mutable_ledger()->set_shortcut(
824 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
826 request.mutable_ledger()->set_shortcut(
827 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
829 request.mutable_ledger()->set_shortcut(
830 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
832 request.mutable_ledger()->set_shortcut(
833 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
838 org::xrpl::rpc::v1::GetLedgerDiffRequest request;
842 request.mutable_base_ledger()->set_shortcut(
843 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
845 request.mutable_base_ledger()->set_sequence(1);
847 request.mutable_base_ledger()->set_hash(
"");
849 request.mutable_base_ledger()->set_shortcut(
850 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
852 request.mutable_base_ledger()->set_shortcut(
853 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
855 request.mutable_base_ledger()->set_shortcut(
856 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
858 request.mutable_base_ledger()->set_shortcut(
859 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
863 request.mutable_base_ledger()->set_shortcut(
864 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
866 request.mutable_desired_ledger()->set_sequence(1);
868 request.mutable_desired_ledger()->set_hash(
"");
870 request.mutable_desired_ledger()->set_shortcut(
871 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
873 request.mutable_desired_ledger()->set_shortcut(
874 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
876 request.mutable_desired_ledger()->set_shortcut(
877 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
879 request.mutable_desired_ledger()->set_shortcut(
880 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
884 request.mutable_base_ledger()->set_shortcut(
885 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
893 testcase(
"SecureGateway");
894 using namespace test::jtx;
900 Env env(*
this, std::move(config));
904 auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
906 BEAST_EXPECT(env.current()->info().seq == 4);
908 auto grpcLedger = [&grpcPort](
914 grpcClient.request.mutable_ledger()->set_sequence(sequence);
915 grpcClient.request.set_client_ip(clientIp);
916 grpcClient.request.set_user(user);
918 grpcClient.GetLedger();
923 auto [status, reply] =
924 grpcLedger(env.current()->info().seq,
"",
"");
925 BEAST_EXPECT(!reply.is_unlimited());
926 BEAST_EXPECT(status.ok());
929 auto [status, reply] =
930 grpcLedger(env.current()->info().seq,
"",
"ETL");
931 BEAST_EXPECT(reply.is_unlimited());
932 BEAST_EXPECT(status.ok());
935 auto [status, reply] =
936 grpcLedger(env.current()->info().seq,
"",
"Reporting");
937 BEAST_EXPECT(reply.is_unlimited());
938 BEAST_EXPECT(status.ok());
941 auto [status, reply] =
942 grpcLedger(env.current()->info().seq,
"127.0.0.1",
"ETL");
943 BEAST_EXPECT(!reply.is_unlimited());
944 BEAST_EXPECT(status.ok());
947 auto [status, reply] =
948 grpcLedger(env.current()->info().seq,
"127.0.0.1",
"");
949 BEAST_EXPECT(!reply.is_unlimited());
950 BEAST_EXPECT(status.ok());
960 Env env(*
this, std::move(config));
964 auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
966 BEAST_EXPECT(env.current()->info().seq == 4);
968 auto grpcLedger = [&grpcPort](
974 grpcClient.request.mutable_ledger()->set_sequence(sequence);
975 grpcClient.request.set_client_ip(clientIp);
976 grpcClient.request.set_user(user);
978 grpcClient.GetLedger();
983 auto [status, reply] =
984 grpcLedger(env.current()->info().seq,
"",
"");
985 BEAST_EXPECT(!reply.is_unlimited());
986 BEAST_EXPECT(status.ok());
989 auto [status, reply] =
990 grpcLedger(env.current()->info().seq,
"",
"ETL");
991 BEAST_EXPECT(!reply.is_unlimited());
992 BEAST_EXPECT(status.ok());
995 auto [status, reply] = grpcLedger(
996 env.current()->info().seq, secureGatewayIp,
"ETL");
997 BEAST_EXPECT(!reply.is_unlimited());
998 BEAST_EXPECT(status.ok());
1001 auto [status, reply] =
1002 grpcLedger(env.current()->info().seq, secureGatewayIp,
"");
1003 BEAST_EXPECT(!reply.is_unlimited());
1004 BEAST_EXPECT(status.ok());
1013 Env env(*
this, std::move(config));
1017 auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
1019 BEAST_EXPECT(env.current()->info().seq == 4);
1020 auto grpcLedgerData = [&grpcPort](
1026 grpcClient.request.mutable_ledger()->set_sequence(sequence);
1027 grpcClient.request.set_client_ip(clientIp);
1028 grpcClient.request.set_user(user);
1030 grpcClient.GetLedgerData();
1034 auto [status, reply] =
1035 grpcLedgerData(env.current()->info().seq,
"",
"");
1036 BEAST_EXPECT(!reply.is_unlimited());
1037 BEAST_EXPECT(status.ok());
1040 auto [status, reply] =
1041 grpcLedgerData(env.current()->info().seq,
"",
"ETL");
1042 BEAST_EXPECT(reply.is_unlimited());
1043 BEAST_EXPECT(status.ok());
1046 auto [status, reply] =
1047 grpcLedgerData(env.current()->info().seq,
"",
"Reporting");
1048 BEAST_EXPECT(reply.is_unlimited());
1049 BEAST_EXPECT(status.ok());
1052 auto [status, reply] = grpcLedgerData(
1053 env.current()->info().seq,
"127.0.0.1",
"ETL");
1054 BEAST_EXPECT(!reply.is_unlimited());
1055 BEAST_EXPECT(status.ok());
1058 auto [status, reply] =
1059 grpcLedgerData(env.current()->info().seq,
"127.0.0.1",
"");
1060 BEAST_EXPECT(!reply.is_unlimited());
1061 BEAST_EXPECT(status.ok());
1070 Env env(*
this, std::move(config));
1074 auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
1076 BEAST_EXPECT(env.current()->info().seq == 4);
1078 auto grpcLedgerData = [&grpcPort](
1084 grpcClient.request.mutable_ledger()->set_sequence(sequence);
1085 grpcClient.request.set_client_ip(clientIp);
1086 grpcClient.request.set_user(user);
1088 grpcClient.GetLedgerData();
1093 auto [status, reply] =
1094 grpcLedgerData(env.current()->info().seq,
"",
"");
1095 BEAST_EXPECT(!reply.is_unlimited());
1096 BEAST_EXPECT(status.ok());
1099 auto [status, reply] =
1100 grpcLedgerData(env.current()->info().seq,
"",
"ETL");
1101 BEAST_EXPECT(!reply.is_unlimited());
1102 BEAST_EXPECT(status.ok());
1105 auto [status, reply] = grpcLedgerData(
1106 env.current()->info().seq, secureGatewayIp,
"ETL");
1107 BEAST_EXPECT(!reply.is_unlimited());
1108 BEAST_EXPECT(status.ok());
1111 auto [status, reply] = grpcLedgerData(
1112 env.current()->info().seq, secureGatewayIp,
"");
1113 BEAST_EXPECT(!reply.is_unlimited());
1114 BEAST_EXPECT(status.ok());