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 
35 namespace ripple {
36 namespace NodeStore {
37 
40 class DatabaseShard;
41 
42 /* A range of historical ledgers backed by a node store.
43  Shards are indexed and store `ledgersPerShard`.
44  Shard `i` stores ledgers starting with sequence: `1 + (i * ledgersPerShard)`
45  and ending with sequence: `(i + 1) * ledgersPerShard`.
46  Once a shard has all its ledgers, it is never written to again.
47 
48  Public functions can be called concurrently from any thread.
49 */
50 class Shard final
51 {
52 public:
53  enum class State {
54  acquire, // Being acquired
55  complete, // Backend contains all ledgers but is not yet final
56  finalizing, // Being finalized
57  final // Database verified, shard is immutable
58  };
59 
60  static constexpr State acquire = State::acquire;
61  static constexpr State complete = State::complete;
62  static constexpr State finalizing = State::finalizing;
63  static constexpr State final = State::final;
64 
65  Shard(
66  Application& app,
67  DatabaseShard const& db,
69  boost::filesystem::path const& dir,
70  beast::Journal j);
71 
72  Shard(
73  Application& app,
74  DatabaseShard const& db,
76  beast::Journal j);
77 
78  ~Shard();
79 
85  [[nodiscard]] bool
86  init(Scheduler& scheduler, nudb::context& context);
87 
90  [[nodiscard]] bool
91  isOpen() const;
92 
97  bool
98  tryClose();
99 
102  void
104  {
105  stop_ = true;
106  }
107 
108  [[nodiscard]] boost::optional<std::uint32_t>
109  prepare();
110 
111  [[nodiscard]] bool
112  storeNodeObject(std::shared_ptr<NodeObject> const& nodeObject);
113 
114  [[nodiscard]] std::shared_ptr<NodeObject>
115  fetchNodeObject(uint256 const& hash, FetchReport& fetchReport);
116 
124  {
125  std::uint64_t count{0}; // Number of storage calls
126  std::uint64_t size{0}; // Number of bytes stored
127  bool error{false};
128  };
129 
130  [[nodiscard]] StoreLedgerResult
131  storeLedger(
132  std::shared_ptr<Ledger const> const& srcLedger,
133  std::shared_ptr<Ledger const> const& next);
134 
135  [[nodiscard]] bool
137 
138  [[nodiscard]] bool
139  containsLedger(std::uint32_t ledgerSeq) const;
140 
141  void
142  sweep();
143 
144  [[nodiscard]] std::uint32_t
145  index() const
146  {
147  return index_;
148  }
149 
150  [[nodiscard]] boost::filesystem::path const&
151  getDir() const
152  {
153  return dir_;
154  }
155 
156  [[nodiscard]] std::chrono::steady_clock::time_point
157  getLastUse() const;
158 
163  getFileInfo() const;
164 
165  [[nodiscard]] State
166  getState() const
167  {
168  return state_;
169  }
170 
171  [[nodiscard]] std::int32_t
172  getWriteLoad();
173 
176  [[nodiscard]] bool
177  isLegacy() const;
178 
186  [[nodiscard]] bool
187  finalize(
188  bool const writeSQLite,
189  boost::optional<uint256> const& referenceHash);
190 
193  void
195  {
196  removeOnDestroy_ = true;
197  }
198 
199  // Current shard version
200  static constexpr std::uint32_t version{2};
201 
202  // The finalKey is a hard coded value of zero. It is used to store
203  // finalizing shard data to the backend. The data contains a version,
204  // last ledger's hash, and the first and last ledger sequences.
205  static uint256 const finalKey;
206 
207 private:
208  class Count final
209  {
210  public:
211  Count(Count const&) = delete;
212  Count&
213  operator=(Count&&) = delete;
214  Count&
215  operator=(Count const&) = delete;
216 
217  Count(Count&& other) : counter_(other.counter_)
218  {
219  other.counter_ = nullptr;
220  }
221 
223  {
224  if (counter_)
225  ++(*counter_);
226  }
227 
229  {
230  if (counter_)
231  --(*counter_);
232  }
233 
234  operator bool() const
235  {
236  return counter_ != nullptr;
237  }
238 
239  private:
241  };
242 
243  struct AcquireInfo
244  {
245  // SQLite database to track information about what has been acquired
247 
248  // Tracks the sequences of ledgers acquired and stored in the backend
250  };
251 
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  [[nodiscard]] bool
321 
322  // Set storage and file descriptor usage stats
323  // Lock over mutex_ required
324  void
326 
327  // Validate this ledger by walking its SHAMaps and verifying Merkle trees
328  [[nodiscard]] bool
329  verifyLedger(
330  std::shared_ptr<Ledger const> const& ledger,
331  std::shared_ptr<Ledger const> const& next) const;
332 
333  // Fetches from backend and log errors based on status codes
334  [[nodiscard]] std::shared_ptr<NodeObject>
335  verifyFetch(uint256 const& hash) const;
336 
337  // Open databases if they are closed
338  [[nodiscard]] Shard::Count
340 };
341 
342 } // namespace NodeStore
343 } // namespace ripple
344 
345 #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:254
ripple::NodeStore::Shard::acquire
static constexpr State acquire
Definition: Shard.h:60
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:62
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:151
ripple::NodeStore::Shard::State::final
@ final
ripple::NodeStore::Shard::Count::Count
Count(std::atomic< std::uint32_t > *counter)
Definition: Shard.h:222
ripple::NodeStore::Shard::State
State
Definition: Shard.h:53
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:538
std::lock_guard
STL class.
ripple::NodeStore::Shard::Count::~Count
~Count()
Definition: Shard.h:228
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:103
ripple::NodeStore::Shard::finalKey
static const uint256 finalKey
Definition: Shard.h:205
ripple::NodeStore::Shard::lastSeq_
const std::uint32_t lastSeq_
Definition: Shard.h:264
ripple::NodeStore::Shard::storedMutex_
std::mutex storedMutex_
Definition: Shard.h:255
ripple::NodeStore::Shard::complete
static constexpr State complete
Definition: Shard.h:61
ripple::NodeStore::Shard::AcquireInfo
Definition: Shard.h:243
ripple::NodeStore::Shard::AcquireInfo::storedSeqs
RangeSet< std::uint32_t > storedSeqs
Definition: Shard.h:249
ripple::NodeStore::Shard::State::finalizing
@ finalizing
ripple::NodeStore::Shard::verifyFetch
std::shared_ptr< NodeObject > verifyFetch(uint256 const &hash) const
Definition: Shard.cpp:1266
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:126
ripple::NodeStore::Shard::removeOnDestroy
void removeOnDestroy()
Enables removal of the shard directory on destruction.
Definition: Shard.h:194
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:554
ripple::NodeStore::Shard::version
static constexpr std::uint32_t version
Definition: Shard.h:200
ripple::NodeStore::Shard::storeSQLite
bool storeSQLite(std::shared_ptr< Ledger const > const &ledger)
Definition: Shard.cpp:1020
ripple::base_uint< 256 >
ripple::NodeStore::Shard::j_
const beast::Journal j_
Definition: Shard.h:253
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:561
ripple::NodeStore::Shard::containsLedger
bool containsLedger(std::uint32_t ledgerSeq) const
Definition: Shard.cpp:507
ripple::NodeStore::Shard::fileSz_
std::uint64_t fileSz_
Definition: Shard.h:274
ripple::NodeStore::Shard::StoreLedgerResult::error
bool error
Definition: Shard.h:127
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:525
ripple::NodeStore::Shard::initSQLite
bool initSQLite(std::lock_guard< std::mutex > const &)
Definition: Shard.cpp:946
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:217
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:246
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:123
ripple::NodeStore::Shard::getState
State getState() const
Definition: Shard.h:166
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:252
ripple::NodeStore::Shard::final
static constexpr State final
Definition: Shard.h:63
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:1304
ripple::NodeStore::Shard::State::complete
@ complete
ripple::NodeStore::Shard::StoreLedgerResult::count
std::uint64_t count
Definition: Shard.h:125
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:807
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:145
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:1185
ripple::NodeStore::Shard::setFileStats
void setFileStats(std::lock_guard< std::mutex > const &)
Definition: Shard.cpp:1160
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:50
ripple::NodeStore::Shard::txSQLiteDB_
std::unique_ptr< DatabaseCon > txSQLiteDB_
Definition: Shard.h:288
ripple::NodeStore::Shard::Count
Definition: Shard.h:208
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:240
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:531
ripple::NodeStore::Shard::getWriteLoad
std::int32_t getWriteLoad()
Definition: Shard.cpp:545