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/ledger/CachedView.h>
26#include <xrpld/overlay/Message.h>
27#include <xrpld/overlay/Overlay.h>
28
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{
61 auto next = std::make_shared<OpenView>(*current_);
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,
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{
164 return std::make_shared<OpenView>(
166 rules,
167 std::make_shared<CachedLedger const>(ledger, cache_));
168}
169
170auto
172 Application& app,
173 OpenView& view,
175 bool retry,
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.
Definition: HashRouter.cpp:119
bool modify(modify_type const &f)
Modify the open ledger.
Definition: OpenLedger.cpp:58
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:72
CachedSLEs & cache_
Definition: OpenLedger.h:55
std::shared_ptr< OpenView > create(Rules const &rules, std::shared_ptr< Ledger const > const &ledger)
Definition: OpenLedger.cpp:160
bool empty() const
Returns true if there are no transactions.
Definition: OpenLedger.cpp:44
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)
Definition: OpenLedger.cpp:171
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.
Definition: OpenLedger.cpp:51
std::mutex current_mutex_
Definition: OpenLedger.h:57
Writable ledger view that accumulates state and tx changes.
Definition: OpenView.h:66
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:35
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:98
std::size_t size() const noexcept
Definition: Serializer.h:73
void const * data() const noexcept
Definition: Serializer.h:79
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:730
Match set account flags.
Definition: flags.h:125
Json::Value create(AccountID const &account, AccountID const &to, STAmount const &amount, NetClock::duration const &settleDelay, PublicKey const &pk, std::optional< NetClock::time_point > const &cancelAfter, std::optional< std::uint32_t > const &dstTag)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
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,...
Definition: BasicConfig.h:315
bool isTefFailure(TER x) noexcept
Definition: TER.h:660
std::string debugTostr(OrderedTxs const &set)
Definition: OpenLedger.cpp:202
ApplyResult apply(Application &app, OpenView &view, STTx const &tx, ApplyFlags flags, beast::Journal journal)
Apply a transaction to an OpenView.
Definition: apply.cpp:143
bool isTemMalformed(TER x) noexcept
Definition: TER.h:654
ApplyFlags
Definition: ApplyView.h:31
@ tapRETRY
Definition: ApplyView.h:40
@ terQUEUED
Definition: TER.h:225
bool isTelLocal(TER x) noexcept
Definition: TER.h:648
std::string debugTxstr(std::shared_ptr< STTx const > const &tx)
Definition: OpenLedger.cpp:194
constexpr std::uint32_t tfInnerBatchTxn
Definition: TxFlags.h:61
T str(T... args)
T what(T... args)