rippled
Shard.h
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 #ifndef RIPPLE_NODESTORE_SHARD_H_INCLUDED
21 #define RIPPLE_NODESTORE_SHARD_H_INCLUDED
22 
23 #include <ripple/app/ledger/Ledger.h>
24 #include <ripple/app/rdb/RelationalDBInterface.h>
25 #include <ripple/basics/BasicConfig.h>
26 #include <ripple/basics/KeyCache.h>
27 #include <ripple/basics/MathUtilities.h>
28 #include <ripple/basics/RangeSet.h>
29 #include <ripple/core/DatabaseCon.h>
30 #include <ripple/nodestore/NodeObject.h>
31 #include <ripple/nodestore/Scheduler.h>
32 #include <ripple/nodestore/impl/DeterministicShard.h>
33 
34 #include <boost/filesystem.hpp>
35 #include <nudb/nudb.hpp>
36 
37 #include <atomic>
38 
39 namespace ripple {
40 namespace NodeStore {
41 
43 using NCache = KeyCache;
44 class DatabaseShard;
45 
46 /* A range of historical ledgers backed by a node store.
47  Shards are indexed and store `ledgersPerShard`.
48  Shard `i` stores ledgers starting with sequence: `1 + (i * ledgersPerShard)`
49  and ending with sequence: `(i + 1) * ledgersPerShard`.
50  Once a shard has all its ledgers, it is never written to again.
51 
52  Public functions can be called concurrently from any thread.
53 */
54 class Shard final
55 {
56 public:
58  Shard(Shard const&) = delete;
59 
61  Shard(Shard&&) = delete;
62 
63  // Copy assignment (disallowed)
64  Shard&
65  operator=(Shard const&) = delete;
66 
67  // Move assignment (disallowed)
68  Shard&
69  operator=(Shard&&) = delete;
70 
71  Shard(
72  Application& app,
73  DatabaseShard const& db,
75  boost::filesystem::path const& dir,
76  beast::Journal j);
77 
78  Shard(
79  Application& app,
80  DatabaseShard const& db,
82  beast::Journal j);
83 
84  ~Shard();
85 
91  [[nodiscard]] bool
92  init(Scheduler& scheduler, nudb::context& context);
93 
96  [[nodiscard]] bool
97  isOpen() const;
98 
103  bool
104  tryClose();
105 
108  void
109  stop() noexcept
110  {
111  stop_ = true;
112  }
113 
114  [[nodiscard]] std::optional<std::uint32_t>
115  prepare();
116 
117  [[nodiscard]] bool
118  storeNodeObject(std::shared_ptr<NodeObject> const& nodeObject);
119 
120  [[nodiscard]] std::shared_ptr<NodeObject>
121  fetchNodeObject(uint256 const& hash, FetchReport& fetchReport);
122 
130  {
131  std::uint64_t count{0}; // Number of storage calls
132  std::uint64_t size{0}; // Number of bytes stored
133  bool error{false};
134  };
135 
136  [[nodiscard]] StoreLedgerResult
137  storeLedger(
138  std::shared_ptr<Ledger const> const& srcLedger,
139  std::shared_ptr<Ledger const> const& next);
140 
141  [[nodiscard]] bool
143 
144  [[nodiscard]] bool
145  containsLedger(std::uint32_t ledgerSeq) const;
146 
147  [[nodiscard]] std::uint32_t
148  index() const noexcept
149  {
150  return index_;
151  }
152 
153  [[nodiscard]] boost::filesystem::path const&
154  getDir() const noexcept
155  {
156  return dir_;
157  }
158 
159  [[nodiscard]] std::chrono::steady_clock::time_point
160  getLastUse() const;
161 
166  getFileInfo() const;
167 
168  [[nodiscard]] ShardState
169  getState() const noexcept
170  {
171  return state_;
172  }
173 
177  [[nodiscard]] std::uint32_t
178  getPercentProgress() const noexcept
179  {
181  }
182 
183  [[nodiscard]] std::int32_t
184  getWriteLoad();
185 
188  [[nodiscard]] bool
189  isLegacy() const;
190 
199  [[nodiscard]] bool
200  finalize(bool writeSQLite, std::optional<uint256> const& referenceHash);
201 
204  void
205  removeOnDestroy() noexcept
206  {
207  removeOnDestroy_ = true;
208  }
209 
212  {
213  if (!acquireInfo_)
214  return "";
215 
216  return to_string(acquireInfo_->storedSeqs);
217  }
218 
224  template <typename... Args>
225  bool
226  callForLedgerSQL(std::function<bool(Args... args)> const& callback)
227  {
228  return callForSQL(callback, lgrSQLiteDB_->checkoutDb());
229  }
230 
236  template <typename... Args>
237  bool
238  callForTransactionSQL(std::function<bool(Args... args)> const& callback)
239  {
240  return callForSQL(callback, txSQLiteDB_->checkoutDb());
241  }
242 
243  // Current shard version
244  static constexpr std::uint32_t version{2};
245 
246  // The finalKey is a hard coded value of zero. It is used to store
247  // finalizing shard data to the backend. The data contains a version,
248  // last ledger's hash, and the first and last ledger sequences.
249  static uint256 const finalKey;
250 
251 private:
252  class Count final
253  {
254  public:
255  Count(Count const&) = delete;
256  Count&
257  operator=(Count const&) = delete;
258  Count&
259  operator=(Count&&) = delete;
260 
261  Count(Count&& other) noexcept : counter_(other.counter_)
262  {
263  other.counter_ = nullptr;
264  }
265 
266  explicit Count(std::atomic<std::uint32_t>* counter) noexcept
267  : counter_(counter)
268  {
269  if (counter_)
270  ++(*counter_);
271  }
272 
273  ~Count() noexcept
274  {
275  if (counter_)
276  --(*counter_);
277  }
278 
279  explicit operator bool() const noexcept
280  {
281  return counter_ != nullptr;
282  }
283 
284  private:
286  };
287 
288  struct AcquireInfo
289  {
290  // SQLite database to track information about what has been acquired
292 
293  // Tracks the sequences of ledgers acquired and stored in the backend
295  };
296 
301 
302  // Shard Index
304 
305  // First ledger sequence in the shard
307 
308  // Last ledger sequence in the shard
310 
311  // The maximum number of ledgers the shard can store
312  // The earliest shard may store fewer ledgers than subsequent shards
314 
315  // Path to database files
316  boost::filesystem::path const dir_;
317 
318  // Storage space utilized by the shard
320 
321  // Number of file descriptors required by the shard
323 
324  // NuDB key/value store for node objects
326 
328 
329  // Ledger SQLite database used for indexes
331 
332  // Transaction SQLite database used for indexes
334 
335  // Tracking information used only when acquiring a shard from the network.
336  // If the shard is finalized, this member will be null.
338 
339  // Older shard without an acquire database or final key
340  // Eventually there will be no need for this and should be removed
341  bool legacy_{false};
342 
343  // Determines if the shard needs to stop processing for shutdown
345 
346  // Determines if the shard busy with replacing by deterministic one
348 
349  // State of the shard
351 
352  // Number of ledgers processed for the current shard state
354 
355  // Determines if the shard directory should be removed in the destructor
357 
358  // The time of the last access of a shard with a finalized state
359  std::chrono::steady_clock::time_point lastAccess_;
360 
361  // Open shard databases
362  [[nodiscard]] bool
363  open(std::lock_guard<std::mutex> const& lock);
364 
365  // Open/Create SQLite databases
366  // Lock over mutex_ required
367  [[nodiscard]] bool
369 
370  // Write SQLite entries for this ledger
371  [[nodiscard]] bool
373 
374  // Set storage and file descriptor usage stats
375  // Lock over mutex_ required
376  void
378 
379  // Verify this ledger by walking its SHAMaps and verifying its Merkle trees
380  // Every node object verified will be stored in the deterministic shard
381  [[nodiscard]] bool
382  verifyLedger(
383  std::shared_ptr<Ledger const> const& ledger,
384  std::shared_ptr<Ledger const> const& next,
385  std::shared_ptr<DeterministicShard> const& dShard) const;
386 
387  // Fetches from backend and log errors based on status codes
388  [[nodiscard]] std::shared_ptr<NodeObject>
389  verifyFetch(uint256 const& hash) const;
390 
391  // Open databases if they are closed
392  [[nodiscard]] Shard::Count
394 
395  // Invoke a callback on the supplied session parameter
396  template <typename... Args>
397  bool
399  std::function<bool(Args... args)> const& callback,
400  LockedSociSession&& db)
401  {
402  auto const scopedCount{makeBackendCount()};
403  if (!scopedCount)
404  return false;
405 
406  return doCallForSQL(callback, std::move(db));
407  }
408 
409  // Invoke a callback that accepts a SQLite session parameter
410  bool
411  doCallForSQL(
412  std::function<bool(soci::session& session)> const& callback,
413  LockedSociSession&& db);
414 
415  // Invoke a callback that accepts a SQLite session and the
416  // shard index as parameters
417  bool
418  doCallForSQL(
420  bool(soci::session& session, std::uint32_t shardIndex)> const&
421  callback,
422  LockedSociSession&& db);
423 };
424 
425 } // namespace NodeStore
426 } // namespace ripple
427 
428 #endif
ripple::NodeStore::Shard::dir_
const boost::filesystem::path dir_
Definition: Shard.h:316
ripple::Application
Definition: Application.h:115
ripple::NodeStore::Shard::mutex_
std::mutex mutex_
Definition: Shard.h:299
ripple::NodeStore::Shard::getPercentProgress
std::uint32_t getPercentProgress() const noexcept
Returns a percent signifying how complete the current state of the shard is.
Definition: Shard.h:178
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
ripple::NodeStore::Shard::removeOnDestroy
void removeOnDestroy() noexcept
Enables removal of the shard directory on destruction.
Definition: Shard.h:205
ripple::TaggedCache
Map/cache combination.
Definition: Application.h:63
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::NodeStore::Shard::prepare
std::optional< std::uint32_t > prepare()
Definition: Shard.cpp:188
std::pair
ripple::NodeStore::Shard::Count::~Count
~Count() noexcept
Definition: Shard.h:273
ripple::NodeStore::Shard::callForLedgerSQL
bool callForLedgerSQL(std::function< bool(Args... args)> const &callback)
Invoke a callback on the ledger SQLite db.
Definition: Shard.h:226
ripple::NodeStore::Shard::Shard
Shard(Shard const &)=delete
Copy constructor (disallowed)
ripple::NodeStore::Shard::Count::Count
Count(std::atomic< std::uint32_t > *counter) noexcept
Definition: Shard.h:266
ripple::NodeStore::Shard::getStoredSeqs
std::string getStoredSeqs()
Definition: Shard.h:211
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::NodeStore::Shard::Count::Count
Count(Count &&other) noexcept
Definition: Shard.h:261
ripple::NodeStore::Shard::operator=
Shard & operator=(Shard const &)=delete
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
std::function
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::ShardState
ShardState
Shard states.
Definition: nodestore/Types.h:60
ripple::NodeStore::Shard::storedMutex_
std::mutex storedMutex_
Definition: Shard.h:300
ripple::NodeStore::Shard::AcquireInfo
Definition: Shard.h:288
ripple::NodeStore::Shard::AcquireInfo::storedSeqs
RangeSet< std::uint32_t > storedSeqs
Definition: Shard.h:294
ripple::NodeStore::Shard::verifyFetch
std::shared_ptr< NodeObject > verifyFetch(uint256 const &hash) const
Definition: Shard.cpp:1180
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::Shard::isLegacy
bool isLegacy() const
Returns true if shard is older, without final key data.
Definition: Shard.cpp:549
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::KeyCache
TaggedCache< uint256, int, true > KeyCache
Definition: KeyCache.h:28
ripple::base_uint< 256 >
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::NodeStore::Shard::storeNodeObject
bool storeNodeObject(std::shared_ptr< NodeObject > const &nodeObject)
Definition: Shard.cpp:211
ripple::NodeStore::Shard::stop
void stop() noexcept
Notify shard to prepare for shutdown.
Definition: Shard.h:109
ripple::NodeStore::Shard::initSQLite
bool initSQLite(std::lock_guard< std::mutex > const &)
Definition: Shard.cpp:948
ripple::NodeStore::Shard::fetchNodeObject
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, FetchReport &fetchReport)
Definition: Shard.cpp:244
ripple::NodeStore::DatabaseShard
A collection of historical shards.
Definition: DatabaseShard.h:37
ripple::calculatePercent
constexpr std::size_t calculatePercent(std::size_t count, std::size_t total)
Calculate one number divided by another number in percentage.
Definition: MathUtilities.h:44
ripple::NodeStore::Shard::firstSeq_
const std::uint32_t firstSeq_
Definition: Shard.h:306
ripple::NodeStore::Shard::AcquireInfo::SQLiteDB
std::unique_ptr< DatabaseCon > SQLiteDB
Definition: Shard.h:291
ripple::NodeStore::Shard::maxLedgers_
const std::uint32_t maxLedgers_
Definition: Shard.h:313
ripple::NodeStore::Shard::~Shard
~Shard()
Definition: Shard.cpp:64
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
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
std::uint32_t
atomic
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::NodeStore::Shard::Count::Count
Count(Count const &)=delete
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::Shard::callForSQL
bool callForSQL(std::function< bool(Args... args)> const &callback, LockedSociSession &&db)
Definition: Shard.h:398
ripple::NodeStore::Shard::progress_
std::atomic< std::uint32_t > progress_
Definition: Shard.h:353
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::NodeStore::Shard::makeBackendCount
Shard::Count makeBackendCount()
Definition: Shard.cpp:1218
ripple::NodeStore::Shard::callForTransactionSQL
bool callForTransactionSQL(std::function< bool(Args... args)> const &callback)
Invoke a callback on the transaction SQLite db.
Definition: Shard.h:238
ripple::ShardState::acquire
@ acquire
ripple::NodeStore::Shard::StoreLedgerResult::count
std::uint64_t count
Definition: Shard.h:131
ripple::NodeStore::Shard::getDir
boost::filesystem::path const & getDir() const noexcept
Definition: Shard.h:154
ripple::NodeStore::Shard::Count::operator=
Count & operator=(Count const &)=delete
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
ripple::NodeStore::Shard::fdRequired_
std::uint32_t fdRequired_
Definition: Shard.h:322
std::optional< std::uint32_t >
std::mutex
STL class.
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::NodeStore::Shard::setFileStats
void setFileStats(std::lock_guard< std::mutex > const &)
Definition: Shard.cpp:1069
ripple::RangeSet
boost::icl::interval_set< T, std::less, ClosedInterval< T > > RangeSet
A set of closed intervals over the domain T.
Definition: RangeSet.h:69
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::NodeStore::Shard::setLedgerStored
bool setLedgerStored(std::shared_ptr< Ledger const > const &ledger)
Definition: Shard.cpp:417
ripple::NodeStore::Shard::getState
ShardState getState() const noexcept
Definition: Shard.h:169
ripple::NodeStore::Shard
Definition: Shard.h:54
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
std::unique_ptr
STL class.
ripple::NodeStore::Shard::stop_
std::atomic< bool > stop_
Definition: Shard.h:344
ripple::NodeStore::Shard::Count::counter_
std::atomic< std::uint32_t > * counter_
Definition: Shard.h:285
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
ripple::NodeStore::Shard::busy_
std::atomic< bool > busy_
Definition: Shard.h:347