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 
125  {
126  std::uint64_t count{0}; // Number of storage calls
127  std::uint64_t size{0}; // Number of bytes stored
128  bool error{false};
129  };
130 
131  [[nodiscard]] StoreLedgerResult
132  storeLedger(
133  std::shared_ptr<Ledger const> const& srcLedger,
134  std::shared_ptr<Ledger const> const& next);
135 
136  [[nodiscard]] bool
138 
139  [[nodiscard]] bool
140  containsLedger(std::uint32_t ledgerSeq) const;
141 
142  void
143  sweep();
144 
145  [[nodiscard]] std::uint32_t
146  index() const
147  {
148  return index_;
149  }
150 
151  [[nodiscard]] boost::filesystem::path const&
152  getDir() const
153  {
154  return dir_;
155  }
156 
157  [[nodiscard]] std::chrono::steady_clock::time_point
158  getLastUse() const;
159 
164  getFileInfo() const;
165 
166  [[nodiscard]] State
167  getState() const
168  {
169  return state_;
170  }
171 
172  [[nodiscard]] std::int32_t
173  getWriteLoad();
174 
177  [[nodiscard]] bool
178  isLegacy() const;
179 
187  [[nodiscard]] bool
188  finalize(
189  bool const writeSQLite,
190  boost::optional<uint256> const& referenceHash);
191 
194  void
196  {
197  removeOnDestroy_ = true;
198  }
199 
200  // Current shard version
201  static constexpr std::uint32_t version{2};
202 
203  // The finalKey is a hard coded value of zero. It is used to store
204  // finalizing shard data to the backend. The data contains a version,
205  // last ledger's hash, and the first and last ledger sequences.
206  static uint256 const finalKey;
207 
208 private:
209  class Count final
210  {
211  public:
212  Count(Count const&) = delete;
213  Count&
214  operator=(Count&&) = delete;
215  Count&
216  operator=(Count const&) = delete;
217 
218  Count(Count&& other) : counter_(other.counter_)
219  {
220  other.counter_ = nullptr;
221  }
222 
224  {
225  if (counter_)
226  ++(*counter_);
227  }
228 
230  {
231  if (counter_)
232  --(*counter_);
233  }
234 
235  operator bool() const
236  {
237  return counter_ != nullptr;
238  }
239 
240  private:
242  };
243 
244  struct AcquireInfo
245  {
246  // SQLite database to track information about what has been acquired
248 
249  // Tracks the sequences of ledgers acquired and stored in the backend
251  };
252 
256 
257  // Shard Index
259 
260  // First ledger sequence in the shard
262 
263  // Last ledger sequence in the shard
265 
266  // The maximum number of ledgers the shard can store
267  // The earliest shard may store fewer ledgers than subsequent shards
269 
270  // Path to database files
271  boost::filesystem::path const dir_;
272 
273  // Storage space utilized by the shard
275 
276  // Number of file descriptors required by the shard
278 
279  // NuDB key/value store for node objects
281 
283 
284  // Ledger SQLite database used for indexes
286 
287  // Transaction SQLite database used for indexes
289 
290  // Tracking information used only when acquiring a shard from the network.
291  // If the shard is final, this member will be null.
293 
294  // Older shard without an acquire database or final key
295  // Eventually there will be no need for this and should be removed
296  bool legacy_{false};
297 
298  // Determines if the shard needs to stop processing for shutdown
300 
302 
303  // Determines if the shard directory should be removed in the destructor
305 
306  // The time of the last access of a shard that has a final state
307  std::chrono::steady_clock::time_point lastAccess_;
308 
309  // Open shard databases
310  [[nodiscard]] bool
311  open(std::lock_guard<std::mutex> const& lock);
312 
313  // Open/Create SQLite databases
314  // Lock over mutex_ required
315  [[nodiscard]] bool
317 
318  // Write SQLite entries for this ledger
319  // Lock over mutex_ required
320  [[nodiscard]] bool
321  storeSQLite(
322  std::shared_ptr<Ledger const> const& ledger,
324 
325  // Set storage and file descriptor usage stats
326  // Lock over mutex_ required
327  void
329 
330  // Validate this ledger by walking its SHAMaps and verifying Merkle trees
331  [[nodiscard]] bool
332  verifyLedger(
333  std::shared_ptr<Ledger const> const& ledger,
334  std::shared_ptr<Ledger const> const& next) const;
335 
336  // Fetches from backend and log errors based on status codes
337  [[nodiscard]] std::shared_ptr<NodeObject>
338  verifyFetch(uint256 const& hash) const;
339 
340  // Open databases if they are closed
341  [[nodiscard]] Shard::Count
343 };
344 
345 } // namespace NodeStore
346 } // namespace ripple
347 
348 #endif
ripple::NodeStore::Shard::dir_
const boost::filesystem::path dir_
Definition: Shard.h:271
ripple::Application
Definition: Application.h:97
ripple::NodeStore::Shard::mutex_
std::mutex mutex_
Definition: Shard.h:255
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:285
ripple::NodeStore::Shard::removeOnDestroy_
std::atomic< bool > removeOnDestroy_
Definition: Shard.h:304
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:290
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:152
ripple::NodeStore::Shard::State::final
@ final
ripple::NodeStore::Shard::Count::Count
Count(std::atomic< std::uint32_t > *counter)
Definition: Shard.h:223
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:499
std::lock_guard
STL class.
ripple::NodeStore::Shard::Count::~Count
~Count()
Definition: Shard.h:229
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:206
ripple::NodeStore::Shard::lastSeq_
const std::uint32_t lastSeq_
Definition: Shard.h:264
ripple::NodeStore::Shard::complete
static constexpr State complete
Definition: Shard.h:62
ripple::NodeStore::Shard::AcquireInfo
Definition: Shard.h:244
ripple::NodeStore::Shard::AcquireInfo::storedSeqs
RangeSet< std::uint32_t > storedSeqs
Definition: Shard.h:250
ripple::NodeStore::Shard::State::finalizing
@ finalizing
ripple::NodeStore::Shard::verifyFetch
std::shared_ptr< NodeObject > verifyFetch(uint256 const &hash) const
Definition: Shard.cpp:1260
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:127
ripple::NodeStore::Shard::removeOnDestroy
void removeOnDestroy()
Enables removal of the shard directory on destruction.
Definition: Shard.h:195
ripple::NodeStore::Shard::backend_
std::unique_ptr< Backend > backend_
Definition: Shard.h:280
ripple::NodeStore::Shard::isLegacy
bool isLegacy() const
Returns true if shard is older, without final key data.
Definition: Shard.cpp:515
ripple::NodeStore::Shard::version
static constexpr std::uint32_t version
Definition: Shard.h:201
ripple::NodeStore::Shard::storeSQLite
bool storeSQLite(std::shared_ptr< Ledger const > const &ledger, std::lock_guard< std::mutex > const &)
Definition: Shard.cpp:984
ripple::base_uint< 256 >
ripple::NodeStore::Shard::j_
const beast::Journal j_
Definition: Shard.h:254
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:522
ripple::NodeStore::Shard::containsLedger
bool containsLedger(std::uint32_t ledgerSeq) const
Definition: Shard.cpp:468
ripple::NodeStore::Shard::fileSz_
std::uint64_t fileSz_
Definition: Shard.h:274
ripple::NodeStore::Shard::StoreLedgerResult::error
bool error
Definition: Shard.h:128
ripple::NodeStore::Shard::storeNodeObject
bool storeNodeObject(std::shared_ptr< NodeObject > const &nodeObject)
Definition: Shard.cpp:209
ripple::NodeStore::Shard::sweep
void sweep()
Definition: Shard.cpp:486
ripple::NodeStore::Shard::initSQLite
bool initSQLite(std::lock_guard< std::mutex > const &)
Definition: Shard.cpp:910
ripple::NodeStore::Shard::fetchNodeObject
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, FetchReport &fetchReport)
Definition: Shard.cpp:242
ripple::NodeStore::Shard::state_
std::atomic< State > state_
Definition: Shard.h:301
ripple::NodeStore::DatabaseShard
A collection of historical shards.
Definition: DatabaseShard.h:37
ripple::NodeStore::Shard::Count::Count
Count(Count &&other)
Definition: Shard.h:218
ripple::NodeStore::Shard::firstSeq_
const std::uint32_t firstSeq_
Definition: Shard.h:261
ripple::NodeStore::Shard::AcquireInfo::SQLiteDB
std::unique_ptr< DatabaseCon > SQLiteDB
Definition: Shard.h:247
ripple::NodeStore::Shard::maxLedgers_
const std::uint32_t maxLedgers_
Definition: Shard.h:268
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:60
ripple::NodeStore::Shard::StoreLedgerResult
Store a ledger.
Definition: Shard.h:124
ripple::NodeStore::Shard::getState
State getState() const
Definition: Shard.h:167
ripple::NodeStore::Shard::Count::Count
Count(Count const &)=delete
ripple::NodeStore::Shard::acquireInfo_
std::unique_ptr< AcquireInfo > acquireInfo_
Definition: Shard.h:292
ripple::NodeStore::Shard::app_
Application & app_
Definition: Shard.h:253
ripple::NodeStore::Shard::final
static constexpr State final
Definition: Shard.h:64
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:307
ripple::NodeStore::Shard::makeBackendCount
Shard::Count makeBackendCount()
Definition: Shard.cpp:1298
ripple::NodeStore::Shard::State::complete
@ complete
ripple::NodeStore::Shard::StoreLedgerResult::count
std::uint64_t count
Definition: Shard.h:126
ripple::NodeStore::Shard::prepare
boost::optional< std::uint32_t > prepare()
Definition: Shard.cpp:186
ripple::NodeStore::Shard::open
bool open(std::lock_guard< std::mutex > const &lock)
Definition: Shard.cpp:771
ripple::NodeStore::Shard::Count::operator=
Count & operator=(Count &&)=delete
ripple::NodeStore::Shard::State::acquire
@ acquire
ripple::NodeStore::Shard::legacy_
bool legacy_
Definition: Shard.h:296
ripple::NodeStore::Shard::fdRequired_
std::uint32_t fdRequired_
Definition: Shard.h:277
ripple::NodeStore::Shard::index
std::uint32_t index() const
Definition: Shard.h:146
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:1179
ripple::NodeStore::Shard::setFileStats
void setFileStats(std::lock_guard< std::mutex > const &)
Definition: Shard.cpp:1154
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:415
ripple::NodeStore::Shard
Definition: Shard.h:51
ripple::NodeStore::Shard::txSQLiteDB_
std::unique_ptr< DatabaseCon > txSQLiteDB_
Definition: Shard.h:288
ripple::NodeStore::Shard::Count
Definition: Shard.h:209
ripple::NodeStore::Shard::index_
const std::uint32_t index_
Definition: Shard.h:258
std::unique_ptr
STL class.
ripple::NodeStore::Shard::stop_
std::atomic< bool > stop_
Definition: Shard.h:299
ripple::NodeStore::Shard::Count::counter_
std::atomic< std::uint32_t > * counter_
Definition: Shard.h:241
ripple::NodeStore::Shard::backendCount_
std::atomic< std::uint32_t > backendCount_
Definition: Shard.h:282
ripple::NodeStore::Shard::getLastUse
std::chrono::steady_clock::time_point getLastUse() const
Definition: Shard.cpp:492
ripple::NodeStore::Shard::getWriteLoad
std::int32_t getWriteLoad()
Definition: Shard.cpp:506