rippled
ShardArchiveHandler.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012-2014 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/app/misc/NetworkOPs.h>
21 #include <ripple/basics/Archive.h>
22 #include <ripple/basics/BasicConfig.h>
23 #include <ripple/core/ConfigSections.h>
24 #include <ripple/nodestore/DatabaseShard.h>
25 #include <ripple/rpc/ShardArchiveHandler.h>
26 #include <ripple/rpc/impl/Handler.h>
27 
28 #include <memory>
29 
30 namespace ripple {
31 namespace RPC {
32 
33 using namespace boost::filesystem;
34 using namespace std::chrono_literals;
35 
36 boost::filesystem::path
38 {
39  return get(config.section(ConfigSection::shardDatabase()),
40  "download_path",
42  "path",
43  "")) /
44  "download";
45 }
46 
49  Application& app,
50  Stoppable& parent)
51 {
52  return std::make_unique<ShardArchiveHandler>(app, parent);
53 }
54 
57 {
58  auto const downloadDir(getDownloadDirectory(app.config()));
59 
60  // Create the handler iff the database
61  // is present.
62  if (exists(downloadDir / stateDBName) &&
63  is_regular_file(downloadDir / stateDBName))
64  {
65  return std::make_unique<RecoveryHandler>(app, parent);
66  }
67 
68  return nullptr;
69 }
70 
72  : Stoppable("ShardArchiveHandler", parent)
73  , process_(false)
74  , app_(app)
75  , j_(app.journal("ShardArchiveHandler"))
76  , downloadDir_(getDownloadDirectory(app.config()))
77  , timer_(app_.getIOService())
78  , verificationScheduler_(
79  std::chrono::seconds(get<std::uint32_t>(
80  app.config().section(ConfigSection::shardDatabase()),
81  "shard_verification_retry_interval")),
82 
83  get<std::uint32_t>(
84  app.config().section(ConfigSection::shardDatabase()),
85  "shard_verification_max_attempts"))
86 {
87  assert(app_.getShardStore());
88 }
89 
90 bool
92 {
93  std::lock_guard lock(m_);
94 
95  if (process_ || downloader_ != nullptr || sqliteDB_ != nullptr)
96  {
97  JLOG(j_.warn()) << "Archives already being processed";
98  return false;
99  }
100 
101  // Initialize from pre-existing database
102  if (exists(downloadDir_ / stateDBName) &&
103  is_regular_file(downloadDir_ / stateDBName))
104  {
105  downloader_ =
107 
108  return initFromDB(lock);
109  }
110 
111  // Fresh initialization
112  else
113  {
114  try
115  {
116  create_directories(downloadDir_);
117 
118  sqliteDB_ = std::make_unique<DatabaseCon>(
119  downloadDir_,
120  stateDBName,
123  }
124  catch (std::exception const& e)
125  {
126  JLOG(j_.error())
127  << "exception: " << e.what() << " in function: " << __func__;
128 
129  return false;
130  }
131  }
132 
133  return true;
134 }
135 
136 bool
138 {
139  try
140  {
141  using namespace boost::filesystem;
142 
143  assert(
144  exists(downloadDir_ / stateDBName) &&
145  is_regular_file(downloadDir_ / stateDBName));
146 
147  sqliteDB_ = std::make_unique<DatabaseCon>(
148  downloadDir_,
149  stateDBName,
152 
153  auto& session{sqliteDB_->getSession()};
154 
155  soci::rowset<soci::row> rs =
156  (session.prepare << "SELECT * FROM State;");
157 
158  for (auto it = rs.begin(); it != rs.end(); ++it)
159  {
160  parsedURL url;
161 
162  if (!parseUrl(url, it->get<std::string>(1)))
163  {
164  JLOG(j_.error())
165  << "Failed to parse url: " << it->get<std::string>(1);
166 
167  continue;
168  }
169 
170  add(it->get<int>(0), std::move(url), lock);
171  }
172 
173  // Failed to load anything
174  // from the state database.
175  if (archives_.empty())
176  {
177  release();
178  return false;
179  }
180  }
181  catch (std::exception const& e)
182  {
183  JLOG(j_.error()) << "exception: " << e.what()
184  << " in function: " << __func__;
185 
186  return false;
187  }
188 
189  return true;
190 }
191 
192 void
194 {
195  {
197 
198  if (downloader_)
199  {
200  downloader_->onStop();
201  downloader_.reset();
202  }
203 
204  timer_.cancel();
205  }
206 
208  "ShardArchiveHandler", std::chrono::milliseconds(2000), j_);
209 
211  "ShardArchiveHandler", std::chrono::milliseconds(2000), j_);
212 
213  stopped();
214 }
215 
216 bool
218  std::uint32_t shardIndex,
220 {
222 
223  if (!add(shardIndex, std::forward<parsedURL>(url.first), lock))
224  return false;
225 
226  auto& session{sqliteDB_->getSession()};
227 
228  session << "INSERT INTO State VALUES (:index, :url);",
229  soci::use(shardIndex), soci::use(url.second);
230 
231  return true;
232 }
233 
234 bool
236  std::uint32_t shardIndex,
237  parsedURL&& url,
239 {
240  if (process_)
241  {
242  JLOG(j_.error()) << "Download and import already in progress";
243  return false;
244  }
245 
246  auto const it{archives_.find(shardIndex)};
247  if (it != archives_.end())
248  return url == it->second;
249 
250  archives_.emplace(shardIndex, std::move(url));
251 
252  return true;
253 }
254 
255 bool
257 {
258  std::lock_guard lock(m_);
259  if (!app_.getShardStore())
260  {
261  JLOG(j_.error()) << "No shard store available";
262  return false;
263  }
264  if (process_)
265  {
266  JLOG(j_.warn()) << "Archives already being processed";
267  return false;
268  }
269  if (archives_.empty())
270  {
271  JLOG(j_.warn()) << "No archives to process";
272  return false;
273  }
274 
275  std::vector<std::uint32_t> shardIndexes(archives_.size());
277  archives_.begin(),
278  archives_.end(),
279  shardIndexes.begin(),
280  [](auto const& entry) { return entry.first; });
281 
282  if (!app_.getShardStore()->prepareShards(shardIndexes))
283  return false;
284 
285  try
286  {
287  // Create temp root download directory
288  create_directories(downloadDir_);
289 
290  if (!downloader_)
291  {
292  // will throw if can't initialize ssl context
293  downloader_ =
295  }
296  }
297  catch (std::exception const& e)
298  {
299  JLOG(j_.error()) << "exception: " << e.what();
300  return false;
301  }
302 
303  process_ = true;
304  return next(lock);
305 }
306 
307 void
309 {
311  doRelease(lock);
312 }
313 
314 bool
316 {
317  if (isStopping())
318  return false;
319 
320  if (archives_.empty())
321  {
322  doRelease(l);
323  return false;
324  }
325 
326  auto const shardIndex{archives_.begin()->first};
327 
328  // We use the sequence of the last validated ledger
329  // to determine whether or not we have stored a ledger
330  // that comes after the last ledger in this shard. A
331  // later ledger must be present in order to reliably
332  // retrieve the hash of the shard's last ledger.
333  boost::optional<uint256> expectedHash;
334  bool shouldHaveHash = false;
335  if (auto const seq = app_.getShardStore()->lastLedgerSeq(shardIndex);
336  (shouldHaveHash = app_.getLedgerMaster().getValidLedgerIndex() > seq))
337  {
338  expectedHash = app_.getLedgerMaster().walkHashBySeq(
340  }
341 
342  if (!expectedHash)
343  {
344  auto wrapper =
345  timerCounter_.wrap([this](boost::system::error_code const& ec) {
346  if (ec != boost::asio::error::operation_aborted)
347  {
348  std::lock_guard lock(m_);
349  this->next(lock);
350  }
351  });
352 
353  if (!wrapper)
354  return onClosureFailed(
355  "failed to wrap closure for last ledger confirmation timer", l);
356 
357  if (!verificationScheduler_.retry(app_, shouldHaveHash, *wrapper))
358  {
359  JLOG(j_.error()) << "failed to find last ledger hash for shard "
360  << shardIndex << ", maximum attempts reached";
361 
362  return removeAndProceed(l);
363  }
364 
365  return true;
366  }
367 
368  // Create a temp archive directory at the root
369  auto const dstDir{downloadDir_ / std::to_string(shardIndex)};
370  try
371  {
372  create_directory(dstDir);
373  }
374  catch (std::exception const& e)
375  {
376  JLOG(j_.error()) << "exception: " << e.what();
377  return removeAndProceed(l);
378  }
379 
380  // Download the archive. Process in another thread
381  // to prevent holding up the lock if the downloader
382  // sleeps.
383  auto const& url{archives_.begin()->second};
384  auto wrapper = jobCounter_.wrap([this, url, dstDir](Job&) {
385  auto const ssl = (url.scheme == "https");
386  auto const defaultPort = ssl ? 443 : 80;
387 
388  if (!downloader_->download(
389  url.domain,
390  std::to_string(url.port.get_value_or(defaultPort)),
391  url.path,
392  11,
393  dstDir / "archive.tar.lz4",
394  [this](path dstPath) { complete(dstPath); },
395  ssl))
396  {
398  removeAndProceed(l);
399  }
400  });
401 
402  if (!wrapper)
403  return onClosureFailed(
404  "failed to wrap closure for starting download", l);
405 
406  app_.getJobQueue().addJob(jtCLIENT, "ShardArchiveHandler", *wrapper);
407 
408  return true;
409 }
410 
411 void
413 {
414  if (isStopping())
415  return;
416 
417  {
418  std::lock_guard lock(m_);
419  try
420  {
421  if (!is_regular_file(dstPath))
422  {
423  auto ar{archives_.begin()};
424  JLOG(j_.error())
425  << "Downloading shard id " << ar->first << " from URL "
426  << ar->second.domain << ar->second.path;
427  removeAndProceed(lock);
428  return;
429  }
430  }
431  catch (std::exception const& e)
432  {
433  JLOG(j_.error()) << "exception: " << e.what();
434  removeAndProceed(lock);
435  return;
436  }
437  }
438 
439  // Make lambdas mutable captured vars can be moved from
440  auto wrapper =
441  jobCounter_.wrap([=, dstPath = std::move(dstPath)](Job&) mutable {
442  if (isStopping())
443  return;
444 
445  // If not synced then defer and retry
446  auto const mode{app_.getOPs().getOperatingMode()};
447  if (mode != OperatingMode::FULL)
448  {
449  std::lock_guard lock(m_);
450  timer_.expires_from_now(static_cast<std::chrono::seconds>(
451  (static_cast<std::size_t>(OperatingMode::FULL) -
452  static_cast<std::size_t>(mode)) *
453  10));
454 
455  auto wrapper = timerCounter_.wrap(
456  [=, dstPath = std::move(dstPath)](
457  boost::system::error_code const& ec) mutable {
458  if (ec != boost::asio::error::operation_aborted)
459  complete(std::move(dstPath));
460  });
461 
462  if (!wrapper)
464  "failed to wrap closure for operating mode timer",
465  lock);
466  else
467  timer_.async_wait(*wrapper);
468  }
469  else
470  {
471  process(dstPath);
472  std::lock_guard lock(m_);
473  removeAndProceed(lock);
474  }
475  });
476 
477  if (!wrapper)
478  {
479  if (isStopping())
480  return;
481 
482  JLOG(j_.error()) << "failed to wrap closure for process()";
483 
484  std::lock_guard lock(m_);
485  removeAndProceed(lock);
486  }
487 
488  // Process in another thread to not hold up the IO service
489  app_.getJobQueue().addJob(jtCLIENT, "ShardArchiveHandler", *wrapper);
490 }
491 
492 void
493 ShardArchiveHandler::process(path const& dstPath)
494 {
495  std::uint32_t shardIndex;
496  {
497  std::lock_guard lock(m_);
498  shardIndex = archives_.begin()->first;
499  }
500 
501  auto const shardDir{dstPath.parent_path() / std::to_string(shardIndex)};
502  try
503  {
504  // Extract the downloaded archive
505  extractTarLz4(dstPath, dstPath.parent_path());
506 
507  // The extracted root directory name must match the shard index
508  if (!is_directory(shardDir))
509  {
510  JLOG(j_.error()) << "Shard " << shardIndex
511  << " mismatches archive shard directory";
512  return;
513  }
514  }
515  catch (std::exception const& e)
516  {
517  JLOG(j_.error()) << "exception: " << e.what();
518  return;
519  }
520 
521  // Import the shard into the shard store
522  if (!app_.getShardStore()->importShard(shardIndex, shardDir))
523  {
524  JLOG(j_.error()) << "Importing shard " << shardIndex;
525  return;
526  }
527 
528  JLOG(j_.debug()) << "Shard " << shardIndex << " downloaded and imported";
529 }
530 
531 void
533 {
535 
536  auto const shardIndex{archives_.begin()->first};
537  app_.getShardStore()->removePreShard(shardIndex);
538  archives_.erase(shardIndex);
539 
540  auto& session{sqliteDB_->getSession()};
541 
542  session << "DELETE FROM State WHERE ShardIndex = :index;",
543  soci::use(shardIndex);
544 
545  auto const dstDir{downloadDir_ / std::to_string(shardIndex)};
546  try
547  {
548  remove_all(dstDir);
549  }
550  catch (std::exception const& e)
551  {
552  JLOG(j_.error()) << "exception: " << e.what();
553  }
554 }
555 
556 void
558 {
559  timer_.cancel();
560  for (auto const& ar : archives_)
561  app_.getShardStore()->removePreShard(ar.first);
562  archives_.clear();
563 
564  {
565  auto& session{sqliteDB_->getSession()};
566 
567  session << "DROP TABLE State;";
568  }
569 
570  sqliteDB_.reset();
571 
572  // Remove temp root download directory
573  try
574  {
575  remove_all(downloadDir_);
576  }
577  catch (std::exception const& e)
578  {
579  JLOG(j_.error()) << "exception: " << e.what()
580  << " in function: " << __func__;
581  }
582 
583  downloader_.reset();
584  process_ = false;
585 }
586 
587 bool
589  std::string const& errorMsg,
590  std::lock_guard<std::mutex> const& lock)
591 {
592  if (isStopping())
593  return false;
594 
595  JLOG(j_.error()) << errorMsg;
596 
597  return removeAndProceed(lock);
598 }
599 
600 bool
602 {
603  remove(lock);
604  return next(lock);
605 }
606 
608  : ShardArchiveHandler(app, parent)
609 {
610 }
611 
612 } // namespace RPC
613 } // namespace ripple
ripple::Application
Definition: Application.h:101
ripple::RPC::ShardArchiveHandler::getDownloadDirectory
static boost::filesystem::path getDownloadDirectory(Config const &config)
Definition: ShardArchiveHandler.cpp:37
ripple::RPC::ShardArchiveHandler::downloader_
std::shared_ptr< DatabaseDownloader > downloader_
Definition: ShardArchiveHandler.h:133
ripple::RPC::ShardArchiveHandler::downloadDir_
const boost::filesystem::path downloadDir_
Definition: ShardArchiveHandler.h:141
ripple::RPC::ShardArchiveHandler::remove
void remove(std::lock_guard< std::mutex > const &)
Definition: ShardArchiveHandler.cpp:532
ripple::RPC::ShardArchiveHandler::timerCounter_
TimerOpCounter timerCounter_
Definition: ShardArchiveHandler.h:144
ripple::RPC::ShardArchiveHandler::verificationScheduler_
ShardVerificationScheduler verificationScheduler_
Definition: ShardArchiveHandler.h:145
std::string
STL class.
ripple::RPC::ShardArchiveHandler::removeAndProceed
bool removeAndProceed(std::lock_guard< std::mutex > const &lock)
Definition: ShardArchiveHandler.cpp:601
ripple::RPC::ShardArchiveHandler::start
bool start()
Starts downloading and importing archives.
Definition: ShardArchiveHandler.cpp:256
ripple::jtCLIENT
@ jtCLIENT
Definition: Job.h:48
std::exception
STL class.
ripple::RPC::ShardArchiveHandler::add
bool add(std::uint32_t shardIndex, std::pair< parsedURL, std::string > &&url)
Definition: ShardArchiveHandler.cpp:217
ripple::Stoppable::stopped
void stopped()
Called by derived classes to indicate that the stoppable has stopped.
Definition: Stoppable.cpp:72
ripple::parsedURL
Definition: StringUtilities.h:100
std::pair
ripple::RPC::ShardVerificationScheduler::reset
void reset()
Definition: ShardVerificationScheduler.cpp:62
ripple::LedgerMaster::getValidLedgerIndex
LedgerIndex getValidLedgerIndex()
Definition: LedgerMaster.cpp:215
ripple::InboundLedger::Reason::GENERIC
@ GENERIC
std::vector
STL class.
ripple::ConfigSection::shardDatabase
static std::string shardDatabase()
Definition: ConfigSections.h:38
ripple::RPC::ShardArchiveHandler::onStop
void onStop() override
Override called when the stop notification is issued.
Definition: ShardArchiveHandler.cpp:193
std::chrono::milliseconds
beast::Journal::warn
Stream warn() const
Definition: Journal.h:327
ripple::NodeStore::DatabaseShard::lastLedgerSeq
virtual std::uint32_t lastLedgerSeq(std::uint32_t shardIndex) const =0
Calculates the last ledger sequence for a given shard index.
ripple::RPC::ShardArchiveHandler::doRelease
void doRelease(std::lock_guard< std::mutex > const &)
Definition: ShardArchiveHandler.cpp:557
std::lock_guard
STL class.
ripple::Application::getShardStore
virtual NodeStore::DatabaseShard * getShardStore()=0
ripple::LedgerMaster::walkHashBySeq
boost::optional< LedgerHash > walkHashBySeq(std::uint32_t index, InboundLedger::Reason reason)
Walk to a ledger's hash using the skip list.
Definition: LedgerMaster.cpp:1676
ripple::ShardArchiveHandlerDBInit
static constexpr std::array< char const *, 3 > ShardArchiveHandlerDBInit
Definition: DBInit.h:180
ripple::JobQueue::addJob
bool addJob(JobType type, std::string const &name, JobHandler &&jobHandler)
Adds a job to the JobQueue.
Definition: JobQueue.h:166
ripple::RPC::ShardArchiveHandler::initFromDB
bool initFromDB(std::lock_guard< std::mutex > const &)
Definition: ShardArchiveHandler.cpp:137
ripple::RPC::ShardArchiveHandler::onClosureFailed
bool onClosureFailed(std::string const &errorMsg, std::lock_guard< std::mutex > const &lock)
Definition: ShardArchiveHandler.cpp:588
ripple::extractTarLz4
void extractTarLz4(boost::filesystem::path const &src, boost::filesystem::path const &dst)
Extract a tar archive compressed with lz4.
Definition: Archive.cpp:29
ripple::Application::getOPs
virtual NetworkOPs & getOPs()=0
ripple::DownloaderDBPragma
static constexpr std::array< char const *, 2 > DownloaderDBPragma
Definition: DBInit.h:177
ripple::RPC::ShardArchiveHandler::timer_
boost::asio::basic_waitable_timer< std::chrono::steady_clock > timer_
Definition: ShardArchiveHandler.h:142
ripple::Stoppable
Provides an interface for starting and stopping.
Definition: Stoppable.h:201
ripple::RPC::ShardArchiveHandler::release
void release()
Definition: ShardArchiveHandler.cpp:308
ripple::RPC::ShardArchiveHandler::process
void process(boost::filesystem::path const &dstPath)
Definition: ShardArchiveHandler.cpp:493
ripple::Application::getLedgerMaster
virtual LedgerMaster & getLedgerMaster()=0
ripple::Config
Definition: Config.h:67
ripple::Application::config
virtual Config & config()=0
std::to_string
T to_string(T... args)
ripple::Application::getJobQueue
virtual JobQueue & getJobQueue()=0
ripple::parseUrl
bool parseUrl(parsedURL &pUrl, std::string const &strUrl)
Definition: StringUtilities.cpp:47
beast::Journal::error
Stream error() const
Definition: Journal.h:333
ripple::RPC::ShardArchiveHandler::sqliteDB_
std::unique_ptr< DatabaseCon > sqliteDB_
Definition: ShardArchiveHandler.h:136
ripple::Job
Definition: Job.h:82
ripple::ConfigSection
Definition: ConfigSections.h:28
ripple::RPC::ShardArchiveHandler::complete
void complete(boost::filesystem::path dstPath)
Definition: ShardArchiveHandler.cpp:412
std::uint32_t
ripple::RPC::ShardVerificationScheduler::retry
bool retry(Application &app, bool shouldHaveHash, retryFunction f)
Definition: ShardVerificationScheduler.cpp:37
ripple::ClosureCounter::wrap
boost::optional< Wrapper< Closure > > wrap(Closure &&closure)
Wrap the passed closure with a reference counter.
Definition: ClosureCounter.h:178
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.
std::transform
T transform(T... args)
ripple::RPC::ShardArchiveHandler::makeShardArchiveHandler
static std::unique_ptr< ShardArchiveHandler > makeShardArchiveHandler(Application &app, Stoppable &parent)
Definition: ShardArchiveHandler.cpp:48
ripple::RPC::ShardArchiveHandler::j_
const beast::Journal j_
Definition: ShardArchiveHandler.h:140
memory
ripple::RPC::RecoveryHandler::RecoveryHandler
RecoveryHandler(Application &app, Stoppable &parent)
Definition: ShardArchiveHandler.cpp:607
ripple::Application::getIOService
virtual boost::asio::io_service & getIOService()=0
ripple::RPC::ShardArchiveHandler::tryMakeRecoveryHandler
static std::unique_ptr< ShardArchiveHandler > tryMakeRecoveryHandler(Application &app, Stoppable &parent)
Definition: ShardArchiveHandler.cpp:56
ripple::stateDBName
static constexpr auto stateDBName
Definition: DBInit.h:174
ripple::NodeStore::DatabaseShard::importShard
virtual bool importShard(std::uint32_t shardIndex, boost::filesystem::path const &srcDir)=0
Import a shard into the shard database.
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::RPC::ShardArchiveHandler::next
bool next(std::lock_guard< std::mutex > const &l)
Definition: ShardArchiveHandler.cpp:315
ripple::RPC::ShardArchiveHandler::archives_
std::map< std::uint32_t, parsedURL > archives_
Definition: ShardArchiveHandler.h:134
std::vector::begin
T begin(T... args)
std
STL namespace.
ripple::RPC::ShardArchiveHandler::app_
Application & app_
Definition: ShardArchiveHandler.h:139
ripple::RPC::ShardArchiveHandler
Handles the download and import of one or more shard archives.
Definition: ShardArchiveHandler.h:39
ripple::RPC::ShardArchiveHandler::ShardArchiveHandler
ShardArchiveHandler()=delete
ripple::ClosureCounter::join
void join(char const *name, std::chrono::milliseconds wait, beast::Journal j)
Returns once all counted in-flight closures are destroyed.
Definition: ClosureCounter.h:152
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
std::size_t
ripple::RPC::ShardArchiveHandler::m_
std::mutex m_
Definition: ShardArchiveHandler.h:132
ripple::RPC::ShardArchiveHandler::jobCounter_
JobCounter jobCounter_
Definition: ShardArchiveHandler.h:143
ripple::NodeStore::DatabaseShard::removePreShard
virtual void removePreShard(std::uint32_t shardIndex)=0
Remove a previously prepared shard index for import.
std::unique_ptr
STL class.
ripple::RPC::ShardArchiveHandler::process_
bool process_
Definition: ShardArchiveHandler.h:135
ripple::RPC::ShardArchiveHandler::init
bool init()
Definition: ShardArchiveHandler.cpp:91
ripple::make_DatabaseDownloader
std::shared_ptr< DatabaseDownloader > make_DatabaseDownloader(boost::asio::io_service &io_service, Config const &config, beast::Journal j)
Definition: DatabaseDownloader.cpp:25
std::exception::what
T what(T... args)
ripple::get
T & get(EitherAmount &amt)
Definition: AmountSpec.h:116
ripple::BasicConfig::section
Section & section(std::string const &name)
Returns the section with the given name.
Definition: BasicConfig.cpp:138
ripple::Stoppable::isStopping
bool isStopping() const
Returns true if the stoppable should stop.
Definition: Stoppable.cpp:54
ripple::OperatingMode::FULL
@ FULL
we have the ledger and can even validate