rippled
ShardArchiveHandler_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2020 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/beast/utility/temp_dir.h>
21 #include <ripple/core/ConfigSections.h>
22 #include <ripple/nodestore/DummyScheduler.h>
23 #include <ripple/nodestore/Manager.h>
24 #include <ripple/nodestore/impl/DecodedBlob.h>
25 #include <ripple/protocol/jss.h>
26 #include <ripple/rpc/ShardArchiveHandler.h>
27 #include <test/jtx/CaptureLogs.h>
28 #include <test/jtx/Env.h>
29 #include <test/jtx/TrustedPublisherServer.h>
30 #include <test/jtx/envconfig.h>
31 #include <test/nodestore/TestBase.h>
32 
33 namespace ripple {
34 namespace test {
35 
36 class ShardArchiveHandler_test : public beast::unit_test::suite
37 {
39 
41  createServer(jtx::Env& env, bool ssl = true)
42  {
46  env.app().getIOService(),
47  list,
48  env.timeKeeper().now() + std::chrono::seconds{3600},
49  ssl);
50  }
51 
52 public:
53  // Test the shard downloading module by queueing
54  // a download and verifying the contents of the
55  // state database.
56  void
58  {
59  testcase("testSingleDownloadAndStateDB");
60 
61  beast::temp_dir tempDir;
62 
63  auto c = jtx::envconfig();
64  auto& section = c->section(ConfigSection::shardDatabase());
65  section.set("path", tempDir.path());
66  section.set("max_historical_shards", "20");
67  c->setupControl(true, true, true);
68 
69  jtx::Env env(*this, std::move(c));
70  auto handler = env.app().getShardArchiveHandler();
71  BEAST_EXPECT(handler);
72  BEAST_EXPECT(dynamic_cast<RPC::RecoveryHandler*>(handler) == nullptr);
73 
74  std::string const rawUrl = "https://foo:443/1.tar.lz4";
75  parsedURL url;
76 
77  parseUrl(url, rawUrl);
78  handler->add(1, {url, rawUrl});
79 
80  {
81  std::lock_guard<std::mutex> lock(handler->m_);
82 
83  auto& session{handler->sqliteDB_->getSession()};
84 
85  soci::rowset<soci::row> rs =
86  (session.prepare << "SELECT * FROM State;");
87 
88  std::uint64_t rowCount = 0;
89 
90  for (auto it = rs.begin(); it != rs.end(); ++it, ++rowCount)
91  {
92  BEAST_EXPECT(it->get<int>(0) == 1);
93  BEAST_EXPECT(it->get<std::string>(1) == rawUrl);
94  }
95 
96  BEAST_EXPECT(rowCount == 1);
97  }
98 
99  handler->release();
100  }
101 
102  // Test the shard downloading module by queueing
103  // three downloads and verifying the contents of
104  // the state database.
105  void
107  {
108  testcase("testDownloadsAndStateDB");
109 
110  beast::temp_dir tempDir;
111 
112  auto c = jtx::envconfig();
113  auto& section = c->section(ConfigSection::shardDatabase());
114  section.set("path", tempDir.path());
115  section.set("max_historical_shards", "20");
116  c->setupControl(true, true, true);
117 
118  jtx::Env env(*this, std::move(c));
119  auto handler = env.app().getShardArchiveHandler();
120  BEAST_EXPECT(handler);
121  BEAST_EXPECT(dynamic_cast<RPC::RecoveryHandler*>(handler) == nullptr);
122 
123  Downloads const dl = {
124  {1, "https://foo:443/1.tar.lz4"},
125  {2, "https://foo:443/2.tar.lz4"},
126  {3, "https://foo:443/3.tar.lz4"}};
127 
128  for (auto const& entry : dl)
129  {
130  parsedURL url;
131  parseUrl(url, entry.second);
132  handler->add(entry.first, {url, entry.second});
133  }
134 
135  {
136  std::lock_guard<std::mutex> lock(handler->m_);
137 
138  auto& session{handler->sqliteDB_->getSession()};
139  soci::rowset<soci::row> rs =
140  (session.prepare << "SELECT * FROM State;");
141 
142  std::uint64_t pos = 0;
143  for (auto it = rs.begin(); it != rs.end(); ++it, ++pos)
144  {
145  BEAST_EXPECT(it->get<int>(0) == dl[pos].first);
146  BEAST_EXPECT(it->get<std::string>(1) == dl[pos].second);
147  }
148 
149  BEAST_EXPECT(pos == dl.size());
150  }
151 
152  handler->release();
153  }
154 
155  // Test the shard downloading module by initiating
156  // and completing ten downloads and verifying the
157  // contents of the filesystem and the handler's
158  // archives.
159  void
161  {
162  testcase("testDownloadsAndFileSystem");
163 
164  beast::temp_dir tempDir;
165 
166  auto c = jtx::envconfig();
167  auto& section = c->section(ConfigSection::shardDatabase());
168  section.set("path", tempDir.path());
169  section.set("max_historical_shards", "20");
170  section.set("ledgers_per_shard", "256");
171  section.set("earliest_seq", "257");
172  auto& sectionNode = c->section(ConfigSection::nodeDatabase());
173  sectionNode.set("earliest_seq", "257");
174  c->setupControl(true, true, true);
175 
176  jtx::Env env(*this, std::move(c));
177 
178  std::uint8_t const numberOfDownloads = 10;
179 
180  // Create some ledgers so that the ShardArchiveHandler
181  // can verify the last ledger hash for the shard
182  // downloads.
183  for (int i = 0; i < env.app().getShardStore()->ledgersPerShard() *
184  (numberOfDownloads + 1);
185  ++i)
186  {
187  env.close();
188  }
189 
190  auto handler = env.app().getShardArchiveHandler();
191  BEAST_EXPECT(handler);
192  BEAST_EXPECT(dynamic_cast<RPC::RecoveryHandler*>(handler) == nullptr);
193 
194  auto server = createServer(env);
195  auto host = server->local_endpoint().address().to_string();
196  auto port = std::to_string(server->local_endpoint().port());
197  server->stop();
198 
199  Downloads const dl = [count = numberOfDownloads, &host, &port] {
200  Downloads ret;
201 
202  for (int i = 1; i <= count; ++i)
203  {
204  ret.push_back(
205  {i,
206  (boost::format("https://%s:%d/%d.tar.lz4") % host % port %
207  i)
208  .str()});
209  }
210 
211  return ret;
212  }();
213 
214  for (auto const& entry : dl)
215  {
216  parsedURL url;
217  parseUrl(url, entry.second);
218  handler->add(entry.first, {url, entry.second});
219  }
220 
221  BEAST_EXPECT(handler->start());
222 
223  auto stateDir =
225 
226  std::unique_lock<std::mutex> lock(handler->m_);
227 
228  BEAST_EXPECT(
229  boost::filesystem::exists(stateDir) || handler->archives_.empty());
230 
231  using namespace std::chrono_literals;
232  auto waitMax = 60s;
233 
234  while (!handler->archives_.empty())
235  {
236  lock.unlock();
238 
239  if (waitMax -= 1s; waitMax <= 0s)
240  {
241  BEAST_EXPECT(false);
242  break;
243  }
244 
245  lock.lock();
246  }
247 
248  BEAST_EXPECT(!boost::filesystem::exists(stateDir));
249  }
250 
251  // Test the shard downloading module by initiating
252  // and completing ten downloads and verifying the
253  // contents of the filesystem and the handler's
254  // archives. Then restart the application and ensure
255  // that the handler is created and started automatically.
256  void
258  {
259  testcase("testDownloadsAndRestart");
260 
261  beast::temp_dir tempDir;
262 
263  {
264  auto c = jtx::envconfig();
265  auto& section = c->section(ConfigSection::shardDatabase());
266  section.set("path", tempDir.path());
267  section.set("max_historical_shards", "20");
268  section.set("ledgers_per_shard", "256");
269  section.set("earliest_seq", "257");
270  auto& sectionNode = c->section(ConfigSection::nodeDatabase());
271  sectionNode.set("earliest_seq", "257");
272  c->setupControl(true, true, true);
273 
274  jtx::Env env(*this, std::move(c));
275 
276  std::uint8_t const numberOfDownloads = 10;
277 
278  // Create some ledgers so that the ShardArchiveHandler
279  // can verify the last ledger hash for the shard
280  // downloads.
281  for (int i = 0; i < env.app().getShardStore()->ledgersPerShard() *
282  (numberOfDownloads + 1);
283  ++i)
284  {
285  env.close();
286  }
287 
288  auto handler = env.app().getShardArchiveHandler();
289  BEAST_EXPECT(handler);
290  BEAST_EXPECT(
291  dynamic_cast<RPC::RecoveryHandler*>(handler) == nullptr);
292 
293  auto server = createServer(env);
294  auto host = server->local_endpoint().address().to_string();
295  auto port = std::to_string(server->local_endpoint().port());
296  server->stop();
297 
298  Downloads const dl = [count = numberOfDownloads, &host, &port] {
299  Downloads ret;
300 
301  for (int i = 1; i <= count; ++i)
302  {
303  ret.push_back(
304  {i,
305  (boost::format("https://%s:%d/%d.tar.lz4") % host %
306  port % i)
307  .str()});
308  }
309 
310  return ret;
311  }();
312 
313  for (auto const& entry : dl)
314  {
315  parsedURL url;
316  parseUrl(url, entry.second);
317  handler->add(entry.first, {url, entry.second});
318  }
319 
321  env.app().config());
322 
323  boost::filesystem::copy_file(
324  stateDir / stateDBName,
325  boost::filesystem::path(tempDir.path()) / stateDBName);
326 
327  BEAST_EXPECT(handler->start());
328 
329  std::unique_lock<std::mutex> lock(handler->m_);
330 
331  BEAST_EXPECT(
332  boost::filesystem::exists(stateDir) ||
333  handler->archives_.empty());
334 
335  using namespace std::chrono_literals;
336  auto waitMax = 60s;
337 
338  while (!handler->archives_.empty())
339  {
340  lock.unlock();
342 
343  if (waitMax -= 1s; waitMax <= 0s)
344  {
345  BEAST_EXPECT(false);
346  break;
347  }
348 
349  lock.lock();
350  }
351 
352  BEAST_EXPECT(!boost::filesystem::exists(stateDir));
353 
354  boost::filesystem::create_directory(stateDir);
355 
356  boost::filesystem::copy_file(
357  boost::filesystem::path(tempDir.path()) / stateDBName,
358  stateDir / stateDBName);
359  }
360 
361  auto c = jtx::envconfig();
362  auto& section = c->section(ConfigSection::shardDatabase());
363  section.set("path", tempDir.path());
364  section.set("max_historical_shards", "20");
365  section.set("ledgers_per_shard", "256");
366  section.set("shard_verification_retry_interval", "1");
367  section.set("shard_verification_max_attempts", "10000");
368  section.set("earliest_seq", "257");
369  auto& sectionNode = c->section(ConfigSection::nodeDatabase());
370  sectionNode.set("earliest_seq", "257");
371  c->setupControl(true, true, true);
372 
373  jtx::Env env(*this, std::move(c));
374 
375  std::uint8_t const numberOfDownloads = 10;
376 
377  // Create some ledgers so that the ShardArchiveHandler
378  // can verify the last ledger hash for the shard
379  // downloads.
380  for (int i = 0; i < env.app().getShardStore()->ledgersPerShard() *
381  (numberOfDownloads + 1);
382  ++i)
383  {
384  env.close();
385  }
386 
387  auto handler = env.app().getShardArchiveHandler();
388  BEAST_EXPECT(dynamic_cast<RPC::RecoveryHandler*>(handler) != nullptr);
389 
390  auto stateDir =
392 
393  std::unique_lock<std::mutex> lock(handler->m_);
394 
395  BEAST_EXPECT(
396  boost::filesystem::exists(stateDir) || handler->archives_.empty());
397 
398  using namespace std::chrono_literals;
399  auto waitMax = 60s;
400 
401  while (!handler->archives_.empty())
402  {
403  lock.unlock();
405 
406  if (waitMax -= 1s; waitMax <= 0s)
407  {
408  BEAST_EXPECT(false);
409  break;
410  }
411 
412  lock.lock();
413  }
414 
415  BEAST_EXPECT(!boost::filesystem::exists(stateDir));
416  }
417 
418  // Ensure that downloads fail when the shard
419  // database cannot store any more shards
420  void
422  {
423  testcase("testShardCountFailure");
424  std::string capturedLogs;
425 
426  {
427  beast::temp_dir tempDir;
428 
429  auto c = jtx::envconfig();
430  auto& section = c->section(ConfigSection::shardDatabase());
431  section.set("path", tempDir.path());
432  section.set("max_historical_shards", "1");
433  section.set("ledgers_per_shard", "256");
434  section.set("earliest_seq", "257");
435  auto& sectionNode = c->section(ConfigSection::nodeDatabase());
436  sectionNode.set("earliest_seq", "257");
437  c->setupControl(true, true, true);
438 
439  std::unique_ptr<Logs> logs(new CaptureLogs(&capturedLogs));
440  jtx::Env env(*this, std::move(c), std::move(logs));
441 
442  std::uint8_t const numberOfDownloads = 10;
443 
444  // Create some ledgers so that the ShardArchiveHandler
445  // can verify the last ledger hash for the shard
446  // downloads.
447  for (int i = 0; i < env.app().getShardStore()->ledgersPerShard() *
448  (numberOfDownloads + 1);
449  ++i)
450  {
451  env.close();
452  }
453 
454  auto handler = env.app().getShardArchiveHandler();
455  BEAST_EXPECT(handler);
456  BEAST_EXPECT(
457  dynamic_cast<RPC::RecoveryHandler*>(handler) == nullptr);
458 
459  auto server = createServer(env);
460  auto host = server->local_endpoint().address().to_string();
461  auto port = std::to_string(server->local_endpoint().port());
462  server->stop();
463 
464  Downloads const dl = [count = numberOfDownloads, &host, &port] {
465  Downloads ret;
466 
467  for (int i = 1; i <= count; ++i)
468  {
469  ret.push_back(
470  {i,
471  (boost::format("https://%s:%d/%d.tar.lz4") % host %
472  port % i)
473  .str()});
474  }
475 
476  return ret;
477  }();
478 
479  for (auto const& entry : dl)
480  {
481  parsedURL url;
482  parseUrl(url, entry.second);
483  handler->add(entry.first, {url, entry.second});
484  }
485 
486  BEAST_EXPECT(!handler->start());
488  env.app().config());
489 
490  handler->release();
491  BEAST_EXPECT(!boost::filesystem::exists(stateDir));
492  }
493 
494  auto const expectedErrorMessage =
495  "shards 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 maximum number of historical "
496  "shards reached";
497  BEAST_EXPECT(
498  capturedLogs.find(expectedErrorMessage) != std::string::npos);
499 
500  {
501  beast::temp_dir tempDir;
502 
503  auto c = jtx::envconfig();
504  auto& section = c->section(ConfigSection::shardDatabase());
505  section.set("path", tempDir.path());
506  section.set("max_historical_shards", "0");
507  section.set("ledgers_per_shard", "256");
508  section.set("earliest_seq", "257");
509  auto& sectionNode = c->section(ConfigSection::nodeDatabase());
510  sectionNode.set("earliest_seq", "257");
511  c->setupControl(true, true, true);
512 
513  std::unique_ptr<Logs> logs(new CaptureLogs(&capturedLogs));
514  jtx::Env env(*this, std::move(c), std::move(logs));
515 
516  std::uint8_t const numberOfDownloads = 1;
517 
518  // Create some ledgers so that the ShardArchiveHandler
519  // can verify the last ledger hash for the shard
520  // downloads.
521  for (int i = 0; i < env.app().getShardStore()->ledgersPerShard() *
522  ((numberOfDownloads * 3) + 1);
523  ++i)
524  {
525  env.close();
526  }
527 
528  auto handler = env.app().getShardArchiveHandler();
529  BEAST_EXPECT(handler);
530  BEAST_EXPECT(
531  dynamic_cast<RPC::RecoveryHandler*>(handler) == nullptr);
532 
533  auto server = createServer(env);
534  auto host = server->local_endpoint().address().to_string();
535  auto port = std::to_string(server->local_endpoint().port());
536  server->stop();
537 
538  Downloads const dl = [count = numberOfDownloads, &host, &port] {
539  Downloads ret;
540 
541  for (int i = 1; i <= count; ++i)
542  {
543  ret.push_back(
544  {i,
545  (boost::format("https://%s:%d/%d.tar.lz4") % host %
546  port % i)
547  .str()});
548  }
549 
550  return ret;
551  }();
552 
553  for (auto const& entry : dl)
554  {
555  parsedURL url;
556  parseUrl(url, entry.second);
557  handler->add(entry.first, {url, entry.second});
558  }
559 
560  BEAST_EXPECT(!handler->start());
562  env.app().config());
563 
564  handler->release();
565  BEAST_EXPECT(!boost::filesystem::exists(stateDir));
566  }
567 
568  auto const expectedErrorMessage2 =
569  "shard 1 maximum number of historical shards reached";
570  BEAST_EXPECT(
571  capturedLogs.find(expectedErrorMessage2) != std::string::npos);
572  }
573 
574  // Ensure that downloads fail when the shard
575  // database has already stored one of the
576  // queued shards
577  void
579  {
580  testcase("testRedundantShardFailure");
581  std::string capturedLogs;
582 
583  {
584  beast::temp_dir tempDir;
585 
586  auto c = jtx::envconfig();
587  auto& section = c->section(ConfigSection::shardDatabase());
588  section.set("path", tempDir.path());
589  section.set("max_historical_shards", "1");
590  section.set("ledgers_per_shard", "256");
591  section.set("earliest_seq", "257");
592  auto& sectionNode = c->section(ConfigSection::nodeDatabase());
593  sectionNode.set("earliest_seq", "257");
594  c->setupControl(true, true, true);
595 
596  std::unique_ptr<Logs> logs(new CaptureLogs(&capturedLogs));
597  jtx::Env env(
598  *this,
599  std::move(c),
600  std::move(logs),
602 
603  std::uint8_t const numberOfDownloads = 10;
604 
605  // Create some ledgers so that the ShardArchiveHandler
606  // can verify the last ledger hash for the shard
607  // downloads.
608  for (int i = 0; i < env.app().getShardStore()->ledgersPerShard() *
609  (numberOfDownloads + 1);
610  ++i)
611  {
612  env.close();
613  }
614 
615  env.app().getShardStore()->prepareShards({1});
616 
617  auto handler = env.app().getShardArchiveHandler();
618  BEAST_EXPECT(handler);
619  BEAST_EXPECT(
620  dynamic_cast<RPC::RecoveryHandler*>(handler) == nullptr);
621 
622  auto server = createServer(env);
623  auto host = server->local_endpoint().address().to_string();
624  auto port = std::to_string(server->local_endpoint().port());
625  server->stop();
626 
627  Downloads const dl = [count = numberOfDownloads, &host, &port] {
628  Downloads ret;
629 
630  for (int i = 1; i <= count; ++i)
631  {
632  ret.push_back(
633  {i,
634  (boost::format("https://%s:%d/%d.tar.lz4") % host %
635  port % i)
636  .str()});
637  }
638 
639  return ret;
640  }();
641 
642  for (auto const& entry : dl)
643  {
644  parsedURL url;
645  parseUrl(url, entry.second);
646  handler->add(entry.first, {url, entry.second});
647  }
648 
649  BEAST_EXPECT(!handler->start());
651  env.app().config());
652 
653  handler->release();
654  BEAST_EXPECT(!boost::filesystem::exists(stateDir));
655  }
656 
657  auto const expectedErrorMessage =
658  "shard 1 is already queued for import";
659  BEAST_EXPECT(
660  capturedLogs.find(expectedErrorMessage) != std::string::npos);
661  }
662 
663  void
664  run() override
665  {
672  }
673 };
674 
675 BEAST_DEFINE_TESTSUITE(ShardArchiveHandler, app, ripple);
676 
677 } // namespace test
678 } // namespace ripple
ripple::RPC::ShardArchiveHandler::getDownloadDirectory
static boost::filesystem::path getDownloadDirectory(Config const &config)
Definition: ShardArchiveHandler.cpp:37
std::this_thread::sleep_for
T sleep_for(T... args)
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountDelete, app, ripple)
std::string
STL class.
std::shared_ptr
STL class.
ripple::parsedURL
Definition: StringUtilities.h:100
std::vector
STL class.
std::string::find
T find(T... args)
ripple::ConfigSection::shardDatabase
static std::string shardDatabase()
Definition: ConfigSections.h:38
ripple::test::ShardArchiveHandler_test::testShardCountFailure
void testShardCountFailure()
Definition: ShardArchiveHandler_test.cpp:421
std::chrono::seconds
std::lock_guard
STL class.
ripple::test::jtx::Env::timeKeeper
ManualTimeKeeper & timeKeeper()
Definition: Env.h:252
ripple::Application::getShardStore
virtual NodeStore::DatabaseShard * getShardStore()=0
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:240
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
ripple::test::ShardArchiveHandler_test::testDownloadsAndRestart
void testDownloadsAndRestart()
Definition: ShardArchiveHandler_test.cpp:257
ripple::test::ShardArchiveHandler_test::createServer
std::shared_ptr< TrustedPublisherServer > createServer(jtx::Env &env, bool ssl=true)
Definition: ShardArchiveHandler_test.cpp:41
std::vector::push_back
T push_back(T... args)
ripple::test::make_TrustedPublisherServer
std::shared_ptr< TrustedPublisherServer > make_TrustedPublisherServer(boost::asio::io_context &ioc, std::vector< TrustedPublisherServer::Validator > const &validators, NetClock::time_point expiration, bool useSSL=false, int version=1, bool immediateStart=true, int sequence=1)
Definition: TrustedPublisherServer.h:618
ripple::test::ShardArchiveHandler_test::testDownloadsAndFileSystem
void testDownloadsAndFileSystem()
Definition: ShardArchiveHandler_test.cpp:160
ripple::Application::config
virtual Config & config()=0
std::unique_lock
STL class.
std::to_string
T to_string(T... args)
ripple::parseUrl
bool parseUrl(parsedURL &pUrl, std::string const &strUrl)
Definition: StringUtilities.cpp:47
std::uint64_t
ripple::test::TrustedPublisherServer::randomValidator
static Validator randomValidator()
Definition: TrustedPublisherServer.h:131
ripple::NodeStore::DatabaseShard::prepareShards
virtual bool prepareShards(std::vector< std::uint32_t > const &shardIndexes)=0
Prepare one or more shard indexes to be imported into the database.
beast::temp_dir::path
std::string path() const
Get the native path for the temporary directory.
Definition: temp_dir.h:66
ripple::Application::getIOService
virtual boost::asio::io_service & getIOService()=0
ripple::RPC::RecoveryHandler
Definition: ShardArchiveHandler.h:161
ripple::stateDBName
static constexpr auto stateDBName
Definition: DBInit.h:174
ripple::test::CaptureLogs
Log manager for CaptureSinks.
Definition: CaptureLogs.h:31
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::ShardArchiveHandler_test::testRedundantShardFailure
void testRedundantShardFailure()
Definition: ShardArchiveHandler_test.cpp:578
ripple::test::ShardArchiveHandler_test::testDownloadsAndStateDB
void testDownloadsAndStateDB()
Definition: ShardArchiveHandler_test.cpp:106
ripple::test::jtx::Env::close
bool close(NetClock::time_point closeTime, boost::optional< std::chrono::milliseconds > consensusDelay=boost::none)
Close and advance the ledger.
Definition: Env.cpp:121
beast::severities::kDebug
@ kDebug
Definition: Journal.h:35
ripple::test::ShardArchiveHandler_test::run
void run() override
Definition: ShardArchiveHandler_test.cpp:664
ripple::test::ShardArchiveHandler_test
Definition: ShardArchiveHandler_test.cpp:36
ripple::test::ManualTimeKeeper::now
time_point now() const override
Returns the estimate of wall time, in network time.
Definition: ManualTimeKeeper.cpp:37
ripple::test::ShardArchiveHandler_test::testSingleDownloadAndStateDB
void testSingleDownloadAndStateDB()
Definition: ShardArchiveHandler_test.cpp:57
std::unique_ptr
STL class.
ripple::getShardStore
static NodeStore::Database & getShardStore(Application &app)
Definition: ShardFamily.cpp:29
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:115
ripple::ConfigSection::nodeDatabase
static std::string nodeDatabase()
Definition: ConfigSections.h:33
beast::temp_dir
RAII temporary directory.
Definition: temp_dir.h:33
ripple::Application::getShardArchiveHandler
virtual RPC::ShardArchiveHandler * getShardArchiveHandler(bool tryRecovery=false)=0