rippled
OpenLedger.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 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_APP_LEDGER_OPENLEDGER_H_INCLUDED
21 #define RIPPLE_APP_LEDGER_OPENLEDGER_H_INCLUDED
22 
23 #include <ripple/app/ledger/Ledger.h>
24 #include <ripple/ledger/CachedSLEs.h>
25 #include <ripple/ledger/OpenView.h>
26 #include <ripple/app/misc/CanonicalTXSet.h>
27 #include <ripple/basics/Log.h>
28 #include <ripple/basics/UnorderedContainers.h>
29 #include <ripple/core/Config.h>
30 #include <ripple/beast/utility/Journal.h>
31 #include <cassert>
32 #include <mutex>
33 
34 namespace ripple {
35 
36 // How many total extra passes we make
37 // We must ensure we make at least one non-retriable pass
38 #define LEDGER_TOTAL_PASSES 3
39 
40 // How many extra retry passes we
41 // make if the previous retry pass made changes
42 #define LEDGER_RETRY_PASSES 1
43 
45 
46 //------------------------------------------------------------------------------
47 
50 {
51 private:
57 
58 public:
70  using modify_type = std::function<
72 
73  OpenLedger() = delete;
74  OpenLedger (OpenLedger const&) = delete;
75  OpenLedger& operator= (OpenLedger const&) = delete;
76 
81  explicit
83  Ledger const> const& ledger,
84  CachedSLEs& cache,
85  beast::Journal journal);
86 
100  bool
101  empty() const;
102 
114  current() const;
115 
126  bool
127  modify (modify_type const& f);
128 
162  void
163  accept (Application& app, Rules const& rules,
164  std::shared_ptr<Ledger const> const& ledger,
165  OrderedTxs const& locals, bool retriesFirst,
166  OrderedTxs& retries, ApplyFlags flags,
167  std::string const& suffix = "",
168  modify_type const& f = {});
169 
170 private:
176  template <class FwdRange>
177  static
178  void
179  apply (Application& app, OpenView& view,
180  ReadView const& check, FwdRange const& txs,
181  OrderedTxs& retries, ApplyFlags flags,
182  std::map<uint256, bool>& shouldRecover,
183  beast::Journal j);
184 
185  enum Result
186  {
190  };
191 
193  create (Rules const& rules,
194  std::shared_ptr<Ledger const> const& ledger);
195 
196  static
197  Result
198  apply_one (Application& app, OpenView& view,
200  bool retry, ApplyFlags flags,
201  bool shouldRecover, beast::Journal j);
202 };
203 
204 //------------------------------------------------------------------------------
205 
206 template <class FwdRange>
207 void
209  ReadView const& check, FwdRange const& txs,
210  OrderedTxs& retries, ApplyFlags flags,
211  std::map<uint256, bool>& shouldRecover,
212  beast::Journal j)
213 {
214  for (auto iter = txs.begin();
215  iter != txs.end(); ++iter)
216  {
217  try
218  {
219  // Dereferencing the iterator can
220  // throw since it may be transformed.
221  auto const tx = *iter;
222  auto const txId = tx->getTransactionID();
223  if (check.txExists(txId))
224  continue;
225  auto const result = apply_one(app, view,
226  tx, true, flags, shouldRecover[txId], j);
227  if (result == Result::retry)
228  retries.insert(tx);
229  }
230  catch(std::exception const&)
231  {
232  JLOG(j.error()) <<
233  "Caught exception";
234  }
235  }
236  bool retry = true;
237  for (int pass = 0;
238  pass < LEDGER_TOTAL_PASSES;
239  ++pass)
240  {
241  int changes = 0;
242  auto iter = retries.begin();
243  while (iter != retries.end())
244  {
245  switch (apply_one(app, view,
246  iter->second, retry, flags,
247  shouldRecover[iter->second->getTransactionID()], j))
248  {
249  case Result::success:
250  ++changes;
251  [[fallthrough]];
252  case Result::failure:
253  iter = retries.erase (iter);
254  break;
255  case Result::retry:
256  ++iter;
257  }
258  }
259  // A non-retry pass made no changes
260  if (! changes && ! retry)
261  return;
262  // Stop retriable passes
263  if (! changes || (pass >= LEDGER_RETRY_PASSES))
264  retry = false;
265  }
266 
267  // If there are any transactions left, we must have
268  // tried them in at least one final pass
269  assert (retries.empty() || ! retry);
270 }
271 
272 //------------------------------------------------------------------------------
273 
274 // For debug logging
275 
278 
280 debugTostr (OrderedTxs const& set);
281 
283 debugTostr (SHAMap const& set);
284 
287 
288 } // ripple
289 
290 #endif
ripple::Application
Definition: Application.h:85
ripple::OpenLedger::current
std::shared_ptr< OpenView const > current() const
Returns a view to the current open ledger.
Definition: OpenLedger.cpp:52
std::string
STL class.
std::shared_ptr
STL class.
std::exception
STL class.
ripple::OpenLedger::current_
std::shared_ptr< OpenView const > current_
Definition: OpenLedger.h:56
ripple::CanonicalTXSet::erase
const_iterator erase(const_iterator const &it)
Definition: CanonicalTXSet.h:98
ripple::OpenLedger::operator=
OpenLedger & operator=(OpenLedger const &)=delete
ripple::OpenView
Writable ledger view that accumulates state and tx changes.
Definition: OpenView.h:52
ripple::ApplyFlags
ApplyFlags
Definition: ApplyView.h:30
ripple::OpenLedger::success
@ success
Definition: OpenLedger.h:187
std::function
ripple::OpenLedger::modify_mutex_
std::mutex modify_mutex_
Definition: OpenLedger.h:54
ripple::OpenLedger::retry
@ retry
Definition: OpenLedger.h:189
ripple::OpenLedger::accept
void accept(Application &app, Rules const &rules, std::shared_ptr< Ledger const > const &ledger, OrderedTxs const &locals, bool retriesFirst, OrderedTxs &retries, ApplyFlags flags, std::string const &suffix="", modify_type const &f={})
Accept a new ledger.
Definition: OpenLedger.cpp:74
ripple::CanonicalTXSet
Holds transactions which were deferred to the next pass of consensus.
Definition: CanonicalTXSet.h:36
ripple::CanonicalTXSet::begin
const_iterator begin() const
Definition: CanonicalTXSet.h:103
ripple::Ledger
Holds a ledger.
Definition: Ledger.h:77
ripple::OpenLedger::failure
@ failure
Definition: OpenLedger.h:188
ripple::CachedSLEs
Caches SLEs by their digest.
Definition: CachedSLEs.h:32
ripple::OpenLedger::j_
const beast::Journal j_
Definition: OpenLedger.h:52
ripple::OpenLedger::OpenLedger
OpenLedger()=delete
ripple::SHAMap
A SHAMap is both a radix tree with a fan-out of 16 and a Merkle tree.
Definition: SHAMap.h:79
ripple::set
bool set(T &target, std::string const &name, Section const &section)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
Definition: BasicConfig.h:271
beast::Journal::error
Stream error() const
Definition: Journal.h:307
ripple::debugTxstr
std::string debugTxstr(std::shared_ptr< STTx const > const &tx)
Definition: OpenLedger.cpp:208
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:60
std::map
STL class.
ripple::CanonicalTXSet::insert
void insert(std::shared_ptr< STTx const > const &txn)
Definition: CanonicalTXSet.cpp:88
ripple::debugTostr
std::string debugTostr(OrderedTxs const &set)
Definition: OpenLedger.cpp:216
ripple::OpenLedger::empty
bool empty() const
Returns true if there are no transactions.
Definition: OpenLedger.cpp:45
ripple::CanonicalTXSet::end
const_iterator end() const
Definition: CanonicalTXSet.h:108
ripple::OpenLedger
Represents the open ledger.
Definition: OpenLedger.h:49
ripple::ReadView
A view into a ledger.
Definition: ReadView.h:186
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::OpenLedger::cache_
CachedSLEs & cache_
Definition: OpenLedger.h:53
cassert
ripple::CanonicalTXSet::empty
bool empty() const
Definition: CanonicalTXSet.h:117
ripple::Rules
Rules controlling protocol behavior.
Definition: ReadView.h:126
mutex
ripple::OpenLedger::Result
Result
Definition: OpenLedger.h:185
ripple::OpenLedger::create
std::shared_ptr< OpenView > create(Rules const &rules, std::shared_ptr< Ledger const > const &ledger)
Definition: OpenLedger.cpp:167
ripple::OpenLedger::current_mutex_
std::mutex current_mutex_
Definition: OpenLedger.h:55
ripple::OpenLedger::apply_one
static Result apply_one(Application &app, OpenView &view, std::shared_ptr< STTx const > const &tx, bool retry, ApplyFlags flags, bool shouldRecover, beast::Journal j)
Definition: OpenLedger.cpp:177
ripple::OpenLedger::apply
static void apply(Application &app, OpenView &view, ReadView const &check, FwdRange const &txs, OrderedTxs &retries, ApplyFlags flags, std::map< uint256, bool > &shouldRecover, beast::Journal j)
Algorithm for applying transactions.
Definition: OpenLedger.h:208
ripple::OpenLedger::modify
bool modify(modify_type const &f)
Modify the open ledger.
Definition: OpenLedger.cpp:59