21 #include <ripple/app/reporting/P2pProxy.h>
22 #include <ripple/beast/unit_test.h>
23 #include <ripple/rpc/impl/Tuning.h>
26 #include <test/jtx/Env.h>
27 #include <test/jtx/envconfig.h>
28 #include <test/rpc/GRPCTestClientBase.h>
39 org::xrpl::rpc::v1::GetLedgerRequest
request;
40 org::xrpl::rpc::v1::GetLedgerResponse
reply;
56 testcase(
"GetLedger");
57 using namespace test::jtx;
60 Env env(*
this, std::move(config));
64 auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
66 BEAST_EXPECT(env.current()->info().seq == 4);
68 auto grpcLedger = [&grpcPort](
73 bool get_object_neighbors) {
76 grpcClient.request.mutable_ledger()->set_sequence(sequence);
77 grpcClient.request.set_transactions(transactions);
78 grpcClient.request.set_expand(expand);
79 grpcClient.request.set_get_objects(get_objects);
80 grpcClient.request.set_get_object_neighbors(get_object_neighbors);
82 grpcClient.GetLedger();
87 auto [status, reply] = grpcLedger(3,
false,
false,
false,
false);
89 BEAST_EXPECT(status.ok());
90 BEAST_EXPECT(reply.validated());
91 BEAST_EXPECT(!reply.has_hashes_list());
92 BEAST_EXPECT(!reply.has_transactions_list());
93 BEAST_EXPECT(!reply.skiplist_included());
94 BEAST_EXPECT(reply.ledger_objects().objects_size() == 0);
97 addRaw(ledger->info(), s,
true);
103 env.fund(
XRP(10000), alice);
104 env.fund(
XRP(10000), bob);
107 ledger = env.app().getLedgerMaster().getLedgerBySeq(4);
112 for (
auto& [sttx, meta] : ledger->txs)
114 hashes.
push_back(sttx->getTransactionID());
120 addRaw(ledger->info(), s,
true);
123 auto [status, reply] = grpcLedger(4,
true,
false,
false,
false);
124 BEAST_EXPECT(status.ok());
125 BEAST_EXPECT(reply.validated());
126 BEAST_EXPECT(reply.has_hashes_list());
127 BEAST_EXPECT(reply.hashes_list().hashes_size() == hashes.
size());
141 BEAST_EXPECT(!reply.has_transactions_list());
142 BEAST_EXPECT(!reply.skiplist_included());
143 BEAST_EXPECT(reply.ledger_objects().objects_size() == 0);
149 auto [status, reply] = grpcLedger(4,
true,
true,
false,
false);
151 BEAST_EXPECT(status.ok());
152 BEAST_EXPECT(reply.validated());
153 BEAST_EXPECT(!reply.has_hashes_list());
155 BEAST_EXPECT(reply.has_transactions_list());
156 BEAST_EXPECT(reply.transactions_list().transactions_size() == 4);
161 .transaction_blob()) ==
162 transactions[0]->getSerializer().slice());
168 metas[0]->getSerializer().slice());
173 .transaction_blob()) ==
174 transactions[1]->getSerializer().slice());
180 metas[1]->getSerializer().slice());
185 .transaction_blob()) ==
186 transactions[2]->getSerializer().slice());
192 metas[2]->getSerializer().slice());
197 .transaction_blob()) ==
198 transactions[3]->getSerializer().slice());
204 metas[3]->getSerializer().slice());
206 BEAST_EXPECT(!reply.skiplist_included());
207 BEAST_EXPECT(reply.ledger_objects().objects_size() == 0);
213 auto [status, reply] = grpcLedger(4,
true,
true,
true,
false);
215 BEAST_EXPECT(status.ok());
216 BEAST_EXPECT(reply.validated());
217 BEAST_EXPECT(!reply.has_hashes_list());
219 BEAST_EXPECT(reply.has_transactions_list());
220 BEAST_EXPECT(reply.transactions_list().transactions_size() == 4);
225 .transaction_blob()) ==
226 transactions[0]->getSerializer().slice());
232 metas[0]->getSerializer().slice());
237 .transaction_blob()) ==
238 transactions[1]->getSerializer().slice());
244 metas[1]->getSerializer().slice());
249 .transaction_blob()) ==
250 transactions[2]->getSerializer().slice());
256 metas[2]->getSerializer().slice());
261 .transaction_blob()) ==
262 transactions[3]->getSerializer().slice());
268 metas[3]->getSerializer().slice());
269 BEAST_EXPECT(reply.skiplist_included());
273 auto parent = env.app().getLedgerMaster().getLedgerBySeq(3);
279 bool res = parent->stateMap().compare(
280 ledger->stateMap(), differences, maxDifferences);
284 for (
auto& [k, v] : differences)
289 reply.ledger_objects().objects(idx).key().data()));
294 makeSlice(reply.ledger_objects().objects(idx).data()));
300 auto [status, reply] = grpcLedger(4,
true,
true,
true,
true);
302 BEAST_EXPECT(status.ok());
303 BEAST_EXPECT(reply.validated());
304 BEAST_EXPECT(!reply.has_hashes_list());
305 BEAST_EXPECT(reply.object_neighbors_included());
307 BEAST_EXPECT(reply.has_transactions_list());
308 BEAST_EXPECT(reply.transactions_list().transactions_size() == 4);
313 .transaction_blob()) ==
314 transactions[0]->getSerializer().slice());
320 metas[0]->getSerializer().slice());
325 .transaction_blob()) ==
326 transactions[1]->getSerializer().slice());
332 metas[1]->getSerializer().slice());
337 .transaction_blob()) ==
338 transactions[2]->getSerializer().slice());
344 metas[2]->getSerializer().slice());
349 .transaction_blob()) ==
350 transactions[3]->getSerializer().slice());
356 metas[3]->getSerializer().slice());
357 BEAST_EXPECT(reply.skiplist_included());
361 auto parent = env.app().getLedgerMaster().getLedgerBySeq(3);
367 bool res = parent->stateMap().compare(
368 ledger->stateMap(), differences, maxDifferences);
373 for (
auto& [k, v] : differences)
375 auto obj = reply.ledger_objects().objects(idx);
379 BEAST_EXPECT(v.second->slice() ==
makeSlice(obj.data()));
382 BEAST_EXPECT(obj.data().size() == 0);
384 if (!(v.first && v.second))
386 auto succ = ledger->stateMap().upper_bound(k);
387 auto pred = ledger->stateMap().lower_bound(k);
389 if (succ != ledger->stateMap().end())
394 BEAST_EXPECT(obj.successor().size() == 0);
395 if (pred != ledger->stateMap().end())
400 BEAST_EXPECT(obj.predecessor().size() == 0);
411 env.current()->seq() + 257 - env.seq(alice)};
416 auto const acctDelFee{
drops(env.current()->fees().increment)};
421 auto [status, reply] =
422 grpcLedger(env.closed()->seq(),
true,
true,
true,
true);
424 BEAST_EXPECT(status.ok());
425 BEAST_EXPECT(reply.validated());
427 env.app().getLedgerMaster().getLedgerBySeq(env.closed()->seq());
429 auto parent = env.app().getLedgerMaster().getLedgerBySeq(
430 env.closed()->seq() - 1);
436 bool res = parent->stateMap().compare(
437 base->stateMap(), differences, maxDifferences);
441 for (
auto& [k, v] : differences)
443 auto obj = reply.ledger_objects().objects(idx);
449 makeSlice(reply.ledger_objects().objects(idx).data()));
452 BEAST_EXPECT(obj.data().size() == 0);
453 if (!(v.first && v.second))
455 auto succ = base->stateMap().upper_bound(k);
456 auto pred = base->stateMap().lower_bound(k);
458 if (succ != base->stateMap().end())
463 BEAST_EXPECT(obj.successor().size() == 0);
464 if (pred != base->stateMap().end())
469 BEAST_EXPECT(obj.predecessor().size() == 0);
481 org::xrpl::rpc::v1::GetLedgerDataRequest
request;
482 org::xrpl::rpc::v1::GetLedgerDataResponse
reply;
498 testcase(
"GetLedgerData");
499 using namespace test::jtx;
502 Env env(*
this, std::move(config));
503 auto grpcLedgerData = [&grpcPort](
507 grpcClient.request.mutable_ledger()->set_sequence(sequence);
510 grpcClient.request.set_marker(marker);
513 grpcClient.GetLedgerData();
518 env.fund(
XRP(100000), alice);
520 int num_accounts = 10;
522 for (
auto i = 0; i < num_accounts; i++)
525 env.fund(
XRP(1000), bob);
530 auto [status, reply] = grpcLedgerData(env.closed()->seq());
531 BEAST_EXPECT(status.ok());
534 reply.ledger_objects().objects_size() == num_accounts + 4);
535 BEAST_EXPECT(reply.marker().size() == 0);
536 auto ledger = env.closed();
538 for (
auto& sle : ledger->sles)
541 sle->getSerializer().slice() ==
542 makeSlice(reply.ledger_objects().objects(idx).data()));
548 auto [status, reply] =
549 grpcLedgerData(env.closed()->seq(),
"bad marker");
550 BEAST_EXPECT(!status.ok());
552 status.error_code() == grpc::StatusCode::INVALID_ARGUMENT);
557 for (
auto i = 0; i < num_accounts; i++)
560 env.fund(
XRP(1000), cat);
567 auto [status, reply] = grpcLedgerData(env.closed()->seq());
568 BEAST_EXPECT(status.ok());
571 BEAST_EXPECT(reply.ledger_objects().objects_size() == maxLimit);
572 BEAST_EXPECT(reply.marker().size() != 0);
574 auto [status2, reply2] =
575 grpcLedgerData(env.closed()->seq(), reply.marker());
576 BEAST_EXPECT(status2.ok());
577 BEAST_EXPECT(reply2.marker().size() == 0);
579 auto ledger = env.closed();
581 for (
auto& sle : ledger->sles)
583 auto& obj = idx < maxLimit
584 ? reply.ledger_objects().objects(idx)
585 : reply2.ledger_objects().objects(idx - maxLimit);
588 sle->getSerializer().slice() ==
makeSlice(obj.data()));
593 reply.ledger_objects().objects_size() +
594 reply2.ledger_objects().objects_size());
602 org::xrpl::rpc::v1::GetLedgerDiffRequest
request;
603 org::xrpl::rpc::v1::GetLedgerDiffResponse
reply;
620 testcase(
"GetLedgerDiff");
621 using namespace test::jtx;
624 Env env(*
this, std::move(config));
626 auto grpcLedgerDiff = [&grpcPort](
627 auto baseSequence,
auto desiredSequence) {
630 grpcClient.request.mutable_base_ledger()->set_sequence(
632 grpcClient.request.mutable_desired_ledger()->set_sequence(
634 grpcClient.request.set_include_blobs(
true);
636 grpcClient.GetLedgerDiff();
640 int num_accounts = 20;
641 for (
auto i = 0; i < num_accounts; i++)
644 env.fund(
XRP(1000), cat);
650 auto compareDiffs = [&](
auto baseSequence,
auto desiredSequence) {
651 auto [status, reply] =
652 grpcLedgerDiff(baseSequence, desiredSequence);
654 BEAST_EXPECT(status.ok());
656 env.app().getLedgerMaster().getLedgerBySeq(desiredSequence);
659 env.app().getLedgerMaster().getLedgerBySeq(baseSequence);
665 bool res = base->stateMap().compare(
666 desired->stateMap(), differences, maxDifferences);
667 if (!BEAST_EXPECT(res))
671 for (
auto& [k, v] : differences)
676 reply.ledger_objects().objects(idx).key().data())))
683 reply.ledger_objects().objects(idx).data())))
694 compareDiffs(env.closed()->seq() - 1, env.closed()->seq()));
698 compareDiffs(env.closed()->seq() - 3, env.closed()->seq() - 2));
702 compareDiffs(env.closed()->seq() - 5, env.closed()->seq() - 1));
706 compareDiffs(env.closed()->seq(), env.closed()->seq() - 1));
710 compareDiffs(env.closed()->seq() - 1, env.closed()->seq() - 5));
717 org::xrpl::rpc::v1::GetLedgerEntryRequest
request;
718 org::xrpl::rpc::v1::GetLedgerEntryResponse
reply;
735 testcase(
"GetLedgerDiff");
736 using namespace test::jtx;
739 Env env(*
this, std::move(config));
741 auto grpcLedgerEntry = [&grpcPort](
auto sequence,
auto key) {
744 grpcClient.request.mutable_ledger()->set_sequence(sequence);
745 grpcClient.request.set_key(key.data(), key.size());
747 grpcClient.GetLedgerEntry();
752 env.fund(
XRP(1000), alice);
755 for (
auto& sle : env.closed()->sles)
757 auto [status, reply] =
758 grpcLedgerEntry(env.closed()->seq(), sle->key());
760 BEAST_EXPECT(status.ok());
766 makeSlice(reply.ledger_object().data()) ==
767 sle->getSerializer().slice());
774 testcase(
"NeedCurrentOrClosed");
777 org::xrpl::rpc::v1::GetLedgerRequest 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::GetLedgerDataRequest 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::GetLedgerEntryRequest 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::GetLedgerDiffRequest request;
841 request.mutable_base_ledger()->set_shortcut(
842 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
844 request.mutable_base_ledger()->set_sequence(1);
846 request.mutable_base_ledger()->set_hash(
"");
848 request.mutable_base_ledger()->set_shortcut(
849 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
851 request.mutable_base_ledger()->set_shortcut(
852 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
854 request.mutable_base_ledger()->set_shortcut(
855 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
857 request.mutable_base_ledger()->set_shortcut(
858 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
862 request.mutable_base_ledger()->set_shortcut(
863 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
865 request.mutable_desired_ledger()->set_sequence(1);
867 request.mutable_desired_ledger()->set_hash(
"");
869 request.mutable_desired_ledger()->set_shortcut(
870 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
872 request.mutable_desired_ledger()->set_shortcut(
873 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
875 request.mutable_desired_ledger()->set_shortcut(
876 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
878 request.mutable_desired_ledger()->set_shortcut(
879 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
883 request.mutable_base_ledger()->set_shortcut(
884 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
892 testcase(
"SecureGateway");
893 using namespace test::jtx;
899 Env env(*
this, std::move(config));
903 auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
905 BEAST_EXPECT(env.current()->info().seq == 4);
907 auto grpcLedger = [&grpcPort](
913 grpcClient.request.mutable_ledger()->set_sequence(sequence);
914 grpcClient.request.set_client_ip(clientIp);
915 grpcClient.request.set_user(user);
917 grpcClient.GetLedger();
922 auto [status, reply] =
923 grpcLedger(env.current()->info().seq,
"",
"");
924 BEAST_EXPECT(!reply.is_unlimited());
925 BEAST_EXPECT(status.ok());
928 auto [status, reply] =
929 grpcLedger(env.current()->info().seq,
"",
"ETL");
930 BEAST_EXPECT(reply.is_unlimited());
931 BEAST_EXPECT(status.ok());
934 auto [status, reply] =
935 grpcLedger(env.current()->info().seq,
"",
"Reporting");
936 BEAST_EXPECT(reply.is_unlimited());
937 BEAST_EXPECT(status.ok());
940 auto [status, reply] =
941 grpcLedger(env.current()->info().seq,
"127.0.0.1",
"ETL");
942 BEAST_EXPECT(!reply.is_unlimited());
943 BEAST_EXPECT(status.ok());
946 auto [status, reply] =
947 grpcLedger(env.current()->info().seq,
"127.0.0.1",
"");
948 BEAST_EXPECT(!reply.is_unlimited());
949 BEAST_EXPECT(status.ok());
959 Env env(*
this, std::move(config));
963 auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
965 BEAST_EXPECT(env.current()->info().seq == 4);
967 auto grpcLedger = [&grpcPort](
973 grpcClient.request.mutable_ledger()->set_sequence(sequence);
974 grpcClient.request.set_client_ip(clientIp);
975 grpcClient.request.set_user(user);
977 grpcClient.GetLedger();
982 auto [status, reply] =
983 grpcLedger(env.current()->info().seq,
"",
"");
984 BEAST_EXPECT(!reply.is_unlimited());
985 BEAST_EXPECT(status.ok());
988 auto [status, reply] =
989 grpcLedger(env.current()->info().seq,
"",
"ETL");
990 BEAST_EXPECT(!reply.is_unlimited());
991 BEAST_EXPECT(status.ok());
994 auto [status, reply] = grpcLedger(
995 env.current()->info().seq, secureGatewayIp,
"ETL");
996 BEAST_EXPECT(!reply.is_unlimited());
997 BEAST_EXPECT(status.ok());
1000 auto [status, reply] =
1001 grpcLedger(env.current()->info().seq, secureGatewayIp,
"");
1002 BEAST_EXPECT(!reply.is_unlimited());
1003 BEAST_EXPECT(status.ok());
1012 Env env(*
this, std::move(config));
1016 auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
1018 BEAST_EXPECT(env.current()->info().seq == 4);
1019 auto grpcLedgerData = [&grpcPort](
1025 grpcClient.request.mutable_ledger()->set_sequence(sequence);
1026 grpcClient.request.set_client_ip(clientIp);
1027 grpcClient.request.set_user(user);
1029 grpcClient.GetLedgerData();
1033 auto [status, reply] =
1034 grpcLedgerData(env.current()->info().seq,
"",
"");
1035 BEAST_EXPECT(!reply.is_unlimited());
1036 BEAST_EXPECT(status.ok());
1039 auto [status, reply] =
1040 grpcLedgerData(env.current()->info().seq,
"",
"ETL");
1041 BEAST_EXPECT(reply.is_unlimited());
1042 BEAST_EXPECT(status.ok());
1045 auto [status, reply] =
1046 grpcLedgerData(env.current()->info().seq,
"",
"Reporting");
1047 BEAST_EXPECT(reply.is_unlimited());
1048 BEAST_EXPECT(status.ok());
1051 auto [status, reply] = grpcLedgerData(
1052 env.current()->info().seq,
"127.0.0.1",
"ETL");
1053 BEAST_EXPECT(!reply.is_unlimited());
1054 BEAST_EXPECT(status.ok());
1057 auto [status, reply] =
1058 grpcLedgerData(env.current()->info().seq,
"127.0.0.1",
"");
1059 BEAST_EXPECT(!reply.is_unlimited());
1060 BEAST_EXPECT(status.ok());
1069 Env env(*
this, std::move(config));
1073 auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
1075 BEAST_EXPECT(env.current()->info().seq == 4);
1077 auto grpcLedgerData = [&grpcPort](
1083 grpcClient.request.mutable_ledger()->set_sequence(sequence);
1084 grpcClient.request.set_client_ip(clientIp);
1085 grpcClient.request.set_user(user);
1087 grpcClient.GetLedgerData();
1092 auto [status, reply] =
1093 grpcLedgerData(env.current()->info().seq,
"",
"");
1094 BEAST_EXPECT(!reply.is_unlimited());
1095 BEAST_EXPECT(status.ok());
1098 auto [status, reply] =
1099 grpcLedgerData(env.current()->info().seq,
"",
"ETL");
1100 BEAST_EXPECT(!reply.is_unlimited());
1101 BEAST_EXPECT(status.ok());
1104 auto [status, reply] = grpcLedgerData(
1105 env.current()->info().seq, secureGatewayIp,
"ETL");
1106 BEAST_EXPECT(!reply.is_unlimited());
1107 BEAST_EXPECT(status.ok());
1110 auto [status, reply] = grpcLedgerData(
1111 env.current()->info().seq, secureGatewayIp,
"");
1112 BEAST_EXPECT(!reply.is_unlimited());
1113 BEAST_EXPECT(status.ok());