rippled
ReportingETL_test.cpp
1 
2 //------------------------------------------------------------------------------
3 /*
4  This file is part of rippled: https://github.com/ripple/rippled
5  Copyright (c) 2020 Ripple Labs Inc.
6 
7  Permission to use, copy, modify, and/or distribute this software for any
8  purpose with or without fee is hereby granted, provided that the above
9  copyright notice and this permission notice appear in all copies.
10 
11  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19 //==============================================================================
20 
21 #include <ripple/app/reporting/P2pProxy.h>
22 #include <ripple/beast/unit_test.h>
23 #include <ripple/rpc/impl/Tuning.h>
24 
25 #include <test/jtx.h>
26 #include <test/jtx/Env.h>
27 #include <test/jtx/envconfig.h>
28 #include <test/rpc/GRPCTestClientBase.h>
29 
30 namespace ripple {
31 namespace test {
32 
33 class ReportingETL_test : public beast::unit_test::suite
34 {
35  // gRPC stuff
37  {
38  public:
39  org::xrpl::rpc::v1::GetLedgerRequest request;
40  org::xrpl::rpc::v1::GetLedgerResponse reply;
41 
42  explicit GrpcLedgerClient(std::string const& port)
43  : GRPCTestClientBase(port)
44  {
45  }
46 
47  void
49  {
50  status = stub_->GetLedger(&context, request, &reply);
51  }
52  };
53  void
55  {
56  testcase("GetLedger");
57  using namespace test::jtx;
59  std::string grpcPort = *(*config)["port_grpc"].get<std::string>("port");
60  Env env(*this, std::move(config));
61 
62  env.close();
63 
64  auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
65 
66  BEAST_EXPECT(env.current()->info().seq == 4);
67 
68  auto grpcLedger = [&grpcPort](
69  auto sequence,
70  bool transactions,
71  bool expand,
72  bool get_objects,
73  bool get_object_neighbors) {
74  GrpcLedgerClient grpcClient{grpcPort};
75 
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);
81 
82  grpcClient.GetLedger();
83  return std::make_pair(grpcClient.status, grpcClient.reply);
84  };
85 
86  {
87  auto [status, reply] = grpcLedger(3, false, false, false, false);
88 
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);
95 
96  Serializer s;
97  addRaw(ledger->info(), s, true);
98  BEAST_EXPECT(s.slice() == makeSlice(reply.ledger_header()));
99  }
100 
101  Account const alice{"alice"};
102  Account const bob{"bob"};
103  env.fund(XRP(10000), alice);
104  env.fund(XRP(10000), bob);
105  env.close();
106 
107  ledger = env.app().getLedgerMaster().getLedgerBySeq(4);
108 
109  std::vector<uint256> hashes;
112  for (auto& [sttx, meta] : ledger->txs)
113  {
114  hashes.push_back(sttx->getTransactionID());
115  transactions.push_back(sttx);
116  metas.push_back(meta);
117  }
118 
119  Serializer s;
120  addRaw(ledger->info(), s, true);
121 
122  {
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());
128  BEAST_EXPECT(
129  uint256::fromVoid(reply.hashes_list().hashes(0).data()) ==
130  hashes[0]);
131  BEAST_EXPECT(
132  uint256::fromVoid(reply.hashes_list().hashes(1).data()) ==
133  hashes[1]);
134  BEAST_EXPECT(
135  uint256::fromVoid(reply.hashes_list().hashes(2).data()) ==
136  hashes[2]);
137  BEAST_EXPECT(
138  uint256::fromVoid(reply.hashes_list().hashes(3).data()) ==
139  hashes[3]);
140 
141  BEAST_EXPECT(!reply.has_transactions_list());
142  BEAST_EXPECT(!reply.skiplist_included());
143  BEAST_EXPECT(reply.ledger_objects().objects_size() == 0);
144 
145  BEAST_EXPECT(s.slice() == makeSlice(reply.ledger_header()));
146  }
147 
148  {
149  auto [status, reply] = grpcLedger(4, true, true, false, false);
150 
151  BEAST_EXPECT(status.ok());
152  BEAST_EXPECT(reply.validated());
153  BEAST_EXPECT(!reply.has_hashes_list());
154 
155  BEAST_EXPECT(reply.has_transactions_list());
156  BEAST_EXPECT(reply.transactions_list().transactions_size() == 4);
157 
158  BEAST_EXPECT(
159  makeSlice(reply.transactions_list()
160  .transactions(0)
161  .transaction_blob()) ==
162  transactions[0]->getSerializer().slice());
163 
164  BEAST_EXPECT(
165  makeSlice(reply.transactions_list()
166  .transactions(0)
167  .metadata_blob()) ==
168  metas[0]->getSerializer().slice());
169 
170  BEAST_EXPECT(
171  makeSlice(reply.transactions_list()
172  .transactions(1)
173  .transaction_blob()) ==
174  transactions[1]->getSerializer().slice());
175 
176  BEAST_EXPECT(
177  makeSlice(reply.transactions_list()
178  .transactions(1)
179  .metadata_blob()) ==
180  metas[1]->getSerializer().slice());
181 
182  BEAST_EXPECT(
183  makeSlice(reply.transactions_list()
184  .transactions(2)
185  .transaction_blob()) ==
186  transactions[2]->getSerializer().slice());
187 
188  BEAST_EXPECT(
189  makeSlice(reply.transactions_list()
190  .transactions(2)
191  .metadata_blob()) ==
192  metas[2]->getSerializer().slice());
193 
194  BEAST_EXPECT(
195  makeSlice(reply.transactions_list()
196  .transactions(3)
197  .transaction_blob()) ==
198  transactions[3]->getSerializer().slice());
199 
200  BEAST_EXPECT(
201  makeSlice(reply.transactions_list()
202  .transactions(3)
203  .metadata_blob()) ==
204  metas[3]->getSerializer().slice());
205 
206  BEAST_EXPECT(!reply.skiplist_included());
207  BEAST_EXPECT(reply.ledger_objects().objects_size() == 0);
208 
209  BEAST_EXPECT(s.slice() == makeSlice(reply.ledger_header()));
210  }
211 
212  {
213  auto [status, reply] = grpcLedger(4, true, true, true, false);
214 
215  BEAST_EXPECT(status.ok());
216  BEAST_EXPECT(reply.validated());
217  BEAST_EXPECT(!reply.has_hashes_list());
218 
219  BEAST_EXPECT(reply.has_transactions_list());
220  BEAST_EXPECT(reply.transactions_list().transactions_size() == 4);
221 
222  BEAST_EXPECT(
223  makeSlice(reply.transactions_list()
224  .transactions(0)
225  .transaction_blob()) ==
226  transactions[0]->getSerializer().slice());
227 
228  BEAST_EXPECT(
229  makeSlice(reply.transactions_list()
230  .transactions(0)
231  .metadata_blob()) ==
232  metas[0]->getSerializer().slice());
233 
234  BEAST_EXPECT(
235  makeSlice(reply.transactions_list()
236  .transactions(1)
237  .transaction_blob()) ==
238  transactions[1]->getSerializer().slice());
239 
240  BEAST_EXPECT(
241  makeSlice(reply.transactions_list()
242  .transactions(1)
243  .metadata_blob()) ==
244  metas[1]->getSerializer().slice());
245 
246  BEAST_EXPECT(
247  makeSlice(reply.transactions_list()
248  .transactions(2)
249  .transaction_blob()) ==
250  transactions[2]->getSerializer().slice());
251 
252  BEAST_EXPECT(
253  makeSlice(reply.transactions_list()
254  .transactions(2)
255  .metadata_blob()) ==
256  metas[2]->getSerializer().slice());
257 
258  BEAST_EXPECT(
259  makeSlice(reply.transactions_list()
260  .transactions(3)
261  .transaction_blob()) ==
262  transactions[3]->getSerializer().slice());
263 
264  BEAST_EXPECT(
265  makeSlice(reply.transactions_list()
266  .transactions(3)
267  .metadata_blob()) ==
268  metas[3]->getSerializer().slice());
269  BEAST_EXPECT(reply.skiplist_included());
270 
271  BEAST_EXPECT(s.slice() == makeSlice(reply.ledger_header()));
272 
273  auto parent = env.app().getLedgerMaster().getLedgerBySeq(3);
274 
275  SHAMap::Delta differences;
276 
277  int maxDifferences = std::numeric_limits<int>::max();
278 
279  bool res = parent->stateMap().compare(
280  ledger->stateMap(), differences, maxDifferences);
281  BEAST_EXPECT(res);
282 
283  size_t idx = 0;
284  for (auto& [k, v] : differences)
285  {
286  BEAST_EXPECT(
287  k ==
289  reply.ledger_objects().objects(idx).key().data()));
290  if (v.second)
291  {
292  BEAST_EXPECT(
293  v.second->slice() ==
294  makeSlice(reply.ledger_objects().objects(idx).data()));
295  }
296  ++idx;
297  }
298  }
299  {
300  auto [status, reply] = grpcLedger(4, true, true, true, true);
301 
302  BEAST_EXPECT(status.ok());
303  BEAST_EXPECT(reply.validated());
304  BEAST_EXPECT(!reply.has_hashes_list());
305  BEAST_EXPECT(reply.object_neighbors_included());
306 
307  BEAST_EXPECT(reply.has_transactions_list());
308  BEAST_EXPECT(reply.transactions_list().transactions_size() == 4);
309 
310  BEAST_EXPECT(
311  makeSlice(reply.transactions_list()
312  .transactions(0)
313  .transaction_blob()) ==
314  transactions[0]->getSerializer().slice());
315 
316  BEAST_EXPECT(
317  makeSlice(reply.transactions_list()
318  .transactions(0)
319  .metadata_blob()) ==
320  metas[0]->getSerializer().slice());
321 
322  BEAST_EXPECT(
323  makeSlice(reply.transactions_list()
324  .transactions(1)
325  .transaction_blob()) ==
326  transactions[1]->getSerializer().slice());
327 
328  BEAST_EXPECT(
329  makeSlice(reply.transactions_list()
330  .transactions(1)
331  .metadata_blob()) ==
332  metas[1]->getSerializer().slice());
333 
334  BEAST_EXPECT(
335  makeSlice(reply.transactions_list()
336  .transactions(2)
337  .transaction_blob()) ==
338  transactions[2]->getSerializer().slice());
339 
340  BEAST_EXPECT(
341  makeSlice(reply.transactions_list()
342  .transactions(2)
343  .metadata_blob()) ==
344  metas[2]->getSerializer().slice());
345 
346  BEAST_EXPECT(
347  makeSlice(reply.transactions_list()
348  .transactions(3)
349  .transaction_blob()) ==
350  transactions[3]->getSerializer().slice());
351 
352  BEAST_EXPECT(
353  makeSlice(reply.transactions_list()
354  .transactions(3)
355  .metadata_blob()) ==
356  metas[3]->getSerializer().slice());
357  BEAST_EXPECT(reply.skiplist_included());
358 
359  BEAST_EXPECT(s.slice() == makeSlice(reply.ledger_header()));
360 
361  auto parent = env.app().getLedgerMaster().getLedgerBySeq(3);
362 
363  SHAMap::Delta differences;
364 
365  int maxDifferences = std::numeric_limits<int>::max();
366 
367  bool res = parent->stateMap().compare(
368  ledger->stateMap(), differences, maxDifferences);
369  BEAST_EXPECT(res);
370 
371  size_t idx = 0;
372 
373  for (auto& [k, v] : differences)
374  {
375  auto obj = reply.ledger_objects().objects(idx);
376  BEAST_EXPECT(k == uint256::fromVoid(obj.key().data()));
377  if (v.second)
378  {
379  BEAST_EXPECT(v.second->slice() == makeSlice(obj.data()));
380  }
381  else
382  BEAST_EXPECT(obj.data().size() == 0);
383 
384  if (!(v.first && v.second))
385  {
386  auto succ = ledger->stateMap().upper_bound(k);
387  auto pred = ledger->stateMap().lower_bound(k);
388 
389  if (succ != ledger->stateMap().end())
390  BEAST_EXPECT(
391  succ->key() ==
392  uint256::fromVoid(obj.successor().data()));
393  else
394  BEAST_EXPECT(obj.successor().size() == 0);
395  if (pred != ledger->stateMap().end())
396  BEAST_EXPECT(
397  pred->key() ==
398  uint256::fromVoid(obj.predecessor().data()));
399  else
400  BEAST_EXPECT(obj.predecessor().size() == 0);
401  }
402  ++idx;
403  }
404  }
405 
406  // Delete an account
407 
408  env(noop(alice));
409 
410  std::uint32_t const ledgerCount{
411  env.current()->seq() + 257 - env.seq(alice)};
412 
413  for (std::uint32_t i = 0; i < ledgerCount; ++i)
414  env.close();
415 
416  auto const acctDelFee{drops(env.current()->fees().increment)};
417  env(acctdelete(alice, bob), fee(acctDelFee));
418  env.close();
419 
420  {
421  auto [status, reply] =
422  grpcLedger(env.closed()->seq(), true, true, true, true);
423 
424  BEAST_EXPECT(status.ok());
425  BEAST_EXPECT(reply.validated());
426  auto base =
427  env.app().getLedgerMaster().getLedgerBySeq(env.closed()->seq());
428 
429  auto parent = env.app().getLedgerMaster().getLedgerBySeq(
430  env.closed()->seq() - 1);
431 
432  SHAMap::Delta differences;
433 
434  int maxDifferences = std::numeric_limits<int>::max();
435 
436  bool res = parent->stateMap().compare(
437  base->stateMap(), differences, maxDifferences);
438  BEAST_EXPECT(res);
439 
440  size_t idx = 0;
441  for (auto& [k, v] : differences)
442  {
443  auto obj = reply.ledger_objects().objects(idx);
444  BEAST_EXPECT(k == uint256::fromVoid(obj.key().data()));
445  if (v.second)
446  {
447  BEAST_EXPECT(
448  v.second->slice() ==
449  makeSlice(reply.ledger_objects().objects(idx).data()));
450  }
451  else
452  BEAST_EXPECT(obj.data().size() == 0);
453  if (!(v.first && v.second))
454  {
455  auto succ = base->stateMap().upper_bound(k);
456  auto pred = base->stateMap().lower_bound(k);
457 
458  if (succ != base->stateMap().end())
459  BEAST_EXPECT(
460  succ->key() ==
461  uint256::fromVoid(obj.successor().data()));
462  else
463  BEAST_EXPECT(obj.successor().size() == 0);
464  if (pred != base->stateMap().end())
465  BEAST_EXPECT(
466  pred->key() ==
467  uint256::fromVoid(obj.predecessor().data()));
468  else
469  BEAST_EXPECT(obj.predecessor().size() == 0);
470  }
471 
472  ++idx;
473  }
474  }
475  }
476 
477  // gRPC stuff
479  {
480  public:
481  org::xrpl::rpc::v1::GetLedgerDataRequest request;
482  org::xrpl::rpc::v1::GetLedgerDataResponse reply;
483 
484  explicit GrpcLedgerDataClient(std::string const& port)
485  : GRPCTestClientBase(port)
486  {
487  }
488 
489  void
491  {
492  status = stub_->GetLedgerData(&context, request, &reply);
493  }
494  };
495  void
497  {
498  testcase("GetLedgerData");
499  using namespace test::jtx;
501  std::string grpcPort = *(*config)["port_grpc"].get<std::string>("port");
502  Env env(*this, std::move(config));
503  auto grpcLedgerData = [&grpcPort](
504  auto sequence, std::string marker = "") {
505  GrpcLedgerDataClient grpcClient{grpcPort};
506 
507  grpcClient.request.mutable_ledger()->set_sequence(sequence);
508  if (marker.size())
509  {
510  grpcClient.request.set_marker(marker);
511  }
512 
513  grpcClient.GetLedgerData();
514  return std::make_pair(grpcClient.status, grpcClient.reply);
515  };
516 
517  Account const alice{"alice"};
518  env.fund(XRP(100000), alice);
519 
520  int num_accounts = 10;
521 
522  for (auto i = 0; i < num_accounts; i++)
523  {
524  Account const bob{std::string("bob") + std::to_string(i)};
525  env.fund(XRP(1000), bob);
526  }
527  env.close();
528 
529  {
530  auto [status, reply] = grpcLedgerData(env.closed()->seq());
531  BEAST_EXPECT(status.ok());
532 
533  BEAST_EXPECT(
534  reply.ledger_objects().objects_size() == num_accounts + 4);
535  BEAST_EXPECT(reply.marker().size() == 0);
536  auto ledger = env.closed();
537  size_t idx = 0;
538  for (auto& sle : ledger->sles)
539  {
540  BEAST_EXPECT(
541  sle->getSerializer().slice() ==
542  makeSlice(reply.ledger_objects().objects(idx).data()));
543  ++idx;
544  }
545  }
546 
547  {
548  auto [status, reply] =
549  grpcLedgerData(env.closed()->seq(), "bad marker");
550  BEAST_EXPECT(!status.ok());
551  BEAST_EXPECT(
552  status.error_code() == grpc::StatusCode::INVALID_ARGUMENT);
553  }
554 
555  num_accounts = 3000;
556 
557  for (auto i = 0; i < num_accounts; i++)
558  {
559  Account const cat{std::string("cat") + std::to_string(i)};
560  env.fund(XRP(1000), cat);
561  if (i % 100 == 0)
562  env.close();
563  }
564  env.close();
565 
566  {
567  auto [status, reply] = grpcLedgerData(env.closed()->seq());
568  BEAST_EXPECT(status.ok());
569 
570  int maxLimit = RPC::Tuning::pageLength(true);
571  BEAST_EXPECT(reply.ledger_objects().objects_size() == maxLimit);
572  BEAST_EXPECT(reply.marker().size() != 0);
573 
574  auto [status2, reply2] =
575  grpcLedgerData(env.closed()->seq(), reply.marker());
576  BEAST_EXPECT(status2.ok());
577  BEAST_EXPECT(reply2.marker().size() == 0);
578 
579  auto ledger = env.closed();
580  size_t idx = 0;
581  for (auto& sle : ledger->sles)
582  {
583  auto& obj = idx < maxLimit
584  ? reply.ledger_objects().objects(idx)
585  : reply2.ledger_objects().objects(idx - maxLimit);
586 
587  BEAST_EXPECT(
588  sle->getSerializer().slice() == makeSlice(obj.data()));
589  ++idx;
590  }
591  BEAST_EXPECT(
592  idx ==
593  reply.ledger_objects().objects_size() +
594  reply2.ledger_objects().objects_size());
595  }
596  }
597 
598  // gRPC stuff
600  {
601  public:
602  org::xrpl::rpc::v1::GetLedgerDiffRequest request;
603  org::xrpl::rpc::v1::GetLedgerDiffResponse reply;
604 
605  explicit GrpcLedgerDiffClient(std::string const& port)
606  : GRPCTestClientBase(port)
607  {
608  }
609 
610  void
612  {
613  status = stub_->GetLedgerDiff(&context, request, &reply);
614  }
615  };
616 
617  void
619  {
620  testcase("GetLedgerDiff");
621  using namespace test::jtx;
623  std::string grpcPort = *(*config)["port_grpc"].get<std::string>("port");
624  Env env(*this, std::move(config));
625 
626  auto grpcLedgerDiff = [&grpcPort](
627  auto baseSequence, auto desiredSequence) {
628  GrpcLedgerDiffClient grpcClient{grpcPort};
629 
630  grpcClient.request.mutable_base_ledger()->set_sequence(
631  baseSequence);
632  grpcClient.request.mutable_desired_ledger()->set_sequence(
633  desiredSequence);
634  grpcClient.request.set_include_blobs(true);
635 
636  grpcClient.GetLedgerDiff();
637  return std::make_pair(grpcClient.status, grpcClient.reply);
638  };
639 
640  int num_accounts = 20;
641  for (auto i = 0; i < num_accounts; i++)
642  {
643  Account const cat{std::string("cat") + std::to_string(i)};
644  env.fund(XRP(1000), cat);
645  if (i % 2 == 0)
646  env.close();
647  }
648  env.close();
649 
650  auto compareDiffs = [&](auto baseSequence, auto desiredSequence) {
651  auto [status, reply] =
652  grpcLedgerDiff(baseSequence, desiredSequence);
653 
654  BEAST_EXPECT(status.ok());
655  auto desired =
656  env.app().getLedgerMaster().getLedgerBySeq(desiredSequence);
657 
658  auto base =
659  env.app().getLedgerMaster().getLedgerBySeq(baseSequence);
660 
661  SHAMap::Delta differences;
662 
663  int maxDifferences = std::numeric_limits<int>::max();
664 
665  bool res = base->stateMap().compare(
666  desired->stateMap(), differences, maxDifferences);
667  if (!BEAST_EXPECT(res))
668  return false;
669 
670  size_t idx = 0;
671  for (auto& [k, v] : differences)
672  {
673  if (!BEAST_EXPECT(
674  k ==
676  reply.ledger_objects().objects(idx).key().data())))
677  return false;
678  if (v.second)
679  {
680  if (!BEAST_EXPECT(
681  v.second->slice() ==
682  makeSlice(
683  reply.ledger_objects().objects(idx).data())))
684  return false;
685  }
686 
687  ++idx;
688  }
689  return true;
690  };
691 
692  // Adjacent ledgers
693  BEAST_EXPECT(
694  compareDiffs(env.closed()->seq() - 1, env.closed()->seq()));
695 
696  // Adjacent ledgers further in the past
697  BEAST_EXPECT(
698  compareDiffs(env.closed()->seq() - 3, env.closed()->seq() - 2));
699 
700  // Non-adjacent ledgers
701  BEAST_EXPECT(
702  compareDiffs(env.closed()->seq() - 5, env.closed()->seq() - 1));
703 
704  // Adjacent ledgers but in reverse order
705  BEAST_EXPECT(
706  compareDiffs(env.closed()->seq(), env.closed()->seq() - 1));
707 
708  // Non-adjacent ledgers in reverse order
709  BEAST_EXPECT(
710  compareDiffs(env.closed()->seq() - 1, env.closed()->seq() - 5));
711  }
712 
713  // gRPC stuff
715  {
716  public:
717  org::xrpl::rpc::v1::GetLedgerEntryRequest request;
718  org::xrpl::rpc::v1::GetLedgerEntryResponse reply;
719 
720  explicit GrpcLedgerEntryClient(std::string const& port)
721  : GRPCTestClientBase(port)
722  {
723  }
724 
725  void
727  {
728  status = stub_->GetLedgerEntry(&context, request, &reply);
729  }
730  };
731 
732  void
734  {
735  testcase("GetLedgerDiff");
736  using namespace test::jtx;
738  std::string grpcPort = *(*config)["port_grpc"].get<std::string>("port");
739  Env env(*this, std::move(config));
740 
741  auto grpcLedgerEntry = [&grpcPort](auto sequence, auto key) {
742  GrpcLedgerEntryClient grpcClient{grpcPort};
743 
744  grpcClient.request.mutable_ledger()->set_sequence(sequence);
745  grpcClient.request.set_key(key.data(), key.size());
746 
747  grpcClient.GetLedgerEntry();
748  return std::make_pair(grpcClient.status, grpcClient.reply);
749  };
750 
751  Account const alice{"alice"};
752  env.fund(XRP(1000), alice);
753  env.close();
754 
755  for (auto& sle : env.closed()->sles)
756  {
757  auto [status, reply] =
758  grpcLedgerEntry(env.closed()->seq(), sle->key());
759 
760  BEAST_EXPECT(status.ok());
761 
762  BEAST_EXPECT(
763  uint256::fromVoid(reply.ledger_object().key().data()) ==
764  sle->key());
765  BEAST_EXPECT(
766  makeSlice(reply.ledger_object().data()) ==
767  sle->getSerializer().slice());
768  }
769  }
770 
771  void
773  {
774  testcase("NeedCurrentOrClosed");
775 
776  {
777  org::xrpl::rpc::v1::GetLedgerRequest request;
778  request.mutable_ledger()->set_sequence(1);
779  BEAST_EXPECT(!needCurrentOrClosed(request));
780  request.mutable_ledger()->set_hash("");
781  BEAST_EXPECT(!needCurrentOrClosed(request));
782  request.mutable_ledger()->set_shortcut(
783  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
784  BEAST_EXPECT(!needCurrentOrClosed(request));
785  request.mutable_ledger()->set_shortcut(
786  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
787  BEAST_EXPECT(!needCurrentOrClosed(request));
788  request.mutable_ledger()->set_shortcut(
789  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
790  BEAST_EXPECT(needCurrentOrClosed(request));
791  request.mutable_ledger()->set_shortcut(
792  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
793  BEAST_EXPECT(needCurrentOrClosed(request));
794  }
795 
796  {
797  org::xrpl::rpc::v1::GetLedgerDataRequest request;
798  request.mutable_ledger()->set_sequence(1);
799  BEAST_EXPECT(!needCurrentOrClosed(request));
800  request.mutable_ledger()->set_hash("");
801  BEAST_EXPECT(!needCurrentOrClosed(request));
802  request.mutable_ledger()->set_shortcut(
803  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
804  BEAST_EXPECT(!needCurrentOrClosed(request));
805  request.mutable_ledger()->set_shortcut(
806  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
807  BEAST_EXPECT(!needCurrentOrClosed(request));
808  request.mutable_ledger()->set_shortcut(
809  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
810  BEAST_EXPECT(needCurrentOrClosed(request));
811  request.mutable_ledger()->set_shortcut(
812  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
813  BEAST_EXPECT(needCurrentOrClosed(request));
814  }
815 
816  {
817  org::xrpl::rpc::v1::GetLedgerEntryRequest request;
818  request.mutable_ledger()->set_sequence(1);
819  BEAST_EXPECT(!needCurrentOrClosed(request));
820  request.mutable_ledger()->set_hash("");
821  BEAST_EXPECT(!needCurrentOrClosed(request));
822  request.mutable_ledger()->set_shortcut(
823  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
824  BEAST_EXPECT(!needCurrentOrClosed(request));
825  request.mutable_ledger()->set_shortcut(
826  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
827  BEAST_EXPECT(!needCurrentOrClosed(request));
828  request.mutable_ledger()->set_shortcut(
829  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
830  BEAST_EXPECT(needCurrentOrClosed(request));
831  request.mutable_ledger()->set_shortcut(
832  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
833  BEAST_EXPECT(needCurrentOrClosed(request));
834  }
835 
836  {
837  org::xrpl::rpc::v1::GetLedgerDiffRequest request;
838 
839  // set desired ledger, so desired ledger does not need current or
840  // closed
841  request.mutable_base_ledger()->set_shortcut(
842  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
843 
844  request.mutable_base_ledger()->set_sequence(1);
845  BEAST_EXPECT(!needCurrentOrClosed(request));
846  request.mutable_base_ledger()->set_hash("");
847  BEAST_EXPECT(!needCurrentOrClosed(request));
848  request.mutable_base_ledger()->set_shortcut(
849  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
850  BEAST_EXPECT(!needCurrentOrClosed(request));
851  request.mutable_base_ledger()->set_shortcut(
852  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
853  BEAST_EXPECT(!needCurrentOrClosed(request));
854  request.mutable_base_ledger()->set_shortcut(
855  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
856  BEAST_EXPECT(needCurrentOrClosed(request));
857  request.mutable_base_ledger()->set_shortcut(
858  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
859  BEAST_EXPECT(needCurrentOrClosed(request));
860 
861  // reset base ledger, so base ledger doesn't need current or closed
862  request.mutable_base_ledger()->set_shortcut(
863  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
864 
865  request.mutable_desired_ledger()->set_sequence(1);
866  BEAST_EXPECT(!needCurrentOrClosed(request));
867  request.mutable_desired_ledger()->set_hash("");
868  BEAST_EXPECT(!needCurrentOrClosed(request));
869  request.mutable_desired_ledger()->set_shortcut(
870  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
871  BEAST_EXPECT(!needCurrentOrClosed(request));
872  request.mutable_desired_ledger()->set_shortcut(
873  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
874  BEAST_EXPECT(!needCurrentOrClosed(request));
875  request.mutable_desired_ledger()->set_shortcut(
876  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
877  BEAST_EXPECT(needCurrentOrClosed(request));
878  request.mutable_desired_ledger()->set_shortcut(
879  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
880  BEAST_EXPECT(needCurrentOrClosed(request));
881 
882  // both base and desired need current or closed
883  request.mutable_base_ledger()->set_shortcut(
884  org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
885  BEAST_EXPECT(needCurrentOrClosed(request));
886  }
887  }
888 
889  void
891  {
892  testcase("SecureGateway");
893  using namespace test::jtx;
894  {
897  std::string grpcPort =
898  *(*config)["port_grpc"].get<std::string>("port");
899  Env env(*this, std::move(config));
900 
901  env.close();
902 
903  auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
904 
905  BEAST_EXPECT(env.current()->info().seq == 4);
906 
907  auto grpcLedger = [&grpcPort](
908  auto sequence,
909  std::string const& clientIp,
910  std::string const& user) {
911  GrpcLedgerClient grpcClient{grpcPort};
912 
913  grpcClient.request.mutable_ledger()->set_sequence(sequence);
914  grpcClient.request.set_client_ip(clientIp);
915  grpcClient.request.set_user(user);
916 
917  grpcClient.GetLedger();
918  return std::make_pair(grpcClient.status, grpcClient.reply);
919  };
920 
921  {
922  auto [status, reply] =
923  grpcLedger(env.current()->info().seq, "", "");
924  BEAST_EXPECT(!reply.is_unlimited());
925  BEAST_EXPECT(status.ok());
926  }
927  {
928  auto [status, reply] =
929  grpcLedger(env.current()->info().seq, "", "ETL");
930  BEAST_EXPECT(reply.is_unlimited());
931  BEAST_EXPECT(status.ok());
932  }
933  {
934  auto [status, reply] =
935  grpcLedger(env.current()->info().seq, "", "Reporting");
936  BEAST_EXPECT(reply.is_unlimited());
937  BEAST_EXPECT(status.ok());
938  }
939  {
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());
944  }
945  {
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());
950  }
951  }
952 
953  {
954  std::string secureGatewayIp = "44.124.234.79";
955  std::unique_ptr<Config> config =
956  envconfig(addGrpcConfigWithSecureGateway, secureGatewayIp);
957  std::string grpcPort =
958  *(*config)["port_grpc"].get<std::string>("port");
959  Env env(*this, std::move(config));
960 
961  env.close();
962 
963  auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
964 
965  BEAST_EXPECT(env.current()->info().seq == 4);
966 
967  auto grpcLedger = [&grpcPort](
968  auto sequence,
969  std::string const& clientIp,
970  std::string const& user) {
971  GrpcLedgerClient grpcClient{grpcPort};
972 
973  grpcClient.request.mutable_ledger()->set_sequence(sequence);
974  grpcClient.request.set_client_ip(clientIp);
975  grpcClient.request.set_user(user);
976 
977  grpcClient.GetLedger();
978  return std::make_pair(grpcClient.status, grpcClient.reply);
979  };
980 
981  {
982  auto [status, reply] =
983  grpcLedger(env.current()->info().seq, "", "");
984  BEAST_EXPECT(!reply.is_unlimited());
985  BEAST_EXPECT(status.ok());
986  }
987  {
988  auto [status, reply] =
989  grpcLedger(env.current()->info().seq, "", "ETL");
990  BEAST_EXPECT(!reply.is_unlimited());
991  BEAST_EXPECT(status.ok());
992  }
993  {
994  auto [status, reply] = grpcLedger(
995  env.current()->info().seq, secureGatewayIp, "ETL");
996  BEAST_EXPECT(!reply.is_unlimited());
997  BEAST_EXPECT(status.ok());
998  }
999  {
1000  auto [status, reply] =
1001  grpcLedger(env.current()->info().seq, secureGatewayIp, "");
1002  BEAST_EXPECT(!reply.is_unlimited());
1003  BEAST_EXPECT(status.ok());
1004  }
1005  }
1006 
1007  {
1010  std::string grpcPort =
1011  *(*config)["port_grpc"].get<std::string>("port");
1012  Env env(*this, std::move(config));
1013 
1014  env.close();
1015 
1016  auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
1017 
1018  BEAST_EXPECT(env.current()->info().seq == 4);
1019  auto grpcLedgerData = [&grpcPort](
1020  auto sequence,
1021  std::string const& clientIp,
1022  std::string const& user) {
1023  GrpcLedgerDataClient grpcClient{grpcPort};
1024 
1025  grpcClient.request.mutable_ledger()->set_sequence(sequence);
1026  grpcClient.request.set_client_ip(clientIp);
1027  grpcClient.request.set_user(user);
1028 
1029  grpcClient.GetLedgerData();
1030  return std::make_pair(grpcClient.status, grpcClient.reply);
1031  };
1032  {
1033  auto [status, reply] =
1034  grpcLedgerData(env.current()->info().seq, "", "");
1035  BEAST_EXPECT(!reply.is_unlimited());
1036  BEAST_EXPECT(status.ok());
1037  }
1038  {
1039  auto [status, reply] =
1040  grpcLedgerData(env.current()->info().seq, "", "ETL");
1041  BEAST_EXPECT(reply.is_unlimited());
1042  BEAST_EXPECT(status.ok());
1043  }
1044  {
1045  auto [status, reply] =
1046  grpcLedgerData(env.current()->info().seq, "", "Reporting");
1047  BEAST_EXPECT(reply.is_unlimited());
1048  BEAST_EXPECT(status.ok());
1049  }
1050  {
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());
1055  }
1056  {
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());
1061  }
1062  }
1063  {
1064  std::string secureGatewayIp = "44.124.234.79";
1065  std::unique_ptr<Config> config =
1066  envconfig(addGrpcConfigWithSecureGateway, secureGatewayIp);
1067  std::string grpcPort =
1068  *(*config)["port_grpc"].get<std::string>("port");
1069  Env env(*this, std::move(config));
1070 
1071  env.close();
1072 
1073  auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
1074 
1075  BEAST_EXPECT(env.current()->info().seq == 4);
1076 
1077  auto grpcLedgerData = [&grpcPort](
1078  auto sequence,
1079  std::string const& clientIp,
1080  std::string const& user) {
1081  GrpcLedgerDataClient grpcClient{grpcPort};
1082 
1083  grpcClient.request.mutable_ledger()->set_sequence(sequence);
1084  grpcClient.request.set_client_ip(clientIp);
1085  grpcClient.request.set_user(user);
1086 
1087  grpcClient.GetLedgerData();
1088  return std::make_pair(grpcClient.status, grpcClient.reply);
1089  };
1090 
1091  {
1092  auto [status, reply] =
1093  grpcLedgerData(env.current()->info().seq, "", "");
1094  BEAST_EXPECT(!reply.is_unlimited());
1095  BEAST_EXPECT(status.ok());
1096  }
1097  {
1098  auto [status, reply] =
1099  grpcLedgerData(env.current()->info().seq, "", "ETL");
1100  BEAST_EXPECT(!reply.is_unlimited());
1101  BEAST_EXPECT(status.ok());
1102  }
1103  {
1104  auto [status, reply] = grpcLedgerData(
1105  env.current()->info().seq, secureGatewayIp, "ETL");
1106  BEAST_EXPECT(!reply.is_unlimited());
1107  BEAST_EXPECT(status.ok());
1108  }
1109  {
1110  auto [status, reply] = grpcLedgerData(
1111  env.current()->info().seq, secureGatewayIp, "");
1112  BEAST_EXPECT(!reply.is_unlimited());
1113  BEAST_EXPECT(status.ok());
1114  }
1115  }
1116  }
1117 
1118 public:
1119  void
1120  run() override
1121  {
1122  testGetLedger();
1123 
1125 
1127 
1129 
1131 
1133  }
1134 };
1135 
1137 
1138 } // namespace test
1139 } // namespace ripple
ripple::test::ReportingETL_test::GrpcLedgerDiffClient::request
org::xrpl::rpc::v1::GetLedgerDiffRequest request
Definition: ReportingETL_test.cpp:602
ripple::test::jtx::noop
Json::Value noop(Account const &account)
The null transaction.
Definition: noop.h:31
ripple::test::ReportingETL_test::run
void run() override
Definition: ReportingETL_test.cpp:1120
ripple::test::jtx::XRP
const XRP_t XRP
Converts to XRP Issue or STAmount.
Definition: amount.cpp:105
ripple::makeSlice
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition: Slice.h:241
std::string
STL class.
ripple::test::jtx::drops
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Definition: amount.h:241
ripple::test::ReportingETL_test::testGetLedgerDiff
void testGetLedgerDiff()
Definition: ReportingETL_test.cpp:618
ripple::test::GRPCTestClientBase::stub_
std::unique_ptr< org::xrpl::rpc::v1::XRPLedgerAPIService::Stub > stub_
Definition: GRPCTestClientBase.h:44
ripple::addRaw
void addRaw(LedgerInfo const &info, Serializer &s, bool includeHash)
Definition: View.cpp:162
std::vector
STL class.
ripple::test::ReportingETL_test::GrpcLedgerClient
Definition: ReportingETL_test.cpp:36
std::vector::size
T size(T... args)
ripple::test::jtx::addGrpcConfig
std::unique_ptr< Config > addGrpcConfig(std::unique_ptr< Config >)
add a grpc address and port to config
Definition: envconfig.cpp:143
ripple::test::ReportingETL_test::GrpcLedgerDataClient
Definition: ReportingETL_test.cpp:478
ripple::test::ReportingETL_test
Definition: ReportingETL_test.cpp:33
ripple::test::jtx::addGrpcConfigWithSecureGateway
std::unique_ptr< Config > addGrpcConfigWithSecureGateway(std::unique_ptr< Config >, std::string const &secureGateway)
add a grpc address, port and secure_gateway to config
Definition: envconfig.cpp:152
ripple::test::ReportingETL_test::testNeedCurrentOrClosed
void testNeedCurrentOrClosed()
Definition: ReportingETL_test.cpp:772
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
ripple::needCurrentOrClosed
bool needCurrentOrClosed(Request &request)
Definition: P2pProxy.h:47
ripple::test::ReportingETL_test::GrpcLedgerDiffClient::reply
org::xrpl::rpc::v1::GetLedgerDiffResponse reply
Definition: ReportingETL_test.cpp:603
ripple::test::ReportingETL_test::testGetLedger
void testGetLedger()
Definition: ReportingETL_test.cpp:54
ripple::test::GRPCTestClientBase::status
grpc::Status status
Definition: GRPCTestClientBase.h:42
ripple::test::BEAST_DEFINE_TESTSUITE_PRIO
BEAST_DEFINE_TESTSUITE_PRIO(AccountDelete, app, ripple, 2)
ripple::test::ReportingETL_test::GrpcLedgerDiffClient::GetLedgerDiff
void GetLedgerDiff()
Definition: ReportingETL_test.cpp:611
ripple::test::ReportingETL_test::GrpcLedgerClient::reply
org::xrpl::rpc::v1::GetLedgerResponse reply
Definition: ReportingETL_test.cpp:40
ripple::test::GRPCTestClientBase
Definition: GRPCTestClientBase.h:29
std::vector::push_back
T push_back(T... args)
ripple::test::getEnvLocalhostAddr
const char * getEnvLocalhostAddr()
Definition: envconfig.h:31
ripple::test::ReportingETL_test::GrpcLedgerEntryClient::GrpcLedgerEntryClient
GrpcLedgerEntryClient(std::string const &port)
Definition: ReportingETL_test.cpp:720
ripple::test::ReportingETL_test::testGetLedgerData
void testGetLedgerData()
Definition: ReportingETL_test.cpp:496
ripple::test::ReportingETL_test::GrpcLedgerClient::GrpcLedgerClient
GrpcLedgerClient(std::string const &port)
Definition: ReportingETL_test.cpp:42
std::to_string
T to_string(T... args)
ripple::Serializer::slice
Slice slice() const noexcept
Definition: Serializer.h:63
ripple::ReportingETL
This class is responsible for continuously extracting data from a p2p node, and writing that data to ...
Definition: ReportingETL.h:70
ripple::RPC::Tuning::pageLength
constexpr int pageLength(bool isBinary)
Maximum number of pages in a LedgerData response.
Definition: rpc/impl/Tuning.h:75
std::uint32_t
ripple::test::ReportingETL_test::GrpcLedgerEntryClient
Definition: ReportingETL_test.cpp:714
std::map
STL class.
ripple::test::GRPCTestClientBase::context
grpc::ClientContext context
Definition: GRPCTestClientBase.h:43
ripple::test::ReportingETL_test::GrpcLedgerDataClient::request
org::xrpl::rpc::v1::GetLedgerDataRequest request
Definition: ReportingETL_test.cpp:481
ripple::test::jtx::fee
Set the fee on a JTx.
Definition: fee.h:35
ripple::Serializer
Definition: Serializer.h:39
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::ReportingETL_test::GrpcLedgerDataClient::GetLedgerData
void GetLedgerData()
Definition: ReportingETL_test.cpp:490
ripple::base_uint< 256 >::fromVoid
static base_uint fromVoid(void const *data)
Definition: base_uint.h:312
ripple::test::ReportingETL_test::GrpcLedgerClient::GetLedger
void GetLedger()
Definition: ReportingETL_test.cpp:48
ripple::test::ReportingETL_test::GrpcLedgerDiffClient::GrpcLedgerDiffClient
GrpcLedgerDiffClient(std::string const &port)
Definition: ReportingETL_test.cpp:605
ripple::test::ReportingETL_test::testSecureGateway
void testSecureGateway()
Definition: ReportingETL_test.cpp:890
ripple::test::ReportingETL_test::GrpcLedgerDataClient::GrpcLedgerDataClient
GrpcLedgerDataClient(std::string const &port)
Definition: ReportingETL_test.cpp:484
ripple::test::jtx::acctdelete
Json::Value acctdelete(Account const &account, Account const &dest)
Delete account.
Definition: acctdelete.cpp:29
ripple::test::ReportingETL_test::testGetLedgerEntry
void testGetLedgerEntry()
Definition: ReportingETL_test.cpp:733
ripple::test::ReportingETL_test::GrpcLedgerDataClient::reply
org::xrpl::rpc::v1::GetLedgerDataResponse reply
Definition: ReportingETL_test.cpp:482
ripple::test::jtx::Account
Immutable cryptographic account descriptor.
Definition: Account.h:37
ripple::test::ReportingETL_test::GrpcLedgerClient::request
org::xrpl::rpc::v1::GetLedgerRequest request
Definition: ReportingETL_test.cpp:39
std::make_pair
T make_pair(T... args)
ripple::test::ReportingETL_test::GrpcLedgerEntryClient::reply
org::xrpl::rpc::v1::GetLedgerEntryResponse reply
Definition: ReportingETL_test.cpp:718
ripple::test::ReportingETL_test::GrpcLedgerEntryClient::request
org::xrpl::rpc::v1::GetLedgerEntryRequest request
Definition: ReportingETL_test.cpp:717
std::numeric_limits::max
T max(T... args)
std::unique_ptr
STL class.
ripple::test::ReportingETL_test::GrpcLedgerDiffClient
Definition: ReportingETL_test.cpp:599
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:116
ripple::test::ReportingETL_test::GrpcLedgerEntryClient::GetLedgerEntry
void GetLedgerEntry()
Definition: ReportingETL_test.cpp:726