rippled
Loading...
Searching...
No Matches
OpenLedger.cpp
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#include <xrpld/app/ledger/OpenLedger.h>
21#include <xrpld/app/main/Application.h>
22#include <xrpld/app/misc/HashRouter.h>
23#include <xrpld/app/misc/TxQ.h>
24#include <xrpld/app/tx/apply.h>
25#include <xrpld/overlay/Message.h>
26#include <xrpld/overlay/Overlay.h>
27
28#include <xrpl/ledger/CachedView.h>
29#include <xrpl/protocol/TxFlags.h>
30
31#include <boost/range/adaptor/transformed.hpp>
32
33namespace ripple {
34
37 CachedSLEs& cache,
38 beast::Journal journal)
39 : j_(journal), cache_(cache), current_(create(ledger->rules(), ledger))
40{
41}
42
43bool
45{
47 return current_->txCount() == 0;
48}
49
52{
54 return current_;
55}
56
57bool
59{
62 auto const changed = f(*next, j_);
63 if (changed)
64 {
66 current_ = std::move(next);
67 }
68 return changed;
69}
70
71void
73 Application& app,
74 Rules const& rules,
76 OrderedTxs const& locals,
77 bool retriesFirst,
78 OrderedTxs& retries,
79 ApplyFlags flags,
80 std::string const& suffix,
81 modify_type const& f)
82{
83 JLOG(j_.trace()) << "accept ledger " << ledger->seq() << " " << suffix;
84 auto next = create(rules, ledger);
85 if (retriesFirst)
86 {
87 // Handle disputed tx, outside lock
89 apply(app, *next, *ledger, empty{}, retries, flags, j_);
90 }
91 // Block calls to modify, otherwise
92 // new tx going into the open ledger
93 // would get lost.
95 // Apply tx from the current open view
96 if (!current_->txs.empty())
97 {
98 apply(
99 app,
100 *next,
101 *ledger,
102 boost::adaptors::transform(
103 current_->txs,
104 [](std::pair<
107 return p.first;
108 }),
109 retries,
110 flags,
111 j_);
112 }
113 // Call the modifier
114 if (f)
115 f(*next, j_);
116 // Apply local tx
117 for (auto const& item : locals)
118 app.getTxQ().apply(app, *next, item.second, flags, j_);
119
120 // If we didn't relay this transaction recently, relay it to all peers
121 for (auto const& txpair : next->txs)
122 {
123 auto const& tx = txpair.first;
124 auto const txId = tx->getTransactionID();
125
126 // skip batch txns
127 // LCOV_EXCL_START
128 if (tx->isFlag(tfInnerBatchTxn) && rules.enabled(featureBatch))
129 {
130 XRPL_ASSERT(
131 txpair.second && txpair.second->isFieldPresent(sfParentBatchID),
132 "Inner Batch transaction missing sfParentBatchID");
133 continue;
134 }
135 // LCOV_EXCL_STOP
136
137 if (auto const toSkip = app.getHashRouter().shouldRelay(txId))
138 {
139 JLOG(j_.debug()) << "Relaying recovered tx " << txId;
140 protocol::TMTransaction msg;
141 Serializer s;
142
143 tx->add(s);
144 msg.set_rawtransaction(s.data(), s.size());
145 msg.set_status(protocol::tsNEW);
146 msg.set_receivetimestamp(
147 app.timeKeeper().now().time_since_epoch().count());
148 app.overlay().relay(txId, msg, *toSkip);
149 }
150 }
151
152 // Switch to the new open view
154 current_ = std::move(next);
155}
156
157//------------------------------------------------------------------------------
158
161 Rules const& rules,
162 std::shared_ptr<Ledger const> const& ledger)
163{
166 rules,
168}
169
170auto
172 Application& app,
173 OpenView& view,
175 bool retry,
176 ApplyFlags flags,
178{
179 if (retry)
180 flags = flags | tapRETRY;
181 // If it's in anybody's proposed set, try to keep it in the ledger
182 auto const result = ripple::apply(app, view, *tx, flags, j);
183 if (result.applied || result.ter == terQUEUED)
184 return Result::success;
185 if (isTefFailure(result.ter) || isTemMalformed(result.ter) ||
186 isTelLocal(result.ter))
187 return Result::failure;
188 return Result::retry;
189}
190
191//------------------------------------------------------------------------------
192
195{
197 ss << tx->getTransactionID();
198 return ss.str().substr(0, 4);
199}
200
203{
205 for (auto const& item : set)
206 ss << debugTxstr(item.second) << ", ";
207 return ss.str();
208}
209
212{
214 for (auto const& item : set)
215 {
216 try
217 {
218 SerialIter sit(item.slice());
219 auto const tx = std::make_shared<STTx const>(sit);
220 ss << debugTxstr(tx) << ", ";
221 }
222 catch (std::exception const& ex)
223 {
224 ss << "THROW:" << ex.what() << ", ";
225 }
226 }
227 return ss.str();
228}
229
232{
234 for (auto const& item : view->txs)
235 ss << debugTxstr(item.first) << ", ";
236 return ss.str();
237}
238
239} // namespace ripple
A generic endpoint for log messages.
Definition Journal.h:60
Stream debug() const
Definition Journal.h:328
Stream trace() const
Severity stream access functions.
Definition Journal.h:322
virtual Overlay & overlay()=0
virtual TimeKeeper & timeKeeper()=0
virtual TxQ & getTxQ()=0
virtual HashRouter & getHashRouter()=0
Holds transactions which were deferred to the next pass of consensus.
std::optional< std::set< PeerShortID > > shouldRelay(uint256 const &key)
Determines whether the hashed item should be relayed.
bool modify(modify_type const &f)
Modify the open ledger.
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.
CachedSLEs & cache_
Definition OpenLedger.h:55
std::shared_ptr< OpenView > create(Rules const &rules, std::shared_ptr< Ledger const > const &ledger)
bool empty() const
Returns true if there are no transactions.
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:211
std::mutex modify_mutex_
Definition OpenLedger.h:56
static Result apply_one(Application &app, OpenView &view, std::shared_ptr< STTx const > const &tx, bool retry, ApplyFlags flags, beast::Journal j)
std::shared_ptr< OpenView const > current_
Definition OpenLedger.h:58
beast::Journal const j_
Definition OpenLedger.h:54
std::shared_ptr< OpenView const > current() const
Returns a view to the current open ledger.
std::mutex current_mutex_
Definition OpenLedger.h:57
Writable ledger view that accumulates state and tx changes.
Definition OpenView.h:65
virtual std::set< Peer::id_t > relay(protocol::TMProposeSet &m, uint256 const &uid, PublicKey const &validator)=0
Relay a proposal.
Rules controlling protocol behavior.
Definition Rules.h:38
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:130
A SHAMap is both a radix tree with a fan-out of 16 and a Merkle tree.
Definition SHAMap.h:97
std::size_t size() const noexcept
Definition Serializer.h:72
void const * data() const noexcept
Definition Serializer.h:78
Map/cache combination.
Definition TaggedCache.h:62
time_point now() const override
Returns the current time, using the server's clock.
Definition TimeKeeper.h:64
ApplyResult apply(Application &app, OpenView &view, std::shared_ptr< STTx const > const &tx, ApplyFlags flags, beast::Journal j)
Add a new transaction to the open ledger, hold it in the queue, or reject it.
Definition TxQ.cpp:729
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
constexpr struct ripple::open_ledger_t open_ledger
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,...
bool isTefFailure(TER x) noexcept
Definition TER.h:666
std::string debugTostr(OrderedTxs const &set)
ApplyResult apply(Application &app, OpenView &view, STTx const &tx, ApplyFlags flags, beast::Journal journal)
Apply a transaction to an OpenView.
Definition apply.cpp:146
bool isTemMalformed(TER x) noexcept
Definition TER.h:660
@ tapRETRY
Definition ApplyView.h:39
@ terQUEUED
Definition TER.h:225
bool isTelLocal(TER x) noexcept
Definition TER.h:654
std::string debugTxstr(std::shared_ptr< STTx const > const &tx)
constexpr std::uint32_t tfInnerBatchTxn
Definition TxFlags.h:61
T str(T... args)
T what(T... args)