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 #include <ripple/nodestore/impl/DeterministicShard.h>
30 
31 #include <boost/filesystem.hpp>
32 #include <nudb/nudb.hpp>
33 
34 #include <atomic>
35 #include <tuple>
36 
37 namespace ripple {
38 namespace NodeStore {
39 
42 class DatabaseShard;
43 
44 /* A range of historical ledgers backed by a node store.
45  Shards are indexed and store `ledgersPerShard`.
46  Shard `i` stores ledgers starting with sequence: `1 + (i * ledgersPerShard)`
47  and ending with sequence: `(i + 1) * ledgersPerShard`.
48  Once a shard has all its ledgers, it is never written to again.
49 
50  Public functions can be called concurrently from any thread.
51 */
52 class Shard final
53 {
54 public:
55  Shard(
56  Application& app,
57  DatabaseShard const& db,
59  beast::Journal j);
60 
61  ~Shard();
62 
63  bool
64  open(Scheduler& scheduler, nudb::context& ctx);
65 
66  boost::optional<std::uint32_t>
67  prepare();
68 
69  bool
70  store(std::shared_ptr<Ledger const> const& ledger);
71 
72  bool
73  containsLedger(std::uint32_t seq) const;
74 
75  void
76  sweep();
77 
79  index() const
80  {
81  return index_;
82  }
83 
84  boost::filesystem::path const&
85  getDir() const
86  {
87  return dir_;
88  }
89 
90  std::tuple<
94  getBackendAll() const;
95 
97  getBackend() const;
98 
101  bool
102  isBackendComplete() const;
103 
105  pCache() const;
106 
108  nCache() const;
109 
114  fileInfo() const;
115 
118  bool
119  isFinal() const;
120 
123  bool
124  isLegacy() const;
125 
135  bool
136  finalize(
137  bool const writeSQLite,
138  boost::optional<uint256> const& referenceHash,
139  const bool writeDeterministicShard = true);
140 
141  void
143  {
144  stop_ = true;
145  }
146 
150  void
152  {
153  removeOnDestroy_ = true;
154  }
155 
156  // Current shard version
157  static constexpr std::uint32_t version{2};
158 
159  // The finalKey is a hard coded value of zero. It is used to store
160  // finalizing shard data to the backend. The data contains a version,
161  // last ledger's hash, and the first and last ledger sequences.
162  static uint256 const finalKey;
163 
164 private:
165  struct AcquireInfo
166  {
167  // SQLite database to track information about what has been acquired
169 
170  // Tracks the sequences of ledgers acquired and stored in the backend
172  };
173 
176 
178 
179  // Shard Index
181 
182  // First ledger sequence in the shard
184 
185  // Last ledger sequence in the shard
187 
188  // The maximum number of ledgers the shard can store
189  // The earliest shard may store fewer ledgers than subsequent shards
191 
192  // Database positive cache
194 
195  // Database negative cache
197 
198  // Path to database files
199  boost::filesystem::path const dir_;
200 
201  // Storage space utilized by the shard
203 
204  // Number of file descriptors required by the shard
206 
207  // NuDB key/value store for node objects
209 
210  // Ledger SQLite database used for indexes
212 
213  // Transaction SQLite database used for indexes
215 
216  // Tracking information used only when acquiring a shard from the network.
217  // If the shard is final, this member will be null.
219 
221 
222  // True if backend has stored all ledgers pertaining to the shard
223  bool backendComplete_{false};
224 
225  // Older shard without an acquire database or final key
226  // Eventually there will be no need for this and should be removed
227  bool legacy_{false};
228 
229  // True if the backend has a final key stored
230  bool final_{false};
231 
232  // Determines if the shard needs to stop processing for shutdown
234 
235  // Determines if the shard directory should be removed in the destructor
237 
238  // Set the backend cache
239  // Lock over mutex_ required
240  void
242 
243  // Open/Create SQLite databases
244  // Lock over mutex_ required
245  bool
247 
248  // Write SQLite entries for this ledger
249  // Lock over mutex_ required
250  bool
251  storeSQLite(
252  std::shared_ptr<Ledger const> const& ledger,
254 
255  // Set storage and file descriptor usage stats
256  // Lock over mutex_ required
257  void
259 
260  // Validate this ledger by walking its SHAMaps and verifying Merkle trees
261  // If dsh != NULL then save all walking SHAMaps to deterministic shard dsh
262  bool
263  verifyLedger(
264  std::shared_ptr<Ledger const> const& ledger,
265  std::shared_ptr<Ledger const> const& next,
266  std::shared_ptr<DeterministicShard> dsh = {}) const;
267 
268  // Fetches from backend and log errors based on status codes
270  valFetch(uint256 const& hash) const;
271 };
272 
273 } // namespace NodeStore
274 } // namespace ripple
275 
276 #endif
ripple::NodeStore::Shard::getBackend
std::shared_ptr< Backend > getBackend() const
Definition: Shard.cpp:340
ripple::NodeStore::Shard::dir_
const boost::filesystem::path dir_
Definition: Shard.h:199
ripple::Application
Definition: Application.h:97
std::shared_ptr
STL class.
ripple::NodeStore::Shard::lgrSQLiteDB_
std::unique_ptr< DatabaseCon > lgrSQLiteDB_
Definition: Shard.h:211
ripple::NodeStore::Shard::removeOnDestroy_
std::atomic< bool > removeOnDestroy_
Definition: Shard.h:236
ripple::TaggedCache
Map/cache combination.
Definition: TaggedCache.h:52
ripple::NodeStore::Shard::setBackendCache
void setBackendCache(std::lock_guard< std::recursive_mutex > const &lock)
Definition: Shard.cpp:670
std::pair
ripple::NodeStore::Shard::store
bool store(std::shared_ptr< Ledger const > const &ledger)
Definition: Shard.cpp:253
ripple::NodeStore::Shard::backendComplete_
bool backendComplete_
Definition: Shard.h:223
ripple::NodeStore::Shard::getDir
boost::filesystem::path const & getDir() const
Definition: Shard.h:85
ripple::NodeStore::Shard::final_
bool final_
Definition: Shard.h:230
ripple::NodeStore::Shard::initSQLite
bool initSQLite(std::lock_guard< std::recursive_mutex > const &lock)
Definition: Shard.cpp:704
std::recursive_mutex
STL class.
std::lock_guard
STL class.
tuple
ripple::NodeStore::Shard::stop
void stop()
Definition: Shard.h:142
ripple::NodeStore::Shard::finalKey
static const uint256 finalKey
Definition: Shard.h:162
ripple::NodeStore::Shard::lastSeq_
const std::uint32_t lastSeq_
Definition: Shard.h:186
ripple::NodeStore::Shard::AcquireInfo
Definition: Shard.h:165
ripple::NodeStore::Shard::AcquireInfo::storedSeqs
RangeSet< std::uint32_t > storedSeqs
Definition: Shard.h:171
ripple::NodeStore::Shard::finalize
bool finalize(bool const writeSQLite, boost::optional< uint256 > const &referenceHash, const bool writeDeterministicShard=true)
Finalize shard by walking its ledgers and verifying each Merkle tree.
Definition: Shard.cpp:395
ripple::NodeStore::Shard::removeOnDestroy
void removeOnDestroy()
If called, the shard directory will be removed when the shard is destroyed.
Definition: Shard.h:151
ripple::NodeStore::Shard::isLegacy
bool isLegacy() const
Returns true if the shard is older, without final key data.
Definition: Shard.cpp:388
ripple::NodeStore::Shard::version
static constexpr std::uint32_t version
Definition: Shard.h:157
ripple::base_uint< 256 >
ripple::NodeStore::Shard::pCache
std::shared_ptr< PCache > pCache() const
Definition: Shard.cpp:356
ripple::NodeStore::Shard::j_
const beast::Journal j_
Definition: Shard.h:220
ripple::NodeStore::Shard::fileSz_
std::uint64_t fileSz_
Definition: Shard.h:202
ripple::NodeStore::Shard::valFetch
std::shared_ptr< NodeObject > valFetch(uint256 const &hash) const
Definition: Shard.cpp:1044
ripple::NodeStore::Shard::db_
DatabaseShard const & db_
Definition: Shard.h:177
ripple::NodeStore::Shard::sweep
void sweep()
Definition: Shard.cpp:318
ripple::NodeStore::DatabaseShard
A collection of historical shards.
Definition: DatabaseShard.h:37
ripple::NodeStore::Shard::nCache_
std::shared_ptr< NCache > nCache_
Definition: Shard.h:196
ripple::NodeStore::Shard::backend_
std::shared_ptr< Backend > backend_
Definition: Shard.h:208
ripple::NodeStore::Shard::firstSeq_
const std::uint32_t firstSeq_
Definition: Shard.h:183
ripple::NodeStore::Shard::pCache_
std::shared_ptr< PCache > pCache_
Definition: Shard.h:193
ripple::NodeStore::Shard::isFinal
bool isFinal() const
Returns true if the shard is complete, validated, and immutable.
Definition: Shard.cpp:381
ripple::NodeStore::Shard::AcquireInfo::SQLiteDB
std::unique_ptr< DatabaseCon > SQLiteDB
Definition: Shard.h:168
ripple::NodeStore::Shard::maxLedgers_
const std::uint32_t maxLedgers_
Definition: Shard.h:190
ripple::NodeStore::Shard::~Shard
~Shard()
Definition: Shard.cpp:57
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:57
ripple::NodeStore::Shard::acquireInfo_
std::unique_ptr< AcquireInfo > acquireInfo_
Definition: Shard.h:218
ripple::NodeStore::Shard::app_
Application & app_
Definition: Shard.h:174
ripple::NodeStore::Shard::isBackendComplete
bool isBackendComplete() const
Returns true if all shard ledgers have been stored in the backend.
Definition: Shard.cpp:349
ripple::NodeStore::Shard::mutex_
std::recursive_mutex mutex_
Definition: Shard.h:175
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::NodeStore::Shard::verifyLedger
bool verifyLedger(std::shared_ptr< Ledger const > const &ledger, std::shared_ptr< Ledger const > const &next, std::shared_ptr< DeterministicShard > dsh={}) const
Definition: Shard.cpp:960
ripple::NodeStore::Shard::prepare
boost::optional< std::uint32_t > prepare()
Definition: Shard.cpp:233
ripple::NodeStore::Shard::Shard
Shard(Application &app, DatabaseShard const &db, std::uint32_t index, beast::Journal j)
Definition: Shard.cpp:37
ripple::NodeStore::Shard::setFileStats
void setFileStats(std::lock_guard< std::recursive_mutex > const &lock)
Definition: Shard.cpp:936
ripple::NodeStore::Shard::legacy_
bool legacy_
Definition: Shard.h:227
ripple::NodeStore::Shard::fdRequired_
std::uint32_t fdRequired_
Definition: Shard.h:205
ripple::NodeStore::Shard::index
std::uint32_t index() const
Definition: Shard.h:79
ripple::NodeStore::Shard::fileInfo
std::pair< std::uint64_t, std::uint32_t > fileInfo() const
Returns a pair where the first item describes the storage space utilized and the second item is the n...
Definition: Shard.cpp:374
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::open
bool open(Scheduler &scheduler, nudb::context &ctx)
Definition: Shard.cpp:79
ripple::KeyCache
Maintains a cache of keys with no associated data.
Definition: KeyCache.h:43
ripple::NodeStore::Shard
Definition: Shard.h:52
ripple::NodeStore::Shard::txSQLiteDB_
std::unique_ptr< DatabaseCon > txSQLiteDB_
Definition: Shard.h:214
ripple::NodeStore::Shard::containsLedger
bool containsLedger(std::uint32_t seq) const
Definition: Shard.cpp:304
ripple::NodeStore::Shard::index_
const std::uint32_t index_
Definition: Shard.h:180
std::unique_ptr
STL class.
ripple::NodeStore::Shard::stop_
std::atomic< bool > stop_
Definition: Shard.h:233
ripple::NodeStore::Shard::nCache
std::shared_ptr< NCache > nCache() const
Definition: Shard.cpp:365
ripple::NodeStore::Shard::getBackendAll
std::tuple< std::shared_ptr< Backend >, std::shared_ptr< PCache >, std::shared_ptr< NCache > > getBackendAll() const
Definition: Shard.cpp:331
ripple::NodeStore::Shard::storeSQLite
bool storeSQLite(std::shared_ptr< Ledger const > const &ledger, std::lock_guard< std::recursive_mutex > const &lock)
Definition: Shard.cpp:768