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  // No future VLs
50  {},
51  ssl);
52  }
53 
54 public:
55  // Test the shard downloading module by queueing
56  // a download and verifying the contents of the
57  // state database.
58  void
60  {
61  testcase("testSingleDownloadAndStateDB");
62 
63  beast::temp_dir tempDir;
64 
65  auto c = jtx::envconfig();
66  auto& section = c->section(ConfigSection::shardDatabase());
67  section.set("path", tempDir.path());
68  section.set("max_historical_shards", "20");
69  c->setupControl(true, true, true);
70 
71  jtx::Env env(*this, std::move(c));
72  auto handler = env.app().getShardArchiveHandler();
73  BEAST_EXPECT(handler);
74  BEAST_EXPECT(dynamic_cast<RPC::RecoveryHandler*>(handler) == nullptr);
75 
76  std::string const rawUrl = "https://foo:443/1.tar.lz4";
77  parsedURL url;
78 
79  parseUrl(url, rawUrl);
80  handler->add(1, {url, rawUrl});
81 
82  {
83  std::lock_guard<std::mutex> lock(handler->m_);
84 
85  auto& session{handler->sqliteDB_->getSession()};
86 
87  soci::rowset<soci::row> rs =
88  (session.prepare << "SELECT * FROM State;");
89 
90  std::uint64_t rowCount = 0;
91 
92  for (auto it = rs.begin(); it != rs.end(); ++it, ++rowCount)
93  {
94  BEAST_EXPECT(it->get<int>(0) == 1);
95  BEAST_EXPECT(it->get<std::string>(1) == rawUrl);
96  }
97 
98  BEAST_EXPECT(rowCount == 1);
99  }
100 
101  handler->release();
102  }
103 
104  // Test the shard downloading module by queueing
105  // three downloads and verifying the contents of
106  // the state database.
107  void
109  {
110  testcase("testDownloadsAndStateDB");
111 
112  beast::temp_dir tempDir;
113 
114  auto c = jtx::envconfig();
115  auto& section = c->section(ConfigSection::shardDatabase());
116  section.set("path", tempDir.path());
117  section.set("max_historical_shards", "20");
118  c->setupControl(true, true, true);
119 
120  jtx::Env env(*this, std::move(c));
121  auto handler = env.app().getShardArchiveHandler();
122  BEAST_EXPECT(handler);
123  BEAST_EXPECT(dynamic_cast<RPC::RecoveryHandler*>(handler) == nullptr);
124 
125  Downloads const dl = {
126  {1, "https://foo:443/1.tar.lz4"},
127  {2, "https://foo:443/2.tar.lz4"},
128  {3, "https://foo:443/3.tar.lz4"}};
129 
130  for (auto const& entry : dl)
131  {
132  parsedURL url;
133  parseUrl(url, entry.second);
134  handler->add(entry.first, {url, entry.second});
135  }
136 
137  {
138  std::lock_guard<std::mutex> lock(handler->m_);
139 
140  auto& session{handler->sqliteDB_->getSession()};
141  soci::rowset<soci::row> rs =
142  (session.prepare << "SELECT * FROM State;");
143 
144  std::uint64_t pos = 0;
145  for (auto it = rs.begin(); it != rs.end(); ++it, ++pos)
146  {
147  BEAST_EXPECT(it->get<int>(0) == dl[pos].first);
148  BEAST_EXPECT(it->get<std::string>(1) == dl[pos].second);
149  }
150 
151  BEAST_EXPECT(pos == dl.size());
152  }
153 
154  handler->release();
155  }
156 
157  // Test the shard downloading module by initiating
158  // and completing ten downloads and verifying the
159  // contents of the filesystem and the handler's
160  // archives.
161  void
163  {
164  testcase("testDownloadsAndFileSystem");
165 
166  beast::temp_dir tempDir;
167 
168  auto c = jtx::envconfig();
169  auto& section = c->section(ConfigSection::shardDatabase());
170  section.set("path", tempDir.path());
171  section.set("max_historical_shards", "20");
172  section.set("ledgers_per_shard", "256");
173  section.set("earliest_seq", "257");
174  auto& sectionNode = c->section(ConfigSection::nodeDatabase());
175  sectionNode.set("earliest_seq", "257");
176  c->setupControl(true, true, true);
177 
178  jtx::Env env(*this, std::move(c));
179 
180  std::uint8_t const numberOfDownloads = 10;
181 
182  // Create some ledgers so that the ShardArchiveHandler
183  // can verify the last ledger hash for the shard
184  // downloads.
185  for (int i = 0; i < env.app().getShardStore()->ledgersPerShard() *
186  (numberOfDownloads + 1);
187  ++i)
188  {
189  env.close();
190  }
191 
192  auto handler = env.app().getShardArchiveHandler();
193  BEAST_EXPECT(handler);
194  BEAST_EXPECT(dynamic_cast<RPC::RecoveryHandler*>(handler) == nullptr);
195 
196  auto server = createServer(env);
197  auto host = server->local_endpoint().address().to_string();
198  auto port = std::to_string(server->local_endpoint().port());
199  server->stop();
200 
201  Downloads const dl = [count = numberOfDownloads, &host, &port] {
202  Downloads ret;
203 
204  for (int i = 1; i <= count; ++i)
205  {
206  ret.push_back(
207  {i,
208  (boost::format("https://%s:%d/%d.tar.lz4") % host % port %
209  i)
210  .str()});
211  }
212 
213  return ret;
214  }();
215 
216  for (auto const& entry : dl)
217  {
218  parsedURL url;
219  parseUrl(url, entry.second);
220  handler->add(entry.first, {url, entry.second});
221  }
222 
223  BEAST_EXPECT(handler->start());
224 
225  auto stateDir =
227 
228  std::unique_lock<std::mutex> lock(handler->m_);
229 
230  BEAST_EXPECT(
231  boost::filesystem::exists(stateDir) || handler->archives_.empty());
232 
233  using namespace std::chrono_literals;
234  auto waitMax = 60s;
235 
236  while (!handler->archives_.empty())
237  {
238  lock.unlock();
240 
241  if (waitMax -= 1s; waitMax <= 0s)
242  {
243  BEAST_EXPECT(false);
244  break;
245  }
246 
247  lock.lock();
248  }
249 
250  BEAST_EXPECT(!boost::filesystem::exists(stateDir));
251  }
252 
253  // Test the shard downloading module by initiating
254  // and completing ten downloads and verifying the
255  // contents of the filesystem and the handler's
256  // archives. Then restart the application and ensure
257  // that the handler is created and started automatically.
258  void
260  {
261  testcase("testDownloadsAndRestart");
262 
263  beast::temp_dir tempDir;
264 
265  {
266  auto c = jtx::envconfig();
267  auto& section = c->section(ConfigSection::shardDatabase());
268  section.set("path", tempDir.path());
269  section.set("max_historical_shards", "20");
270  section.set("ledgers_per_shard", "256");
271  section.set("earliest_seq", "257");
272  auto& sectionNode = c->section(ConfigSection::nodeDatabase());
273  sectionNode.set("earliest_seq", "257");
274  c->setupControl(true, true, true);
275 
276  jtx::Env env(*this, std::move(c));
277 
278  std::uint8_t const numberOfDownloads = 10;
279 
280  // Create some ledgers so that the ShardArchiveHandler
281  // can verify the last ledger hash for the shard
282  // downloads.
283  for (int i = 0; i < env.app().getShardStore()->ledgersPerShard() *
284  (numberOfDownloads + 1);
285  ++i)
286  {
287  env.close();
288  }
289 
290  auto handler = env.app().getShardArchiveHandler();
291  BEAST_EXPECT(handler);
292  BEAST_EXPECT(
293  dynamic_cast<RPC::RecoveryHandler*>(handler) == nullptr);
294 
295  auto server = createServer(env);
296  auto host = server->local_endpoint().address().to_string();
297  auto port = std::to_string(server->local_endpoint().port());
298  server->stop();
299 
300  Downloads const dl = [count = numberOfDownloads, &host, &port] {
301  Downloads ret;
302 
303  for (int i = 1; i <= count; ++i)
304  {
305  ret.push_back(
306  {i,
307  (boost::format("https://%s:%d/%d.tar.lz4") % host %
308  port % i)
309  .str()});
310  }
311 
312  return ret;
313  }();
314 
315  for (auto const& entry : dl)
316  {
317  parsedURL url;
318  parseUrl(url, entry.second);
319  handler->add(entry.first, {url, entry.second});
320  }
321 
323  env.app().config());
324 
325  boost::filesystem::copy_file(
326  stateDir / stateDBName,
327  boost::filesystem::path(tempDir.path()) / stateDBName);
328 
329  BEAST_EXPECT(handler->start());
330 
331  std::unique_lock<std::mutex> lock(handler->m_);
332 
333  BEAST_EXPECT(
334  boost::filesystem::exists(stateDir) ||
335  handler->archives_.empty());
336 
337  using namespace std::chrono_literals;
338  auto waitMax = 60s;
339 
340  while (!handler->archives_.empty())
341  {
342  lock.unlock();
344 
345  if (waitMax -= 1s; waitMax <= 0s)
346  {
347  BEAST_EXPECT(false);
348  break;
349  }
350 
351  lock.lock();
352  }
353 
354  BEAST_EXPECT(!boost::filesystem::exists(stateDir));
355 
356  boost::filesystem::create_directory(stateDir);
357 
358  boost::filesystem::copy_file(
359  boost::filesystem::path(tempDir.path()) / stateDBName,
360  stateDir / stateDBName);
361  }
362 
363  auto c = jtx::envconfig();
364  auto& section = c->section(ConfigSection::shardDatabase());
365  section.set("path", tempDir.path());
366  section.set("max_historical_shards", "20");
367  section.set("ledgers_per_shard", "256");
368  section.set("shard_verification_retry_interval", "1");
369  section.set("shard_verification_max_attempts", "10000");
370  section.set("earliest_seq", "257");
371  auto& sectionNode = c->section(ConfigSection::nodeDatabase());
372  sectionNode.set("earliest_seq", "257");
373  c->setupControl(true, true, true);
374 
375  jtx::Env env(*this, std::move(c));
376 
377  std::uint8_t const numberOfDownloads = 10;
378 
379  // Create some ledgers so that the ShardArchiveHandler
380  // can verify the last ledger hash for the shard
381  // downloads.
382  for (int i = 0; i < env.app().getShardStore()->ledgersPerShard() *
383  (numberOfDownloads + 1);
384  ++i)
385  {
386  env.close();
387  }
388 
389  auto handler = env.app().getShardArchiveHandler();
390  BEAST_EXPECT(dynamic_cast<RPC::RecoveryHandler*>(handler) != nullptr);
391 
392  auto stateDir =
394 
395  std::unique_lock<std::mutex> lock(handler->m_);
396 
397  BEAST_EXPECT(
398  boost::filesystem::exists(stateDir) || handler->archives_.empty());
399 
400  using namespace std::chrono_literals;
401  auto waitMax = 60s;
402 
403  while (!handler->archives_.empty())
404  {
405  lock.unlock();
407 
408  if (waitMax -= 1s; waitMax <= 0s)
409  {
410  BEAST_EXPECT(false);
411  break;
412  }
413 
414  lock.lock();
415  }
416 
417  BEAST_EXPECT(!boost::filesystem::exists(stateDir));
418  }
419 
420  // Ensure that downloads fail when the shard
421  // database cannot store any more shards
422  void
424  {
425  testcase("testShardCountFailure");
426  std::string capturedLogs;
427 
428  {
429  beast::temp_dir tempDir;
430 
431  auto c = jtx::envconfig();
432  auto& section = c->section(ConfigSection::shardDatabase());
433  section.set("path", tempDir.path());
434  section.set("max_historical_shards", "1");
435  section.set("ledgers_per_shard", "256");
436  section.set("earliest_seq", "257");
437  auto& sectionNode = c->section(ConfigSection::nodeDatabase());
438  sectionNode.set("earliest_seq", "257");
439  c->setupControl(true, true, true);
440 
441  std::unique_ptr<Logs> logs(new CaptureLogs(&capturedLogs));
442  jtx::Env env(*this, std::move(c), std::move(logs));
443 
444  std::uint8_t const numberOfDownloads = 10;
445 
446  // Create some ledgers so that the ShardArchiveHandler
447  // can verify the last ledger hash for the shard
448  // downloads.
449  for (int i = 0; i < env.app().getShardStore()->ledgersPerShard() *
450  (numberOfDownloads + 1);
451  ++i)
452  {
453  env.close();
454  }
455 
456  auto handler = env.app().getShardArchiveHandler();
457  BEAST_EXPECT(handler);
458  BEAST_EXPECT(
459  dynamic_cast<RPC::RecoveryHandler*>(handler) == nullptr);
460 
461  auto server = createServer(env);
462  auto host = server->local_endpoint().address().to_string();
463  auto port = std::to_string(server->local_endpoint().port());
464  server->stop();
465 
466  Downloads const dl = [count = numberOfDownloads, &host, &port] {
467  Downloads ret;
468 
469  for (int i = 1; i <= count; ++i)
470  {
471  ret.push_back(
472  {i,
473  (boost::format("https://%s:%d/%d.tar.lz4") % host %
474  port % i)
475  .str()});
476  }
477 
478  return ret;
479  }();
480 
481  for (auto const& entry : dl)
482  {
483  parsedURL url;
484  parseUrl(url, entry.second);
485  handler->add(entry.first, {url, entry.second});
486  }
487 
488  BEAST_EXPECT(!handler->start());
490  env.app().config());
491 
492  handler->release();
493  BEAST_EXPECT(!boost::filesystem::exists(stateDir));
494  }
495 
496  auto const expectedErrorMessage =
497  "shards 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 maximum number of historical "
498  "shards reached";
499  BEAST_EXPECT(
500  capturedLogs.find(expectedErrorMessage) != std::string::npos);
501 
502  {
503  beast::temp_dir tempDir;
504 
505  auto c = jtx::envconfig();
506  auto& section = c->section(ConfigSection::shardDatabase());
507  section.set("path", tempDir.path());
508  section.set("max_historical_shards", "0");
509  section.set("ledgers_per_shard", "256");
510  section.set("earliest_seq", "257");
511  auto& sectionNode = c->section(ConfigSection::nodeDatabase());
512  sectionNode.set("earliest_seq", "257");
513  c->setupControl(true, true, true);
514 
515  std::unique_ptr<Logs> logs(new CaptureLogs(&capturedLogs));
516  jtx::Env env(*this, std::move(c), std::move(logs));
517 
518  std::uint8_t const numberOfDownloads = 1;
519 
520  // Create some ledgers so that the ShardArchiveHandler
521  // can verify the last ledger hash for the shard
522  // downloads.
523  for (int i = 0; i < env.app().getShardStore()->ledgersPerShard() *
524  ((numberOfDownloads * 3) + 1);
525  ++i)
526  {
527  env.close();
528  }
529 
530  auto handler = env.app().getShardArchiveHandler();
531  BEAST_EXPECT(handler);
532  BEAST_EXPECT(
533  dynamic_cast<RPC::RecoveryHandler*>(handler) == nullptr);
534 
535  auto server = createServer(env);
536  auto host = server->local_endpoint().address().to_string();
537  auto port = std::to_string(server->local_endpoint().port());
538  server->stop();
539 
540  Downloads const dl = [count = numberOfDownloads, &host, &port] {
541  Downloads ret;
542 
543  for (int i = 1; i <= count; ++i)
544  {
545  ret.push_back(
546  {i,
547  (boost::format("https://%s:%d/%d.tar.lz4") % host %
548  port % i)
549  .str()});
550  }
551 
552  return ret;
553  }();
554 
555  for (auto const& entry : dl)
556  {
557  parsedURL url;
558  parseUrl(url, entry.second);
559  handler->add(entry.first, {url, entry.second});
560  }
561 
562  BEAST_EXPECT(!handler->start());
564  env.app().config());
565 
566  handler->release();
567  BEAST_EXPECT(!boost::filesystem::exists(stateDir));
568  }
569 
570  auto const expectedErrorMessage2 =
571  "shard 1 maximum number of historical shards reached";
572  BEAST_EXPECT(
573  capturedLogs.find(expectedErrorMessage2) != std::string::npos);
574  }
575 
576  // Ensure that downloads fail when the shard
577  // database has already stored one of the
578  // queued shards
579  void
581  {
582  testcase("testRedundantShardFailure");
583  std::string capturedLogs;
584 
585  {
586  beast::temp_dir tempDir;
587 
588  auto c = jtx::envconfig();
589  auto& section = c->section(ConfigSection::shardDatabase());
590  section.set("path", tempDir.path());
591  section.set("max_historical_shards", "1");
592  section.set("ledgers_per_shard", "256");
593  section.set("earliest_seq", "257");
594  auto& sectionNode = c->section(ConfigSection::nodeDatabase());
595  sectionNode.set("earliest_seq", "257");
596  c->setupControl(true, true, true);
597 
598  std::unique_ptr<Logs> logs(new CaptureLogs(&capturedLogs));
599  jtx::Env env(
600  *this,
601  std::move(c),
602  std::move(logs),
604 
605  std::uint8_t const numberOfDownloads = 10;
606 
607  // Create some ledgers so that the ShardArchiveHandler
608  // can verify the last ledger hash for the shard
609  // downloads.
610  for (int i = 0; i < env.app().getShardStore()->ledgersPerShard() *
611  (numberOfDownloads + 1);
612  ++i)
613  {
614  env.close();
615  }
616 
617  env.app().getShardStore()->prepareShards({1});
618 
619  auto handler = env.app().getShardArchiveHandler();
620  BEAST_EXPECT(handler);
621  BEAST_EXPECT(
622  dynamic_cast<RPC::RecoveryHandler*>(handler) == nullptr);
623 
624  auto server = createServer(env);
625  auto host = server->local_endpoint().address().to_string();
626  auto port = std::to_string(server->local_endpoint().port());
627  server->stop();
628 
629  Downloads const dl = [count = numberOfDownloads, &host, &port] {
630  Downloads ret;
631 
632  for (int i = 1; i <= count; ++i)
633  {
634  ret.push_back(
635  {i,
636  (boost::format("https://%s:%d/%d.tar.lz4") % host %
637  port % i)
638  .str()});
639  }
640 
641  return ret;
642  }();
643 
644  for (auto const& entry : dl)
645  {
646  parsedURL url;
647  parseUrl(url, entry.second);
648  handler->add(entry.first, {url, entry.second});
649  }
650 
651  BEAST_EXPECT(!handler->start());
653  env.app().config());
654 
655  handler->release();
656  BEAST_EXPECT(!boost::filesystem::exists(stateDir));
657  }
658 
659  auto const expectedErrorMessage =
660  "shard 1 is already queued for import";
661  BEAST_EXPECT(
662  capturedLogs.find(expectedErrorMessage) != std::string::npos);
663  }
664 
665  void
666  run() override
667  {
674  }
675 };
676 
677 BEAST_DEFINE_TESTSUITE(ShardArchiveHandler, app, ripple);
678 
679 } // namespace test
680 } // 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:423
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:259
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::ShardArchiveHandler_test::testDownloadsAndFileSystem
void testDownloadsAndFileSystem()
Definition: ShardArchiveHandler_test.cpp:162
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:148
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:580
ripple::test::ShardArchiveHandler_test::testDownloadsAndStateDB
void testDownloadsAndStateDB()
Definition: ShardArchiveHandler_test.cpp:108
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
ripple::test::make_TrustedPublisherServer
std::shared_ptr< TrustedPublisherServer > make_TrustedPublisherServer(boost::asio::io_context &ioc, std::vector< TrustedPublisherServer::Validator > const &validators, NetClock::time_point validUntil, std::vector< std::pair< NetClock::time_point, NetClock::time_point >> const &futures, bool useSSL=false, int version=1, bool immediateStart=true, int sequence=1)
Definition: TrustedPublisherServer.h:712
beast::severities::kDebug
@ kDebug
Definition: Journal.h:35
ripple::test::ShardArchiveHandler_test::run
void run() override
Definition: ShardArchiveHandler_test.cpp:666
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:59
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