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