rippled
Shard.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2017 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/ledger/InboundLedger.h>
21 #include <ripple/app/main/DBInit.h>
22 #include <ripple/app/rdb/RelationalDBInterface_global.h>
23 #include <ripple/app/rdb/RelationalDBInterface_shards.h>
24 #include <ripple/basics/StringUtilities.h>
25 #include <ripple/core/ConfigSections.h>
26 #include <ripple/nodestore/Manager.h>
27 #include <ripple/nodestore/impl/DeterministicShard.h>
28 #include <ripple/nodestore/impl/Shard.h>
29 #include <ripple/protocol/digest.h>
30 
31 #include <boost/algorithm/string.hpp>
32 #include <boost/range/adaptor/transformed.hpp>
33 
34 namespace ripple {
35 namespace NodeStore {
36 
37 uint256 const Shard::finalKey{0};
38 
40  Application& app,
41  DatabaseShard const& db,
42  std::uint32_t index,
44  : Shard(app, db, index, "", j)
45 {
46 }
47 
49  Application& app,
50  DatabaseShard const& db,
51  std::uint32_t index,
52  boost::filesystem::path const& dir,
54  : app_(app)
55  , j_(j)
56  , index_(index)
57  , firstSeq_(db.firstLedgerSeq(index))
58  , lastSeq_(std::max(firstSeq_, db.lastLedgerSeq(index)))
59  , maxLedgers_(db.maxLedgers(index))
60  , dir_((dir.empty() ? db.getRootDir() : dir) / std::to_string(index_))
61 {
62 }
63 
65 {
66  if (!removeOnDestroy_)
67  return;
68 
69  if (backend_)
70  {
71  // Abort removal if the backend is in use
72  if (backendCount_ > 0)
73  {
74  JLOG(j_.error()) << "shard " << index_
75  << " backend in use, unable to remove directory";
76  return;
77  }
78 
79  // Release database files first otherwise remove_all may fail
80  backend_.reset();
81  lgrSQLiteDB_.reset();
82  txSQLiteDB_.reset();
83  acquireInfo_.reset();
84  }
85 
86  try
87  {
88  boost::filesystem::remove_all(dir_);
89  }
90  catch (std::exception const& e)
91  {
92  JLOG(j_.fatal()) << "shard " << index_
93  << ". Exception caught in function " << __func__
94  << ". Error: " << e.what();
95  }
96 }
97 
98 bool
99 Shard::init(Scheduler& scheduler, nudb::context& context)
100 {
102  std::string const type{get(section, "type", "nudb")};
103  auto const factory{Manager::instance().find(type)};
104  if (!factory)
105  {
106  JLOG(j_.error()) << "shard " << index_ << " failed to find factory for "
107  << type;
108  return false;
109  }
110  section.set("path", dir_.string());
111 
112  std::lock_guard lock{mutex_};
113  if (backend_)
114  {
115  JLOG(j_.error()) << "shard " << index_ << " already initialized";
116  return false;
117  }
118  backend_ = factory->createInstance(
120  section,
121  megabytes(
122  app_.config().getValueFor(SizedItem::burstSize, std::nullopt)),
123  scheduler,
124  context,
125  j_);
126 
127  return open(lock);
128 }
129 
130 bool
132 {
133  std::lock_guard lock(mutex_);
134  if (!backend_)
135  {
136  JLOG(j_.error()) << "shard " << index_ << " not initialized";
137  return false;
138  }
139 
140  return backend_->isOpen();
141 }
142 
143 bool
145 {
146  // Keep database open if being acquired or finalized
148  return false;
149 
150  std::lock_guard lock(mutex_);
151 
152  // Keep database open if in use
153  if (backendCount_ > 0)
154  return false;
155 
156  if (!backend_)
157  {
158  JLOG(j_.error()) << "shard " << index_ << " not initialized";
159  return false;
160  }
161  if (!backend_->isOpen())
162  return false;
163 
164  try
165  {
166  backend_->close();
167  }
168  catch (std::exception const& e)
169  {
170  JLOG(j_.fatal()) << "shard " << index_
171  << ". Exception caught in function " << __func__
172  << ". Error: " << e.what();
173  return false;
174  }
175 
176  lgrSQLiteDB_.reset();
177  txSQLiteDB_.reset();
178  acquireInfo_.reset();
179 
180  // Reset caches to reduce memory use
183 
184  return true;
185 }
186 
189 {
191  {
192  JLOG(j_.warn()) << "shard " << index_
193  << " prepare called when not acquiring";
194  return std::nullopt;
195  }
196 
197  std::lock_guard lock(mutex_);
198  if (!acquireInfo_)
199  {
200  JLOG(j_.error()) << "shard " << index_
201  << " missing acquire SQLite database";
202  return std::nullopt;
203  }
204 
205  if (acquireInfo_->storedSeqs.empty())
206  return lastSeq_;
207  return prevMissing(acquireInfo_->storedSeqs, 1 + lastSeq_, firstSeq_);
208 }
209 
210 bool
212 {
214  {
215  // The import node store case is an exception
216  if (nodeObject->getHash() != finalKey)
217  {
218  // Ignore residual calls from InboundLedgers
219  JLOG(j_.trace()) << "shard " << index_ << " not acquiring";
220  return false;
221  }
222  }
223 
224  auto const scopedCount{makeBackendCount()};
225  if (!scopedCount)
226  return false;
227 
228  try
229  {
230  backend_->store(nodeObject);
231  }
232  catch (std::exception const& e)
233  {
234  JLOG(j_.fatal()) << "shard " << index_
235  << ". Exception caught in function " << __func__
236  << ". Error: " << e.what();
237  return false;
238  }
239 
240  return true;
241 }
242 
244 Shard::fetchNodeObject(uint256 const& hash, FetchReport& fetchReport)
245 {
246  auto const scopedCount{makeBackendCount()};
247  if (!scopedCount)
248  return nullptr;
249 
250  std::shared_ptr<NodeObject> nodeObject;
251 
252  // Try the backend
253  Status status;
254  try
255  {
256  status = backend_->fetch(hash.data(), &nodeObject);
257  }
258  catch (std::exception const& e)
259  {
260  JLOG(j_.fatal()) << "shard " << index_
261  << ". Exception caught in function " << __func__
262  << ". Error: " << e.what();
263  return nullptr;
264  }
265 
266  switch (status)
267  {
268  case ok:
269  case notFound:
270  break;
271  case dataCorrupt: {
272  JLOG(j_.fatal())
273  << "shard " << index_ << ". Corrupt node object at hash "
274  << to_string(hash);
275  break;
276  }
277  default: {
278  JLOG(j_.warn())
279  << "shard " << index_ << ". Unknown status=" << status
280  << " fetching node object at hash " << to_string(hash);
281  break;
282  }
283  }
284 
285  if (nodeObject)
286  fetchReport.wasFound = true;
287 
288  return nodeObject;
289 }
290 
293  std::shared_ptr<Ledger const> const& srcLedger,
294  std::shared_ptr<Ledger const> const& next)
295 {
296  StoreLedgerResult result;
298  {
299  // Ignore residual calls from InboundLedgers
300  JLOG(j_.trace()) << "shard " << index_ << ". Not acquiring";
301  return result;
302  }
303  if (containsLedger(srcLedger->info().seq))
304  {
305  JLOG(j_.trace()) << "shard " << index_ << ". Ledger already stored";
306  return result;
307  }
308 
309  auto fail = [&](std::string const& msg) {
310  JLOG(j_.error()) << "shard " << index_ << ". Source ledger sequence "
311  << srcLedger->info().seq << ". " << msg;
312  result.error = true;
313  return result;
314  };
315 
316  if (srcLedger->info().hash.isZero())
317  return fail("Invalid hash");
318  if (srcLedger->info().accountHash.isZero())
319  return fail("Invalid account hash");
320 
321  auto& srcDB{const_cast<Database&>(srcLedger->stateMap().family().db())};
322  if (&srcDB == &(app_.getShardFamily()->db()))
323  return fail("Source and destination databases are the same");
324 
325  auto const scopedCount{makeBackendCount()};
326  if (!scopedCount)
327  return fail("Failed to lock backend");
328 
329  Batch batch;
331  auto storeBatch = [&]() {
332  std::uint64_t sz{0};
333  for (auto const& nodeObject : batch)
334  sz += nodeObject->getData().size();
335 
336  try
337  {
338  backend_->storeBatch(batch);
339  }
340  catch (std::exception const& e)
341  {
342  fail(
343  std::string(". Exception caught in function ") + __func__ +
344  ". Error: " + e.what());
345  return false;
346  }
347 
348  result.count += batch.size();
349  result.size += sz;
350  batch.clear();
351  return true;
352  };
353 
354  // Store ledger header
355  {
356  Serializer s(sizeof(std::uint32_t) + sizeof(LedgerInfo));
358  addRaw(srcLedger->info(), s);
359  auto nodeObject = NodeObject::createObject(
360  hotLEDGER, std::move(s.modData()), srcLedger->info().hash);
361  batch.emplace_back(std::move(nodeObject));
362  }
363 
364  bool error = false;
365  auto visit = [&](SHAMapTreeNode const& node) {
366  if (!stop_)
367  {
368  if (auto nodeObject = srcDB.fetchNodeObject(
369  node.getHash().as_uint256(), srcLedger->info().seq))
370  {
371  batch.emplace_back(std::move(nodeObject));
372  if (batch.size() < batchWritePreallocationSize || storeBatch())
373  return true;
374  }
375  }
376 
377  error = true;
378  return false;
379  };
380 
381  // Store the state map
382  if (srcLedger->stateMap().getHash().isNonZero())
383  {
384  if (!srcLedger->stateMap().isValid())
385  return fail("Invalid state map");
386 
387  if (next && next->info().parentHash == srcLedger->info().hash)
388  {
389  auto have = next->stateMap().snapShot(false);
390  srcLedger->stateMap().snapShot(false)->visitDifferences(
391  &(*have), visit);
392  }
393  else
394  srcLedger->stateMap().snapShot(false)->visitNodes(visit);
395  if (error)
396  return fail("Failed to store state map");
397  }
398 
399  // Store the transaction map
400  if (srcLedger->info().txHash.isNonZero())
401  {
402  if (!srcLedger->txMap().isValid())
403  return fail("Invalid transaction map");
404 
405  srcLedger->txMap().snapShot(false)->visitNodes(visit);
406  if (error)
407  return fail("Failed to store transaction map");
408  }
409 
410  if (!batch.empty() && !storeBatch())
411  return fail("Failed to store");
412 
413  return result;
414 }
415 
416 bool
418 {
420  {
421  // Ignore residual calls from InboundLedgers
422  JLOG(j_.trace()) << "shard " << index_ << " not acquiring";
423  return false;
424  }
425 
426  auto fail = [&](std::string const& msg) {
427  JLOG(j_.error()) << "shard " << index_ << ". " << msg;
428  return false;
429  };
430 
431  auto const ledgerSeq{ledger->info().seq};
432  if (ledgerSeq < firstSeq_ || ledgerSeq > lastSeq_)
433  return fail("Invalid ledger sequence " + std::to_string(ledgerSeq));
434 
435  auto const scopedCount{makeBackendCount()};
436  if (!scopedCount)
437  return false;
438 
439  // This lock is used as an optimization to prevent unneeded
440  // calls to storeSQLite before acquireInfo_ is updated
441  std::lock_guard storedLock(storedMutex_);
442 
443  {
444  std::lock_guard lock(mutex_);
445  if (!acquireInfo_)
446  return fail("Missing acquire SQLite database");
447 
448  if (boost::icl::contains(acquireInfo_->storedSeqs, ledgerSeq))
449  {
450  // Ignore redundant calls
451  JLOG(j_.debug()) << "shard " << index_ << " ledger sequence "
452  << ledgerSeq << " already stored";
453  return true;
454  }
455  }
456 
457  if (!storeSQLite(ledger))
458  return fail("Failed to store ledger");
459 
460  std::lock_guard lock(mutex_);
461 
462  // Update the acquire database
463  acquireInfo_->storedSeqs.insert(ledgerSeq);
464 
465  try
466  {
467  auto session{acquireInfo_->SQLiteDB->checkoutDb()};
468  soci::blob sociBlob(*session);
469  convert(to_string(acquireInfo_->storedSeqs), sociBlob);
470  if (ledgerSeq == lastSeq_)
471  {
472  // Store shard's last ledger hash
473  auto const sHash{to_string(ledger->info().hash)};
474  *session << "UPDATE Shard "
475  "SET LastLedgerHash = :lastLedgerHash,"
476  "StoredLedgerSeqs = :storedLedgerSeqs "
477  "WHERE ShardIndex = :shardIndex;",
478  soci::use(sHash), soci::use(sociBlob), soci::use(index_);
479  }
480  else
481  {
482  *session << "UPDATE Shard "
483  "SET StoredLedgerSeqs = :storedLedgerSeqs "
484  "WHERE ShardIndex = :shardIndex;",
485  soci::use(sociBlob), soci::use(index_);
486  }
487  }
488  catch (std::exception const& e)
489  {
490  acquireInfo_->storedSeqs.erase(ledgerSeq);
491  return fail(
492  std::string(". Exception caught in function ") + __func__ +
493  ". Error: " + e.what());
494  }
495 
496  // Update progress
497  progress_ = boost::icl::length(acquireInfo_->storedSeqs);
498  if (progress_ == maxLedgers_)
500 
501  setFileStats(lock);
502  JLOG(j_.trace()) << "shard " << index_ << " stored ledger sequence "
503  << ledgerSeq;
504  return true;
505 }
506 
507 bool
509 {
510  if (ledgerSeq < firstSeq_ || ledgerSeq > lastSeq_)
511  return false;
513  return true;
514 
515  std::lock_guard lock(mutex_);
516  if (!acquireInfo_)
517  {
518  JLOG(j_.error()) << "shard " << index_
519  << " missing acquire SQLite database";
520  return false;
521  }
522  return boost::icl::contains(acquireInfo_->storedSeqs, ledgerSeq);
523 }
524 
525 std::chrono::steady_clock::time_point
527 {
528  std::lock_guard lock(mutex_);
529  return lastAccess_;
530 }
531 
534 {
535  std::lock_guard lock(mutex_);
536  return {fileSz_, fdRequired_};
537 }
538 
541 {
542  auto const scopedCount{makeBackendCount()};
543  if (!scopedCount)
544  return 0;
545  return backend_->getWriteLoad();
546 }
547 
548 bool
550 {
551  std::lock_guard lock(mutex_);
552  return legacy_;
553 }
554 
555 bool
556 Shard::finalize(bool writeSQLite, std::optional<uint256> const& referenceHash)
557 {
558  auto const scopedCount{makeBackendCount()};
559  if (!scopedCount)
560  return false;
561 
562  uint256 hash{0};
563  std::uint32_t ledgerSeq{0};
564  auto fail = [&](std::string const& msg) {
565  JLOG(j_.fatal()) << "shard " << index_ << ". " << msg
566  << (hash.isZero() ? ""
567  : ". Ledger hash " + to_string(hash))
568  << (ledgerSeq == 0 ? ""
569  : ". Ledger sequence " +
570  std::to_string(ledgerSeq));
572  progress_ = 0;
573  busy_ = false;
574  return false;
575  };
576 
577  try
578  {
580  progress_ = 0;
581 
582  // Check if a final key has been stored
583  if (std::shared_ptr<NodeObject> nodeObject;
584  backend_->fetch(finalKey.data(), &nodeObject) == Status::ok)
585  {
586  // Check final key's value
587  SerialIter sIt(
588  nodeObject->getData().data(), nodeObject->getData().size());
589  if (sIt.get32() != version)
590  return fail("invalid version");
591 
592  if (sIt.get32() != firstSeq_ || sIt.get32() != lastSeq_)
593  return fail("out of range ledger sequences");
594 
595  if (hash = sIt.get256(); hash.isZero())
596  return fail("invalid last ledger hash");
597  }
598  else
599  {
600  // In the absence of a final key, an acquire SQLite database
601  // must be present in order to verify the shard
602  if (!acquireInfo_)
603  return fail("missing acquire SQLite database");
604 
605  auto [res, seqshash] = selectAcquireDBLedgerSeqsHash(
606  *acquireInfo_->SQLiteDB->checkoutDb(), index_);
607 
608  if (!res)
609  return fail("missing or invalid ShardIndex");
610 
611  if (!seqshash.hash)
612  return fail("missing LastLedgerHash");
613 
614  if (!hash.parseHex(*seqshash.hash) || hash.isZero())
615  return fail("invalid LastLedgerHash");
616 
617  if (!seqshash.sequences)
618  return fail("missing StoredLedgerSeqs");
619 
620  auto& storedSeqs{acquireInfo_->storedSeqs};
621  if (!from_string(storedSeqs, *seqshash.sequences) ||
622  boost::icl::first(storedSeqs) != firstSeq_ ||
623  boost::icl::last(storedSeqs) != lastSeq_ ||
624  storedSeqs.size() != maxLedgers_)
625  {
626  return fail("invalid StoredLedgerSeqs");
627  }
628  }
629  }
630  catch (std::exception const& e)
631  {
632  return fail(
633  std::string(". Exception caught in function ") + __func__ +
634  ". Error: " + e.what());
635  }
636 
637  // Verify the last ledger hash of a downloaded shard
638  // using a ledger hash obtained from the peer network
639  if (referenceHash && *referenceHash != hash)
640  return fail("invalid last ledger hash");
641 
642  // Verify every ledger stored in the backend
643  Config const& config{app_.config()};
646  auto const lastLedgerHash{hash};
647  auto& shardFamily{*app_.getShardFamily()};
648  auto const fullBelowCache{shardFamily.getFullBelowCache(lastSeq_)};
649  auto const treeNodeCache{shardFamily.getTreeNodeCache(lastSeq_)};
650 
651  // Reset caches to reduce memory usage
652  fullBelowCache->reset();
653  treeNodeCache->reset();
654 
655  Serializer s;
656  s.add32(version);
657  s.add32(firstSeq_);
658  s.add32(lastSeq_);
659  s.addBitString(lastLedgerHash);
660 
663  if (!dShard)
664  return fail("Failed to create deterministic shard");
665 
666  // Start with the last ledger in the shard and walk backwards from
667  // child to parent until we reach the first ledger
668  ledgerSeq = lastSeq_;
669  while (ledgerSeq >= firstSeq_)
670  {
671  if (stop_)
672  return false;
673 
674  auto nodeObject{verifyFetch(hash)};
675  if (!nodeObject)
676  return fail("invalid ledger");
677 
678  ledger = std::make_shared<Ledger>(
679  deserializePrefixedHeader(makeSlice(nodeObject->getData())),
680  config,
681  shardFamily);
682  if (ledger->info().seq != ledgerSeq)
683  return fail("invalid ledger sequence");
684  if (ledger->info().hash != hash)
685  return fail("invalid ledger hash");
686 
687  ledger->stateMap().setLedgerSeq(ledgerSeq);
688  ledger->txMap().setLedgerSeq(ledgerSeq);
689  ledger->setImmutable(config);
690  if (!ledger->stateMap().fetchRoot(
691  SHAMapHash{ledger->info().accountHash}, nullptr))
692  {
693  return fail("missing root STATE node");
694  }
695  if (ledger->info().txHash.isNonZero() &&
696  !ledger->txMap().fetchRoot(
697  SHAMapHash{ledger->info().txHash}, nullptr))
698  {
699  return fail("missing root TXN node");
700  }
701 
702  if (!verifyLedger(ledger, next, dShard))
703  return fail("failed to verify ledger");
704 
705  if (!dShard->store(nodeObject))
706  return fail("failed to store node object");
707 
708  if (writeSQLite && !storeSQLite(ledger))
709  return fail("failed storing to SQLite databases");
710 
711  hash = ledger->info().parentHash;
712  next = std::move(ledger);
713 
714  // Update progress
715  progress_ = maxLedgers_ - (ledgerSeq - firstSeq_);
716 
717  --ledgerSeq;
718 
719  fullBelowCache->reset();
720  treeNodeCache->reset();
721  }
722 
723  JLOG(j_.debug()) << "shard " << index_ << " is valid";
724 
725  /*
726  TODO MP
727  SQLite VACUUM blocks all database access while processing.
728  Depending on the file size, that can take a while. Until we find
729  a non-blocking way of doing this, we cannot enable vacuum as
730  it can desync a server.
731 
732  try
733  {
734  // VACUUM the SQLite databases
735  auto const tmpDir {dir_ / "tmp_vacuum"};
736  create_directory(tmpDir);
737 
738  auto vacuum = [&tmpDir](std::unique_ptr<DatabaseCon>& sqliteDB)
739  {
740  auto session {sqliteDB->checkoutDb()};
741  *session << "PRAGMA synchronous=OFF;";
742  *session << "PRAGMA journal_mode=OFF;";
743  *session << "PRAGMA temp_store_directory='" <<
744  tmpDir.string() << "';";
745  *session << "VACUUM;";
746  };
747  vacuum(lgrSQLiteDB_);
748  vacuum(txSQLiteDB_);
749  remove_all(tmpDir);
750  }
751  catch (std::exception const& e)
752  {
753  return fail(
754  std::string(". Exception caught in function ") + __func__ +
755  ". Error: " + e.what());
756  }
757  */
758 
759  auto const nodeObject{
761  if (!dShard->store(nodeObject))
762  return fail("failed to store node object");
763 
764  try
765  {
766  // Store final key's value, may already be stored
767  backend_->store(nodeObject);
768 
769  // Do not allow all other threads work with the shard
770  busy_ = true;
771 
772  // Wait until all other threads leave the shard
773  while (backendCount_ > 1)
775 
776  std::lock_guard lock(mutex_);
777 
778  // Close original backend
779  backend_->close();
780 
781  // Close SQL databases
782  lgrSQLiteDB_.reset();
783  txSQLiteDB_.reset();
784 
785  // Remove the acquire SQLite database
786  if (acquireInfo_)
787  {
788  acquireInfo_.reset();
789  remove_all(dir_ / AcquireShardDBName);
790  }
791 
792  // Close deterministic backend
793  dShard->close();
794 
795  // Replace original backend with deterministic backend
796  remove(dir_ / "nudb.key");
797  remove(dir_ / "nudb.dat");
798  rename(dShard->getDir() / "nudb.key", dir_ / "nudb.key");
799  rename(dShard->getDir() / "nudb.dat", dir_ / "nudb.dat");
800 
801  // Re-open deterministic shard
802  if (!open(lock))
803  return fail("failed to open");
804 
805  assert(state_ == ShardState::finalized);
806 
807  // Allow all other threads work with the shard
808  busy_ = false;
809  }
810  catch (std::exception const& e)
811  {
812  return fail(
813  std::string(". Exception caught in function ") + __func__ +
814  ". Error: " + e.what());
815  }
816 
817  return true;
818 }
819 
820 bool
822 {
823  using namespace boost::filesystem;
824  Config const& config{app_.config()};
825  auto preexist{false};
826  auto fail = [this, &preexist](std::string const& msg) {
827  backend_->close();
828  lgrSQLiteDB_.reset();
829  txSQLiteDB_.reset();
830  acquireInfo_.reset();
831 
833  progress_ = 0;
834 
835  if (!preexist)
836  remove_all(dir_);
837 
838  if (!msg.empty())
839  {
840  JLOG(j_.fatal()) << "shard " << index_ << " " << msg;
841  }
842  return false;
843  };
844  auto createAcquireInfo = [this, &config]() {
845  DatabaseCon::Setup setup;
846  setup.startUp = config.standalone() ? config.LOAD : config.START_UP;
847  setup.standAlone = config.standalone();
848  setup.dataDir = dir_;
849  setup.useGlobalPragma = true;
850 
851  acquireInfo_ = std::make_unique<AcquireInfo>();
852  acquireInfo_->SQLiteDB = makeAcquireDB(
853  setup,
855 
857  progress_ = 0;
858  };
859 
860  try
861  {
862  // Open or create the NuDB key/value store
863  preexist = exists(dir_);
864  backend_->open(!preexist);
865 
866  if (!preexist)
867  {
868  // A new shard
869  createAcquireInfo();
870  insertAcquireDBIndex(acquireInfo_->SQLiteDB->getSession(), index_);
871  }
872  else if (exists(dir_ / AcquireShardDBName))
873  {
874  // A shard being acquired, backend is likely incomplete
875  createAcquireInfo();
876  auto [res, s] = selectAcquireDBLedgerSeqs(
877  acquireInfo_->SQLiteDB->getSession(), index_);
878 
879  if (!res)
880  return fail("invalid acquire SQLite database");
881 
882  if (s)
883  {
884  auto& storedSeqs{acquireInfo_->storedSeqs};
885  if (!from_string(storedSeqs, *s))
886  return fail("invalid StoredLedgerSeqs");
887 
888  if (boost::icl::first(storedSeqs) < firstSeq_ ||
889  boost::icl::last(storedSeqs) > lastSeq_)
890  {
891  return fail("invalid StoredLedgerSeqs");
892  }
893 
894  // Check if backend is complete
895  progress_ = boost::icl::length(storedSeqs);
896  if (progress_ == maxLedgers_)
898  }
899  }
900  else
901  {
902  // A shard with a finalized or complete state
903  std::shared_ptr<NodeObject> nodeObject;
904  if (backend_->fetch(finalKey.data(), &nodeObject) != Status::ok)
905  {
906  legacy_ = true;
907  return fail("incompatible, missing backend final key");
908  }
909 
910  // Check final key's value
911  SerialIter sIt(
912  nodeObject->getData().data(), nodeObject->getData().size());
913  if (sIt.get32() != version)
914  return fail("invalid version");
915 
916  if (sIt.get32() != firstSeq_ || sIt.get32() != lastSeq_)
917  return fail("out of range ledger sequences");
918 
919  if (sIt.get256().isZero())
920  return fail("invalid last ledger hash");
921 
922  if (exists(dir_ / LgrDBName) && exists(dir_ / TxDBName))
923  {
926  }
927  else
929 
931  }
932  }
933  catch (std::exception const& e)
934  {
935  return fail(
936  std::string(". Exception caught in function ") + __func__ +
937  ". Error: " + e.what());
938  }
939 
940  if (!initSQLite(lock))
941  return fail({});
942 
943  setFileStats(lock);
944  return true;
945 }
946 
947 bool
949 {
950  Config const& config{app_.config()};
951  DatabaseCon::Setup const setup = [&]() {
952  DatabaseCon::Setup setup;
953  setup.startUp = config.standalone() ? config.LOAD : config.START_UP;
954  setup.standAlone = config.standalone();
955  setup.dataDir = dir_;
957  return setup;
958  }();
959 
960  try
961  {
962  if (lgrSQLiteDB_)
963  lgrSQLiteDB_.reset();
964 
965  if (txSQLiteDB_)
966  txSQLiteDB_.reset();
967 
968  switch (state_)
969  {
972  case ShardState::finalized: {
973  auto [lgr, tx] = makeShardCompleteLedgerDBs(config, setup);
974 
975  lgrSQLiteDB_ = std::move(lgr);
976  lgrSQLiteDB_->getSession() << boost::str(
977  boost::format("PRAGMA cache_size=-%d;") %
978  kilobytes(config.getValueFor(
979  SizedItem::lgrDBCache, std::nullopt)));
980 
981  txSQLiteDB_ = std::move(tx);
982  txSQLiteDB_->getSession() << boost::str(
983  boost::format("PRAGMA cache_size=-%d;") %
984  kilobytes(config.getValueFor(
985  SizedItem::txnDBCache, std::nullopt)));
986  break;
987  }
988 
989  // case ShardState::acquire:
990  // case ShardState::queued:
991  default: {
992  // Incomplete shards use a Write Ahead Log for performance
993  auto [lgr, tx] = makeShardIncompleteLedgerDBs(
994  config,
995  setup,
997  &app_.getJobQueue(), &app_.logs()});
998 
999  lgrSQLiteDB_ = std::move(lgr);
1000  lgrSQLiteDB_->getSession() << boost::str(
1001  boost::format("PRAGMA cache_size=-%d;") %
1002  kilobytes(config.getValueFor(SizedItem::lgrDBCache)));
1003 
1004  txSQLiteDB_ = std::move(tx);
1005  txSQLiteDB_->getSession() << boost::str(
1006  boost::format("PRAGMA cache_size=-%d;") %
1007  kilobytes(config.getValueFor(SizedItem::txnDBCache)));
1008  break;
1009  }
1010  }
1011  }
1012  catch (std::exception const& e)
1013  {
1014  JLOG(j_.fatal()) << "shard " << index_
1015  << ". Exception caught in function " << __func__
1016  << ". Error: " << e.what();
1017  return false;
1018  }
1019 
1020  return true;
1021 }
1022 
1023 bool
1025 {
1026  if (stop_)
1027  return false;
1028 
1029  try
1030  {
1031  auto res = updateLedgerDBs(
1032  *txSQLiteDB_->checkoutDb(),
1033  *lgrSQLiteDB_->checkoutDb(),
1034  ledger,
1035  index_,
1036  stop_,
1037  j_);
1038 
1039  if (!res)
1040  return false;
1041 
1042  // Update the acquire database if present
1043  if (acquireInfo_)
1044  {
1046  if (!acquireInfo_->storedSeqs.empty())
1047  s = to_string(acquireInfo_->storedSeqs);
1048 
1050  acquireInfo_->SQLiteDB->getSession(),
1051  ledger,
1052  index_,
1053  lastSeq_,
1054  s);
1055  }
1056  }
1057  catch (std::exception const& e)
1058  {
1059  JLOG(j_.fatal()) << "shard " << index_
1060  << ". Exception caught in function " << __func__
1061  << ". Error: " << e.what();
1062  return false;
1063  }
1064 
1065  return true;
1066 }
1067 
1068 void
1070 {
1071  fileSz_ = 0;
1072  fdRequired_ = 0;
1073  try
1074  {
1075  using namespace boost::filesystem;
1076  for (auto const& d : directory_iterator(dir_))
1077  {
1078  if (is_regular_file(d))
1079  {
1080  fileSz_ += file_size(d);
1081  ++fdRequired_;
1082  }
1083  }
1084  }
1085  catch (std::exception const& e)
1086  {
1087  JLOG(j_.fatal()) << "shard " << index_
1088  << ". Exception caught in function " << __func__
1089  << ". Error: " << e.what();
1090  }
1091 }
1092 
1093 bool
1095  std::shared_ptr<Ledger const> const& ledger,
1096  std::shared_ptr<Ledger const> const& next,
1097  std::shared_ptr<DeterministicShard> const& dShard) const
1098 {
1099  auto fail = [j = j_, index = index_, &ledger](std::string const& msg) {
1100  JLOG(j.error()) << "shard " << index << ". " << msg
1101  << (ledger->info().hash.isZero() ? ""
1102  : ". Ledger hash " +
1103  to_string(ledger->info().hash))
1104  << (ledger->info().seq == 0 ? ""
1105  : ". Ledger sequence " +
1106  std::to_string(ledger->info().seq));
1107  return false;
1108  };
1109 
1110  if (ledger->info().hash.isZero())
1111  return fail("Invalid ledger hash");
1112  if (ledger->info().accountHash.isZero())
1113  return fail("Invalid ledger account hash");
1114 
1115  bool error{false};
1116  auto visit = [this, &error, &dShard](SHAMapTreeNode const& node) {
1117  if (stop_)
1118  return false;
1119 
1120  auto nodeObject{verifyFetch(node.getHash().as_uint256())};
1121  if (!nodeObject || !dShard->store(nodeObject))
1122  error = true;
1123 
1124  return !error;
1125  };
1126 
1127  // Verify the state map
1128  if (ledger->stateMap().getHash().isNonZero())
1129  {
1130  if (!ledger->stateMap().isValid())
1131  return fail("Invalid state map");
1132 
1133  try
1134  {
1135  if (next && next->info().parentHash == ledger->info().hash)
1136  ledger->stateMap().visitDifferences(&next->stateMap(), visit);
1137  else
1138  ledger->stateMap().visitNodes(visit);
1139  }
1140  catch (std::exception const& e)
1141  {
1142  return fail(
1143  std::string(". Exception caught in function ") + __func__ +
1144  ". Error: " + e.what());
1145  }
1146 
1147  if (stop_)
1148  return false;
1149  if (error)
1150  return fail("Invalid state map");
1151  }
1152 
1153  // Verify the transaction map
1154  if (ledger->info().txHash.isNonZero())
1155  {
1156  if (!ledger->txMap().isValid())
1157  return fail("Invalid transaction map");
1158 
1159  try
1160  {
1161  ledger->txMap().visitNodes(visit);
1162  }
1163  catch (std::exception const& e)
1164  {
1165  return fail(
1166  std::string(". Exception caught in function ") + __func__ +
1167  ". Error: " + e.what());
1168  }
1169 
1170  if (stop_)
1171  return false;
1172  if (error)
1173  return fail("Invalid transaction map");
1174  }
1175 
1176  return true;
1177 }
1178 
1180 Shard::verifyFetch(uint256 const& hash) const
1181 {
1182  std::shared_ptr<NodeObject> nodeObject;
1183  auto fail =
1184  [j = j_, index = index_, &hash, &nodeObject](std::string const& msg) {
1185  JLOG(j.error()) << "shard " << index << ". " << msg
1186  << ". Node object hash " << to_string(hash);
1187  nodeObject.reset();
1188  return nodeObject;
1189  };
1190 
1191  try
1192  {
1193  switch (backend_->fetch(hash.data(), &nodeObject))
1194  {
1195  case ok:
1196  // Verify that the hash of node object matches the payload
1197  if (nodeObject->getHash() !=
1198  sha512Half(makeSlice(nodeObject->getData())))
1199  return fail("Node object hash does not match payload");
1200  return nodeObject;
1201  case notFound:
1202  return fail("Missing node object");
1203  case dataCorrupt:
1204  return fail("Corrupt node object");
1205  default:
1206  return fail("Unknown error");
1207  }
1208  }
1209  catch (std::exception const& e)
1210  {
1211  return fail(
1212  std::string(". Exception caught in function ") + __func__ +
1213  ". Error: " + e.what());
1214  }
1215 }
1216 
1219 {
1220  if (stop_ || busy_)
1221  return Shard::Count{nullptr};
1222 
1223  std::lock_guard lock(mutex_);
1224  if (!backend_)
1225  {
1226  JLOG(j_.error()) << "shard " << index_ << " not initialized";
1227  return Shard::Count{nullptr};
1228  }
1229  if (!backend_->isOpen())
1230  {
1231  if (!open(lock))
1232  return Shard::Count{nullptr};
1233  }
1234  else if (state_ == ShardState::finalized)
1236 
1237  return Shard::Count(&backendCount_);
1238 }
1239 
1240 bool
1242  std::function<bool(soci::session& session)> const& callback,
1243  LockedSociSession&& db)
1244 {
1245  return callback(*db);
1246 }
1247 
1248 bool
1250  std::function<bool(soci::session& session, std::uint32_t shardIndex)> const&
1251  callback,
1252  LockedSociSession&& db)
1253 {
1254  return callback(*db, index_);
1255 }
1256 
1257 } // namespace NodeStore
1258 } // namespace ripple
beast::Journal::fatal
Stream fatal() const
Definition: Journal.h:339
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:42
ripple::NodeStore::Shard::dir_
const boost::filesystem::path dir_
Definition: Shard.h:316
ripple::Application
Definition: Application.h:115
ripple::AcquireShardDBName
constexpr auto AcquireShardDBName
Definition: DBInit.h:166
ripple::hotUNKNOWN
@ hotUNKNOWN
Definition: NodeObject.h:33
ripple::HashPrefix::ledgerMaster
@ ledgerMaster
ledger master data for signing
ripple::Family::getTreeNodeCache
virtual std::shared_ptr< TreeNodeCache > getTreeNodeCache(std::uint32_t ledgerSeq)=0
Return a pointer to the Family Tree Node Cache.
ripple::makeAcquireDB
std::unique_ptr< DatabaseCon > makeAcquireDB(DatabaseCon::Setup const &setup, DatabaseCon::CheckpointerSetup const &checkpointerSetup)
makeAcquireDB Opens shard acquire DB and returns its descriptor.
Definition: RelationalDBInterface_shards.cpp:338
ripple::NodeStore::Shard::mutex_
std::mutex mutex_
Definition: Shard.h:299
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:240
ripple::ShardState::complete
@ complete
ripple::NodeStore::Database
Persistency layer for NodeObject.
Definition: Database.h:51
std::string
STL class.
std::shared_ptr< NodeObject >
ripple::NodeStore::Shard::lgrSQLiteDB_
std::unique_ptr< DatabaseCon > lgrSQLiteDB_
Definition: Shard.h:330
ripple::NodeStore::Shard::removeOnDestroy_
std::atomic< bool > removeOnDestroy_
Definition: Shard.h:356
std::exception
STL class.
ripple::NodeStore::Shard::storeLedger
StoreLedgerResult storeLedger(std::shared_ptr< Ledger const > const &srcLedger, std::shared_ptr< Ledger const > const &next)
Definition: Shard.cpp:292
ripple::DatabaseCon::Setup
Definition: DatabaseCon.h:84
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::NodeStore::Shard::prepare
std::optional< std::uint32_t > prepare()
Definition: Shard.cpp:188
ripple::NodeStore::ok
@ ok
Definition: nodestore/Types.h:45
ripple::Serializer::modData
Blob & modData()
Definition: Serializer.h:178
std::pair
std::vector::reserve
T reserve(T... args)
ripple::convert
void convert(soci::blob &from, std::vector< std::uint8_t > &to)
Definition: SociDB.cpp:154
ripple::addRaw
void addRaw(LedgerInfo const &info, Serializer &s, bool includeHash)
Definition: View.cpp:164
ripple::selectAcquireDBLedgerSeqsHash
std::pair< bool, AcquireShardSeqsHash > selectAcquireDBLedgerSeqsHash(soci::session &session, std::uint32_t index)
selectAcquireDBLedgerSeqsHash Returns set of acquired ledgers and hash for given shard.
Definition: RelationalDBInterface_shards.cpp:386
ripple::insertAcquireDBIndex
void insertAcquireDBIndex(soci::session &session, std::uint32_t index)
insertAcquireDBIndex Adds new shard index to shard acquire DB.
Definition: RelationalDBInterface_shards.cpp:351
ripple::DatabaseCon::Setup::startUp
Config::StartUpType startUp
Definition: DatabaseCon.h:88
std::vector< std::shared_ptr< NodeObject > >
ripple::ConfigSection::shardDatabase
static std::string shardDatabase()
Definition: ConfigSections.h:38
ripple::NodeStore::Shard::Shard
Shard(Shard const &)=delete
Copy constructor (disallowed)
std::vector::size
T size(T... args)
ripple::NodeObject::createObject
static std::shared_ptr< NodeObject > createObject(NodeObjectType type, Blob &&data, uint256 const &hash)
Create an object from fields.
Definition: NodeObject.cpp:37
ripple::NodeStore::make_DeterministicShard
std::shared_ptr< DeterministicShard > make_DeterministicShard(Application &app, boost::filesystem::path const &shardDir, std::uint32_t shardIndex, Serializer const &finalKey, beast::Journal j)
Creates shared pointer to deterministic shard and initializes it.
Definition: DeterministicShard.cpp:151
ripple::DatabaseCon::CheckpointerSetup
Definition: DatabaseCon.h:107
beast::Journal::warn
Stream warn() const
Definition: Journal.h:327
ripple::NodeStore::Shard::getFileInfo
std::pair< std::uint64_t, std::uint32_t > getFileInfo() const
Returns a pair where the first item describes the storage space utilized and the second item is the n...
Definition: Shard.cpp:533
std::lock_guard
STL class.
ripple::kilobytes
constexpr auto kilobytes(T value) noexcept
Definition: ByteUtilities.h:27
ripple::NodeStore::FetchReport
Contains information about a fetch operation.
Definition: ripple/nodestore/Scheduler.h:32
ripple::NodeStore::Shard::isOpen
bool isOpen() const
Returns true if the database are open.
Definition: Shard.cpp:131
ripple::DatabaseCon::Setup::dataDir
boost::filesystem::path dataDir
Definition: DatabaseCon.h:91
ripple::from_string
bool from_string(RangeSet< T > &rs, std::string const &s)
Convert the given styled string to a RangeSet.
Definition: RangeSet.h:123
std::function
ripple::Family::getFullBelowCache
virtual std::shared_ptr< FullBelowCache > getFullBelowCache(std::uint32_t ledgerSeq)=0
Return a pointer to the Family Full Below Cache.
ripple::NodeStore::Shard::finalKey
static const uint256 finalKey
Definition: Shard.h:249
ripple::NodeStore::Shard::lastSeq_
const std::uint32_t lastSeq_
Definition: Shard.h:309
ripple::NodeStore::Shard::storedMutex_
std::mutex storedMutex_
Definition: Shard.h:300
ripple::deserializePrefixedHeader
LedgerInfo deserializePrefixedHeader(Slice data, bool hasHash)
Deserialize a ledger header (prefixed with 4 bytes) from a byte array.
Definition: InboundLedger.cpp:293
ripple::Family::db
virtual NodeStore::Database & db()=0
ripple::NodeStore::Shard::verifyFetch
std::shared_ptr< NodeObject > verifyFetch(uint256 const &hash) const
Definition: Shard.cpp:1180
std::shared_ptr::reset
T reset(T... args)
ripple::base_uint::data
pointer data()
Definition: base_uint.h:115
ripple::SHAMapHash
Definition: SHAMapHash.h:32
ripple::NodeStore::Shard::tryClose
bool tryClose()
Try to close databases if not in use.
Definition: Shard.cpp:144
ripple::NodeStore::Shard::StoreLedgerResult::size
std::uint64_t size
Definition: Shard.h:132
ripple::NodeStore::Shard::backend_
std::unique_ptr< Backend > backend_
Definition: Shard.h:325
ripple::NodeStore::batchWritePreallocationSize
@ batchWritePreallocationSize
Definition: nodestore/Types.h:34
ripple::NodeStore::Shard::isLegacy
bool isLegacy() const
Returns true if shard is older, without final key data.
Definition: Shard.cpp:549
ripple::uint256
base_uint< 256 > uint256
Definition: base_uint.h:529
ripple::NodeStore::Shard::version
static constexpr std::uint32_t version
Definition: Shard.h:244
ripple::NodeStore::Shard::storeSQLite
bool storeSQLite(std::shared_ptr< Ledger const > const &ledger)
Definition: Shard.cpp:1024
ripple::NodeStore::notFound
@ notFound
Definition: nodestore/Types.h:46
ripple::TxDBName
constexpr auto TxDBName
Definition: DBInit.h:73
ripple::base_uint< 256 >
ripple::updateAcquireDB
void updateAcquireDB(soci::session &session, std::shared_ptr< Ledger const > const &ledger, std::uint32_t index, std::uint32_t lastSeq, std::optional< std::string > const &seqs)
updateAcquireDB Updates information in acquire DB.
Definition: RelationalDBInterface_shards.cpp:417
ripple::DatabaseCon::Setup::useGlobalPragma
bool useGlobalPragma
Definition: DatabaseCon.h:94
ripple::NodeStore::Shard::j_
const beast::Journal j_
Definition: Shard.h:298
ripple::NodeStore::Shard::containsLedger
bool containsLedger(std::uint32_t ledgerSeq) const
Definition: Shard.cpp:508
ripple::NodeStore::Shard::fileSz_
std::uint64_t fileSz_
Definition: Shard.h:319
ripple::NodeStore::Shard::StoreLedgerResult::error
bool error
Definition: Shard.h:133
ripple::DatabaseCon::Setup::standAlone
bool standAlone
Definition: DatabaseCon.h:89
ripple::Config::getValueFor
int getValueFor(SizedItem item, std::optional< std::size_t > node=std::nullopt) const
Retrieve the default value for the item at the specified node size.
Definition: Config.cpp:990
ripple::NodeStore::Shard::storeNodeObject
bool storeNodeObject(std::shared_ptr< NodeObject > const &nodeObject)
Definition: Shard.cpp:211
ripple::base_uint::isZero
bool isZero() const
Definition: base_uint.h:511
ripple::SerialIter::get256
uint256 get256()
Definition: Serializer.h:376
ripple::Config
Definition: Config.h:68
ripple::NodeStore::Shard::initSQLite
bool initSQLite(std::lock_guard< std::mutex > const &)
Definition: Shard.cpp:948
ripple::Application::config
virtual Config & config()=0
ripple::NodeStore::Shard::fetchNodeObject
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, FetchReport &fetchReport)
Definition: Shard.cpp:244
ripple::megabytes
constexpr auto megabytes(T value) noexcept
Definition: ByteUtilities.h:34
ripple::NodeStore::DatabaseShard
A collection of historical shards.
Definition: DatabaseShard.h:37
ripple::SHAMapTreeNode
Definition: SHAMapTreeNode.h:53
std::to_string
T to_string(T... args)
ripple::Application::getJobQueue
virtual JobQueue & getJobQueue()=0
ripple::NodeStore::Shard::firstSeq_
const std::uint32_t firstSeq_
Definition: Shard.h:306
beast::Journal::error
Stream error() const
Definition: Journal.h:333
ripple::ShardState::finalized
@ finalized
ripple::Application::logs
virtual Logs & logs()=0
ripple::NodeStore::Shard::maxLedgers_
const std::uint32_t maxLedgers_
Definition: Shard.h:313
ripple::SerialIter
Definition: Serializer.h:310
ripple::SizedItem::lgrDBCache
@ lgrDBCache
ripple::NodeStore::Shard::~Shard
~Shard()
Definition: Shard.cpp:64
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::SizedItem::burstSize
@ burstSize
ripple::NodeStore::Shard::verifyLedger
bool verifyLedger(std::shared_ptr< Ledger const > const &ledger, std::shared_ptr< Ledger const > const &next, std::shared_ptr< DeterministicShard > const &dShard) const
Definition: Shard.cpp:1094
ripple::NodeStore::dataCorrupt
@ dataCorrupt
Definition: nodestore/Types.h:47
std::uint32_t
ripple::ShardState::finalizing
@ finalizing
ripple::NodeStore::Scheduler
Scheduling for asynchronous backend activity.
Definition: ripple/nodestore/Scheduler.h:60
ripple::NodeStore::Shard::StoreLedgerResult
Store a ledger.
Definition: Shard.h:129
ripple::SizedItem::txnDBCache
@ txnDBCache
ripple::prevMissing
std::optional< T > prevMissing(RangeSet< T > const &rs, T t, T minVal=0)
Find the largest value not in the set that is less than a given value.
Definition: RangeSet.h:182
ripple::NodeStore::Shard::index
std::uint32_t index() const noexcept
Definition: Shard.h:148
ripple::NodeStore::Shard::acquireInfo_
std::unique_ptr< AcquireInfo > acquireInfo_
Definition: Shard.h:337
ripple::NodeStore::Shard::app_
Application & app_
Definition: Shard.h:297
ripple::NodeStore::Status
Status
Return codes from Backend operations.
Definition: nodestore/Types.h:44
ripple::Serializer
Definition: Serializer.h:39
ripple::updateLedgerDBs
bool updateLedgerDBs(soci::session &txsession, soci::session &lgrsession, std::shared_ptr< Ledger const > const &ledger, std::uint32_t index, std::atomic< bool > &stop, beast::Journal j)
updateLedgerDBs Save given ledger to shard databases.
Definition: RelationalDBInterface_shards.cpp:201
ripple::NodeStore::Manager::find
virtual Factory * find(std::string const &name)=0
Return a pointer to the matching factory if it exists.
ripple::NodeStore::Shard::progress_
std::atomic< std::uint32_t > progress_
Definition: Shard.h:353
std::vector::emplace_back
T emplace_back(T... args)
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::LockedSociSession
Definition: DatabaseCon.h:37
ripple::NodeStore::Shard::lastAccess_
std::chrono::steady_clock::time_point lastAccess_
Definition: Shard.h:359
ripple::Serializer::addBitString
int addBitString(base_uint< Bits, Tag > const &v)
Definition: Serializer.h:97
ripple::NodeObject::keyBytes
static constexpr std::size_t keyBytes
Definition: NodeObject.h:51
ripple::NodeStore::Shard::makeBackendCount
Shard::Count makeBackendCount()
Definition: Shard.cpp:1218
ripple::ShardState::acquire
@ acquire
ripple::Application::getShardFamily
virtual Family * getShardFamily()=0
ripple::NodeStore::Shard::StoreLedgerResult::count
std::uint64_t count
Definition: Shard.h:131
ripple::NodeStore::FetchReport::wasFound
bool wasFound
Definition: ripple/nodestore/Scheduler.h:40
std
STL namespace.
ripple::sha512Half
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
Definition: digest.h:216
ripple::NodeStore::Shard::open
bool open(std::lock_guard< std::mutex > const &lock)
Definition: Shard.cpp:821
ripple::NodeStore::Shard::state_
std::atomic< ShardState > state_
Definition: Shard.h:350
ripple::NodeStore::Shard::doCallForSQL
bool doCallForSQL(std::function< bool(soci::session &session)> const &callback, LockedSociSession &&db)
Definition: Shard.cpp:1241
ripple::NodeStore::Shard::legacy_
bool legacy_
Definition: Shard.h:341
std::vector::empty
T empty(T... args)
ripple::NodeStore::Shard::fdRequired_
std::uint32_t fdRequired_
Definition: Shard.h:322
ripple::makeShardIncompleteLedgerDBs
DatabasePair makeShardIncompleteLedgerDBs(Config const &config, DatabaseCon::Setup const &setup, DatabaseCon::CheckpointerSetup const &checkpointerSetup)
makeShardIncompleteLedgerDBs Opens shard databases for not fully downloaded or verified shard and ret...
Definition: RelationalDBInterface_shards.cpp:178
std::optional< std::uint32_t >
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::NodeStore::Shard::init
bool init(Scheduler &scheduler, nudb::context &context)
Initialize shard.
Definition: Shard.cpp:99
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:38
ripple::hotLEDGER
@ hotLEDGER
Definition: NodeObject.h:34
ripple::Serializer::add32
int add32(std::uint32_t i)
Definition: Serializer.cpp:38
ripple::LedgerInfo
Information about the notional ledger backing the view.
Definition: ReadView.h:84
ripple::NodeStore::Shard::setFileStats
void setFileStats(std::lock_guard< std::mutex > const &)
Definition: Shard.cpp:1069
ripple::NodeStore::Shard::finalize
bool finalize(bool writeSQLite, std::optional< uint256 > const &referenceHash)
Finalize shard by walking its ledgers, verifying each Merkle tree and creating a deterministic backen...
Definition: Shard.cpp:556
ripple::selectAcquireDBLedgerSeqs
std::pair< bool, std::optional< std::string > > selectAcquireDBLedgerSeqs(soci::session &session, std::uint32_t index)
selectAcquireDBLedgerSeqs Returns set of acquired ledgers for given shard.
Definition: RelationalDBInterface_shards.cpp:359
ripple::NodeStore::Manager::instance
static Manager & instance()
Returns the instance of the manager singleton.
Definition: ManagerImp.cpp:120
ripple::NodeStore::Shard::setLedgerStored
bool setLedgerStored(std::shared_ptr< Ledger const > const &ledger)
Definition: Shard.cpp:417
ripple::NodeStore::Shard
Definition: Shard.h:54
ripple::SerialIter::get32
std::uint32_t get32()
Definition: Serializer.cpp:386
ripple::NodeStore::Shard::txSQLiteDB_
std::unique_ptr< DatabaseCon > txSQLiteDB_
Definition: Shard.h:333
ripple::NodeStore::Shard::Count
Definition: Shard.h:252
ripple::NodeStore::Shard::index_
const std::uint32_t index_
Definition: Shard.h:303
ripple::NodeStore::Shard::stop_
std::atomic< bool > stop_
Definition: Shard.h:344
ripple::NodeStore::Shard::backendCount_
std::atomic< std::uint32_t > backendCount_
Definition: Shard.h:327
ripple::NodeStore::Shard::getLastUse
std::chrono::steady_clock::time_point getLastUse() const
Definition: Shard.cpp:526
ripple::NodeStore::Shard::getWriteLoad
std::int32_t getWriteLoad()
Definition: Shard.cpp:540
std::this_thread::yield
T yield(T... args)
std::exception::what
T what(T... args)
ripple::get
T & get(EitherAmount &amt)
Definition: AmountSpec.h:118
ripple::makeShardCompleteLedgerDBs
DatabasePair makeShardCompleteLedgerDBs(Config const &config, DatabaseCon::Setup const &setup)
makeShardCompleteLedgerDBs Opens shard databases for already verified shard and returns its descripto...
Definition: RelationalDBInterface_shards.cpp:158
ripple::BasicConfig::section
Section & section(std::string const &name)
Returns the section with the given name.
Definition: BasicConfig.cpp:127
ripple::NodeStore::Shard::busy_
std::atomic< bool > busy_
Definition: Shard.h:347
ripple::LgrDBName
constexpr auto LgrDBName
Definition: DBInit.h:43
std::chrono::steady_clock::now
T now(T... args)