rippled
Loading...
Searching...
No Matches
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 <xrpld/app/ledger/Ledger.h>
24#include <xrpld/app/misc/CanonicalTXSet.h>
25#include <xrpld/core/Config.h>
26#include <xrpld/ledger/CachedSLEs.h>
27#include <xrpld/ledger/OpenView.h>
28#include <xrpl/basics/Log.h>
29#include <xrpl/basics/UnorderedContainers.h>
30#include <xrpl/beast/utility/Journal.h>
31#include <xrpl/beast/utility/instrumentation.h>
32#include <mutex>
33
34namespace 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{
51private:
57
58public:
71
72 OpenLedger() = delete;
73 OpenLedger(OpenLedger const&) = delete;
75 operator=(OpenLedger const&) = delete;
76
81 explicit OpenLedger(
83 CachedSLEs& cache,
84 beast::Journal journal);
85
99 bool
100 empty() const;
101
113 current() const;
114
125 bool
126 modify(modify_type const& f);
127
161 void
162 accept(
163 Application& app,
164 Rules const& rules,
165 std::shared_ptr<Ledger const> const& ledger,
166 OrderedTxs const& locals,
167 bool retriesFirst,
168 OrderedTxs& retries,
169 ApplyFlags flags,
170 std::string const& suffix = "",
171 modify_type const& f = {});
172
173private:
179 template <class FwdRange>
180 static void
181 apply(
182 Application& app,
183 OpenView& view,
184 ReadView const& check,
185 FwdRange const& txs,
186 OrderedTxs& retries,
187 ApplyFlags flags,
189
191
193 create(Rules const& rules, std::shared_ptr<Ledger const> const& ledger);
194
195 static Result
196 apply_one(
197 Application& app,
198 OpenView& view,
200 bool retry,
201 ApplyFlags flags,
203};
204
205//------------------------------------------------------------------------------
206
207template <class FwdRange>
208void
210 Application& app,
211 OpenView& view,
212 ReadView const& check,
213 FwdRange const& txs,
214 OrderedTxs& retries,
215 ApplyFlags flags,
217{
218 for (auto iter = txs.begin(); iter != txs.end(); ++iter)
219 {
220 try
221 {
222 // Dereferencing the iterator can throw since it may be transformed.
223 auto const tx = *iter;
224 auto const txId = tx->getTransactionID();
225 if (check.txExists(txId))
226 continue;
227 auto const result = apply_one(app, view, tx, true, flags, j);
228 if (result == Result::retry)
229 retries.insert(tx);
230 }
231 catch (std::exception const& e)
232 {
233 JLOG(j.error())
234 << "OpenLedger::apply: Caught exception: " << e.what();
235 }
236 }
237 bool retry = true;
238 for (int pass = 0; pass < LEDGER_TOTAL_PASSES; ++pass)
239 {
240 int changes = 0;
241 auto iter = retries.begin();
242 while (iter != retries.end())
243 {
244 switch (apply_one(app, view, iter->second, retry, flags, j))
245 {
246 case Result::success:
247 ++changes;
248 [[fallthrough]];
249 case Result::failure:
250 iter = retries.erase(iter);
251 break;
252 case Result::retry:
253 ++iter;
254 }
255 }
256 // A non-retry pass made no changes
257 if (!changes && !retry)
258 return;
259 // Stop retriable passes
260 if (!changes || (pass >= LEDGER_RETRY_PASSES))
261 retry = false;
262 }
263
264 // If there are any transactions left, we must have
265 // tried them in at least one final pass
266 XRPL_ASSERT(
267 retries.empty() || !retry, "ripple::OpenLedger::apply : valid retries");
268}
269
270//------------------------------------------------------------------------------
271
272// For debug logging
273
276
278debugTostr(OrderedTxs const& set);
279
281debugTostr(SHAMap const& set);
282
285
286} // namespace ripple
287
288#endif
A generic endpoint for log messages.
Definition: Journal.h:59
Stream error() const
Definition: Journal.h:335
Holds transactions which were deferred to the next pass of consensus.
void insert(std::shared_ptr< STTx const > const &txn)
const_iterator end() const
const_iterator begin() const
const_iterator erase(const_iterator const &it)
Represents the open ledger.
Definition: OpenLedger.h:50
bool modify(modify_type const &f)
Modify the open ledger.
Definition: OpenLedger.cpp:57
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:71
CachedSLEs & cache_
Definition: OpenLedger.h:53
OpenLedger(OpenLedger const &)=delete
std::shared_ptr< OpenView > create(Rules const &rules, std::shared_ptr< Ledger const > const &ledger)
Definition: OpenLedger.cpp:147
bool empty() const
Returns true if there are no transactions.
Definition: OpenLedger.cpp:43
static void apply(Application &app, OpenView &view, ReadView const &check, FwdRange const &txs, OrderedTxs &retries, ApplyFlags flags, beast::Journal j)
Algorithm for applying transactions.
Definition: OpenLedger.h:209
std::mutex modify_mutex_
Definition: OpenLedger.h:54
OpenLedger & operator=(OpenLedger const &)=delete
static Result apply_one(Application &app, OpenView &view, std::shared_ptr< STTx const > const &tx, bool retry, ApplyFlags flags, beast::Journal j)
Definition: OpenLedger.cpp:158
std::shared_ptr< OpenView const > current_
Definition: OpenLedger.h:56
beast::Journal const j_
Definition: OpenLedger.h:52
std::shared_ptr< OpenView const > current() const
Returns a view to the current open ledger.
Definition: OpenLedger.cpp:50
std::mutex current_mutex_
Definition: OpenLedger.h:55
Writable ledger view that accumulates state and tx changes.
Definition: OpenView.h:56
A view into a ledger.
Definition: ReadView.h:55
Rules controlling protocol behavior.
Definition: Rules.h:35
A SHAMap is both a radix tree with a fan-out of 16 and a Merkle tree.
Definition: SHAMap.h:96
Map/cache combination.
Definition: TaggedCache.h:57
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
boost::outcome_v2::result< T, std::error_code > Result
Definition: b58_utils.h:38
std::string debugTostr(OrderedTxs const &set)
Definition: OpenLedger.cpp:189
ApplyFlags
Definition: ApplyView.h:30
std::string debugTxstr(std::shared_ptr< STTx const > const &tx)
Definition: OpenLedger.cpp:181
T what(T... args)