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/basics/BasicConfig.h>
25 #include <ripple/basics/RangeSet.h>
26 #include <ripple/core/DatabaseCon.h>
27 #include <ripple/nodestore/NodeObject.h>
28 #include <ripple/nodestore/Scheduler.h>
29 
30 #include <boost/filesystem.hpp>
31 #include <nudb/nudb.hpp>
32 
33 #include <atomic>
34 #include <tuple>
35 
36 namespace ripple {
37 namespace NodeStore {
38 
41 class DatabaseShard;
42 
43 /* A range of historical ledgers backed by a node store.
44  Shards are indexed and store `ledgersPerShard`.
45  Shard `i` stores ledgers starting with sequence: `1 + (i * ledgersPerShard)`
46  and ending with sequence: `(i + 1) * ledgersPerShard`.
47  Once a shard has all its ledgers, it is never written to again.
48 
49  Public functions can be called concurrently from any thread.
50 */
51 class Shard final
52 {
53 public:
54  enum class State {
55  acquire, // Being acquired
56  complete, // Backend contains all ledgers but is not yet final
57  finalizing, // Being finalized
58  final // Database verified, shard is immutable
59  };
60 
61  static constexpr State acquire = State::acquire;
62  static constexpr State complete = State::complete;
63  static constexpr State finalizing = State::finalizing;
64  static constexpr State final = State::final;
65 
66  Shard(
67  Application& app,
68  DatabaseShard const& db,
70  boost::filesystem::path const& dir,
71  beast::Journal j);
72 
73  Shard(
74  Application& app,
75  DatabaseShard const& db,
77  beast::Journal j);
78 
79  ~Shard();
80 
86  [[nodiscard]] bool
87  init(Scheduler& scheduler, nudb::context& context);
88 
91  [[nodiscard]] bool
92  isOpen() const;
93 
98  bool
99  tryClose();
100 
103  void
105  {
106  stop_ = true;
107  }
108 
109  [[nodiscard]] boost::optional<std::uint32_t>
110  prepare();
111 
112  [[nodiscard]] bool
113  storeNodeObject(std::shared_ptr<NodeObject> const& nodeObject);
114 
115  [[nodiscard]] std::shared_ptr<NodeObject>
116  fetchNodeObject(uint256 const& hash, FetchReport& fetchReport);
117 
118  [[nodiscard]] bool
120  uint256 const& hash,
121  std::shared_ptr<NodeObject>& nodeObject);
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  void
148  sweep();
149 
150  [[nodiscard]] std::uint32_t
151  index() const
152  {
153  return index_;
154  }
155 
156  [[nodiscard]] boost::filesystem::path const&
157  getDir() const
158  {
159  return dir_;
160  }
161 
162  [[nodiscard]] int
164 
165  [[nodiscard]] float
166  getCacheHitRate();
167 
168  [[nodiscard]] std::chrono::steady_clock::time_point
169  getLastUse() const;
170 
175  getFileInfo() const;
176 
177  [[nodiscard]] State
178  getState() const
179  {
180  return state_;
181  }
182 
183  [[nodiscard]] std::int32_t
184  getWriteLoad();
185 
188  [[nodiscard]] bool
189  isLegacy() const;
190 
198  [[nodiscard]] bool
199  finalize(
200  bool const writeSQLite,
201  boost::optional<uint256> const& referenceHash);
202 
205  void
207  {
208  removeOnDestroy_ = true;
209  }
210 
211  // Current shard version
212  static constexpr std::uint32_t version{2};
213 
214  // The finalKey is a hard coded value of zero. It is used to store
215  // finalizing shard data to the backend. The data contains a version,
216  // last ledger's hash, and the first and last ledger sequences.
217  static uint256 const finalKey;
218 
219 private:
220  class Count final
221  {
222  public:
223  Count(Count const&) = delete;
224  Count&
225  operator=(Count&&) = delete;
226  Count&
227  operator=(Count const&) = delete;
228 
229  Count(Count&& other) : counter_(other.counter_)
230  {
231  other.counter_ = nullptr;
232  }
233 
235  {
236  if (counter_)
237  ++(*counter_);
238  }
239 
241  {
242  if (counter_)
243  --(*counter_);
244  }
245 
246  operator bool() const
247  {
248  return counter_ != nullptr;
249  }
250 
251  private:
253  };
254 
255  struct AcquireInfo
256  {
257  // SQLite database to track information about what has been acquired
259 
260  // Tracks the sequences of ledgers acquired and stored in the backend
262  };
263 
267 
268  // Shard Index
270 
271  // First ledger sequence in the shard
273 
274  // Last ledger sequence in the shard
276 
277  // The maximum number of ledgers the shard can store
278  // The earliest shard may store fewer ledgers than subsequent shards
280 
281  // Database positive cache
283 
284  // Database negative cache
286 
287  // Path to database files
288  boost::filesystem::path const dir_;
289 
290  // Storage space utilized by the shard
292 
293  // Number of file descriptors required by the shard
295 
296  // NuDB key/value store for node objects
298 
300 
301  // Ledger SQLite database used for indexes
303 
304  // Transaction SQLite database used for indexes
306 
307  // Tracking information used only when acquiring a shard from the network.
308  // If the shard is final, this member will be null.
310 
311  // Older shard without an acquire database or final key
312  // Eventually there will be no need for this and should be removed
313  bool legacy_{false};
314 
315  // Determines if the shard needs to stop processing for shutdown
317 
319 
320  // Determines if the shard directory should be removed in the destructor
322 
323  // The time of the last access of a shard that has a final state
324  std::chrono::steady_clock::time_point lastAccess_;
325 
326  // Open shard databases
327  [[nodiscard]] bool
328  open(std::lock_guard<std::mutex> const& lock);
329 
330  // Open/Create SQLite databases
331  // Lock over mutex_ required
332  [[nodiscard]] bool
334 
335  // Write SQLite entries for this ledger
336  // Lock over mutex_ required
337  [[nodiscard]] bool
338  storeSQLite(
339  std::shared_ptr<Ledger const> const& ledger,
341 
342  // Set storage and file descriptor usage stats
343  // Lock over mutex_ required
344  void
346 
347  // Validate this ledger by walking its SHAMaps and verifying Merkle trees
348  [[nodiscard]] bool
349  verifyLedger(
350  std::shared_ptr<Ledger const> const& ledger,
351  std::shared_ptr<Ledger const> const& next) const;
352 
353  // Fetches from backend and log errors based on status codes
354  [[nodiscard]] std::shared_ptr<NodeObject>
355  verifyFetch(uint256 const& hash) const;
356 
357  // Open databases if they are closed
358  [[nodiscard]] Shard::Count
360 };
361 
362 } // namespace NodeStore
363 } // namespace ripple
364 
365 #endif
ripple::NodeStore::Shard::dir_
const boost::filesystem::path dir_
Definition: Shard.h:288
ripple::Application
Definition: Application.h:97
ripple::NodeStore::Shard::getDesiredAsyncReadCount
int getDesiredAsyncReadCount()
Definition: Shard.cpp:550
ripple::NodeStore::Shard::mutex_
std::mutex mutex_
Definition: Shard.h:266
ripple::NodeStore::Shard::acquire
static constexpr State acquire
Definition: Shard.h:61
std::shared_ptr< NodeObject >
ripple::NodeStore::Shard::lgrSQLiteDB_
std::unique_ptr< DatabaseCon > lgrSQLiteDB_
Definition: Shard.h:302
ripple::NodeStore::Shard::removeOnDestroy_
std::atomic< bool > removeOnDestroy_
Definition: Shard.h:321
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:330
ripple::NodeStore::Shard::finalizing
static constexpr State finalizing
Definition: Shard.h:63
ripple::NodeStore::Shard::Shard
Shard(Application &app, DatabaseShard const &db, std::uint32_t index, boost::filesystem::path const &dir, beast::Journal j)
Definition: Shard.cpp:45
std::pair
ripple::NodeStore::Shard::getDir
boost::filesystem::path const & getDir() const
Definition: Shard.h:157
ripple::NodeStore::Shard::State::final
@ final
ripple::NodeStore::Shard::Count::Count
Count(std::atomic< std::uint32_t > *counter)
Definition: Shard.h:234
ripple::NodeStore::Shard::State
State
Definition: Shard.h:54
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:575
std::lock_guard
STL class.
ripple::NodeStore::Shard::Count::~Count
~Count()
Definition: Shard.h:240
tuple
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:129
ripple::NodeStore::Shard::stop
void stop()
Notify shard to prepare for shutdown.
Definition: Shard.h:104
ripple::NodeStore::Shard::finalKey
static const uint256 finalKey
Definition: Shard.h:217
ripple::NodeStore::Shard::lastSeq_
const std::uint32_t lastSeq_
Definition: Shard.h:275
ripple::NodeStore::Shard::complete
static constexpr State complete
Definition: Shard.h:62
ripple::NodeStore::Shard::AcquireInfo
Definition: Shard.h:255
ripple::NodeStore::Shard::AcquireInfo::storedSeqs
RangeSet< std::uint32_t > storedSeqs
Definition: Shard.h:261
ripple::NodeStore::Shard::State::finalizing
@ finalizing
ripple::NodeStore::Shard::verifyFetch
std::shared_ptr< NodeObject > verifyFetch(uint256 const &hash) const
Definition: Shard.cpp:1351
ripple::NodeStore::Shard::tryClose
bool tryClose()
Try to close databases if not in use.
Definition: Shard.cpp:142
ripple::NodeStore::Shard::StoreLedgerResult::size
std::uint64_t size
Definition: Shard.h:132
ripple::NodeStore::Shard::removeOnDestroy
void removeOnDestroy()
Enables removal of the shard directory on destruction.
Definition: Shard.h:206
ripple::NodeStore::Shard::backend_
std::unique_ptr< Backend > backend_
Definition: Shard.h:297
ripple::NodeStore::Shard::isLegacy
bool isLegacy() const
Returns true if shard is older, without final key data.
Definition: Shard.cpp:591
ripple::NodeStore::Shard::version
static constexpr std::uint32_t version
Definition: Shard.h:212
ripple::NodeStore::Shard::storeSQLite
bool storeSQLite(std::shared_ptr< Ledger const > const &ledger, std::lock_guard< std::mutex > const &)
Definition: Shard.cpp:1075
ripple::base_uint< 256 >
ripple::NodeStore::Shard::j_
const beast::Journal j_
Definition: Shard.h:265
ripple::NodeStore::Shard::finalize
bool finalize(bool const writeSQLite, boost::optional< uint256 > const &referenceHash)
Finalize shard by walking its ledgers and verifying each Merkle tree.
Definition: Shard.cpp:598
ripple::NodeStore::Shard::containsLedger
bool containsLedger(std::uint32_t ledgerSeq) const
Definition: Shard.cpp:513
ripple::NodeStore::Shard::fileSz_
std::uint64_t fileSz_
Definition: Shard.h:291
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::sweep
void sweep()
Definition: Shard.cpp:531
ripple::NodeStore::Shard::initSQLite
bool initSQLite(std::lock_guard< std::mutex > const &)
Definition: Shard.cpp:1001
ripple::NodeStore::Shard::fetchNodeObject
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, FetchReport &fetchReport)
Definition: Shard.cpp:247
ripple::NodeStore::Shard::state_
std::atomic< State > state_
Definition: Shard.h:318
ripple::NodeStore::Shard::pCache_
std::unique_ptr< PCache > pCache_
Definition: Shard.h:282
ripple::NodeStore::DatabaseShard
A collection of historical shards.
Definition: DatabaseShard.h:37
ripple::NodeStore::Shard::Count::Count
Count(Count &&other)
Definition: Shard.h:229
ripple::NodeStore::Shard::firstSeq_
const std::uint32_t firstSeq_
Definition: Shard.h:272
ripple::NodeStore::Shard::AcquireInfo::SQLiteDB
std::unique_ptr< DatabaseCon > SQLiteDB
Definition: Shard.h:258
ripple::NodeStore::Shard::maxLedgers_
const std::uint32_t maxLedgers_
Definition: Shard.h:279
ripple::NodeStore::Shard::~Shard
~Shard()
Definition: Shard.cpp:63
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::uint32_t
atomic
ripple::NodeStore::Scheduler
Scheduling for asynchronous backend activity.
Definition: ripple/nodestore/Scheduler.h:61
ripple::NodeStore::Shard::nCache_
std::unique_ptr< NCache > nCache_
Definition: Shard.h:285
ripple::NodeStore::Shard::StoreLedgerResult
Store a ledger.
Definition: Shard.h:129
ripple::NodeStore::Shard::getState
State getState() const
Definition: Shard.h:178
ripple::NodeStore::Shard::Count::Count
Count(Count const &)=delete
ripple::NodeStore::Shard::acquireInfo_
std::unique_ptr< AcquireInfo > acquireInfo_
Definition: Shard.h:309
ripple::NodeStore::Shard::app_
Application & app_
Definition: Shard.h:264
ripple::NodeStore::Shard::final
static constexpr State final
Definition: Shard.h:64
ripple::NodeStore::Shard::fetchNodeObjectFromCache
bool fetchNodeObjectFromCache(uint256 const &hash, std::shared_ptr< NodeObject > &nodeObject)
Definition: Shard.cpp:315
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::NodeStore::Shard::lastAccess_
std::chrono::steady_clock::time_point lastAccess_
Definition: Shard.h:324
ripple::NodeStore::Shard::makeBackendCount
Shard::Count makeBackendCount()
Definition: Shard.cpp:1389
ripple::NodeStore::Shard::State::complete
@ complete
ripple::NodeStore::Shard::StoreLedgerResult::count
std::uint64_t count
Definition: Shard.h:131
ripple::NodeStore::Shard::prepare
boost::optional< std::uint32_t > prepare()
Definition: Shard.cpp:188
ripple::NodeStore::Shard::open
bool open(std::lock_guard< std::mutex > const &lock)
Definition: Shard.cpp:851
ripple::NodeStore::Shard::Count::operator=
Count & operator=(Count &&)=delete
ripple::NodeStore::Shard::State::acquire
@ acquire
ripple::NodeStore::Shard::legacy_
bool legacy_
Definition: Shard.h:313
ripple::NodeStore::Shard::fdRequired_
std::uint32_t fdRequired_
Definition: Shard.h:294
ripple::NodeStore::Shard::index
std::uint32_t index() const
Definition: Shard.h:151
std::mutex
STL class.
ripple::NodeStore::Shard::init
bool init(Scheduler &scheduler, nudb::context &context)
Initialize shard.
Definition: Shard.cpp:98
ripple::NodeStore::Shard::verifyLedger
bool verifyLedger(std::shared_ptr< Ledger const > const &ledger, std::shared_ptr< Ledger const > const &next) const
Definition: Shard.cpp:1270
ripple::NodeStore::Shard::setFileStats
void setFileStats(std::lock_guard< std::mutex > const &)
Definition: Shard.cpp:1245
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::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:460
ripple::NodeStore::Shard
Definition: Shard.h:51
ripple::NodeStore::Shard::txSQLiteDB_
std::unique_ptr< DatabaseCon > txSQLiteDB_
Definition: Shard.h:305
ripple::NodeStore::Shard::Count
Definition: Shard.h:220
ripple::NodeStore::Shard::index_
const std::uint32_t index_
Definition: Shard.h:269
std::unique_ptr
STL class.
ripple::NodeStore::Shard::stop_
std::atomic< bool > stop_
Definition: Shard.h:316
ripple::NodeStore::Shard::Count::counter_
std::atomic< std::uint32_t > * counter_
Definition: Shard.h:252
ripple::NodeStore::Shard::backendCount_
std::atomic< std::uint32_t > backendCount_
Definition: Shard.h:299
ripple::NodeStore::Shard::getLastUse
std::chrono::steady_clock::time_point getLastUse() const
Definition: Shard.cpp:568
ripple::NodeStore::Shard::getWriteLoad
std::int32_t getWriteLoad()
Definition: Shard.cpp:582
ripple::NodeStore::Shard::getCacheHitRate
float getCacheHitRate()
Definition: Shard.cpp:559