rippled
Loading...
Searching...
No Matches
OpenLedger.cpp
1#include <xrpld/app/ledger/OpenLedger.h>
2#include <xrpld/app/main/Application.h>
3#include <xrpld/app/misc/HashRouter.h>
4#include <xrpld/app/misc/TxQ.h>
5#include <xrpld/app/tx/apply.h>
6#include <xrpld/overlay/Message.h>
7#include <xrpld/overlay/Overlay.h>
8
9#include <xrpl/ledger/CachedView.h>
10#include <xrpl/protocol/TxFlags.h>
11
12#include <boost/range/adaptor/transformed.hpp>
13
14namespace xrpl {
15
17 : j_(journal), cache_(cache), current_(create(ledger->rules(), ledger))
18{
19}
20
21bool
23{
25 return current_->txCount() == 0;
26}
27
30{
32 return current_;
33}
34
35bool
37{
40 auto const changed = f(*next, j_);
41 if (changed)
42 {
44 current_ = std::move(next);
45 }
46 return changed;
47}
48
49void
51 Application& app,
52 Rules const& rules,
54 OrderedTxs const& locals,
55 bool retriesFirst,
56 OrderedTxs& retries,
57 ApplyFlags flags,
58 std::string const& suffix,
59 modify_type const& f)
60{
61 JLOG(j_.trace()) << "accept ledger " << ledger->seq() << " " << suffix;
62 auto next = create(rules, ledger);
63 if (retriesFirst)
64 {
65 // Handle disputed tx, outside lock
67 apply(app, *next, *ledger, empty{}, retries, flags, j_);
68 }
69 // Block calls to modify, otherwise
70 // new tx going into the open ledger
71 // would get lost.
73 // Apply tx from the current open view
74 if (!current_->txs.empty())
75 {
76 apply(
77 app,
78 *next,
79 *ledger,
80 boost::adaptors::transform(
81 current_->txs,
83 return p.first;
84 }),
85 retries,
86 flags,
87 j_);
88 }
89 // Call the modifier
90 if (f)
91 f(*next, j_);
92 // Apply local tx
93 for (auto const& item : locals)
94 app.getTxQ().apply(app, *next, item.second, flags, j_);
95
96 // If we didn't relay this transaction recently, relay it to all peers
97 for (auto const& txpair : next->txs)
98 {
99 auto const& tx = txpair.first;
100 auto const txId = tx->getTransactionID();
101
102 // skip batch txns
103 // The flag should only be settable if Batch feature is enabled. If
104 // Batch is not enabled, the flag is always invalid, so don't relay it
105 // regardless.
106 // LCOV_EXCL_START
107 if (tx->isFlag(tfInnerBatchTxn))
108 {
109 XRPL_ASSERT(
110 txpair.second && txpair.second->isFieldPresent(sfParentBatchID),
111 "Inner Batch transaction missing sfParentBatchID");
112 continue;
113 }
114 // LCOV_EXCL_STOP
115
116 if (auto const toSkip = app.getHashRouter().shouldRelay(txId))
117 {
118 JLOG(j_.debug()) << "Relaying recovered tx " << txId;
119 protocol::TMTransaction msg;
120 Serializer s;
121
122 tx->add(s);
123 msg.set_rawtransaction(s.data(), s.size());
124 msg.set_status(protocol::tsNEW);
125 msg.set_receivetimestamp(app.timeKeeper().now().time_since_epoch().count());
126 app.overlay().relay(txId, msg, *toSkip);
127 }
128 }
129
130 // Switch to the new open view
132 current_ = std::move(next);
133}
134
135//------------------------------------------------------------------------------
136
142
143auto
145 Application& app,
146 OpenView& view,
148 bool retry,
149 ApplyFlags flags,
151{
152 if (retry)
153 flags = flags | tapRETRY;
154 // If it's in anybody's proposed set, try to keep it in the ledger
155 auto const result = xrpl::apply(app, view, *tx, flags, j);
156 if (result.applied || result.ter == terQUEUED)
157 return Result::success;
158 if (isTefFailure(result.ter) || isTemMalformed(result.ter) || isTelLocal(result.ter))
159 return Result::failure;
160 return Result::retry;
161}
162
163//------------------------------------------------------------------------------
164
167{
169 ss << tx->getTransactionID();
170 return ss.str().substr(0, 4);
171}
172
175{
177 for (auto const& item : set)
178 ss << debugTxstr(item.second) << ", ";
179 return ss.str();
180}
181
184{
186 for (auto const& item : set)
187 {
188 try
189 {
190 SerialIter sit(item.slice());
191 auto const tx = std::make_shared<STTx const>(sit);
192 ss << debugTxstr(tx) << ", ";
193 }
194 catch (std::exception const& ex)
195 {
196 ss << "THROW:" << ex.what() << ", ";
197 }
198 }
199 return ss.str();
200}
201
204{
206 for (auto const& item : view->txs)
207 ss << debugTxstr(item.first) << ", ";
208 return ss.str();
209}
210
211} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:41
Stream debug() const
Definition Journal.h:301
Stream trace() const
Severity stream access functions.
Definition Journal.h:295
virtual TxQ & getTxQ()=0
virtual HashRouter & getHashRouter()=0
virtual TimeKeeper & timeKeeper()=0
virtual Overlay & overlay()=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.
beast::Journal const j_
Definition OpenLedger.h:35
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.
bool empty() const
Returns true if there are no transactions.
std::shared_ptr< OpenView const > current() const
Returns a view to the current open ledger.
std::shared_ptr< OpenView > create(Rules const &rules, std::shared_ptr< Ledger const > const &ledger)
std::shared_ptr< OpenView const > current_
Definition OpenLedger.h:39
OpenLedger()=delete
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:189
static Result apply_one(Application &app, OpenView &view, std::shared_ptr< STTx const > const &tx, bool retry, ApplyFlags flags, beast::Journal j)
CachedSLEs & cache_
Definition OpenLedger.h:36
std::mutex current_mutex_
Definition OpenLedger.h:38
std::mutex modify_mutex_
Definition OpenLedger.h:37
Writable ledger view that accumulates state and tx changes.
Definition OpenView.h:46
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:19
A SHAMap is both a radix tree with a fan-out of 16 and a Merkle tree.
Definition SHAMap.h:78
std::size_t size() const noexcept
Definition Serializer.h:51
void const * data() const noexcept
Definition Serializer.h:57
Map/cache combination.
Definition TaggedCache.h:43
time_point now() const override
Returns the current time, using the server's clock.
Definition TimeKeeper.h:44
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:663
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
@ terQUEUED
Definition TER.h:206
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,...
constexpr struct xrpl::open_ledger_t open_ledger
ApplyResult apply(Application &app, OpenView &view, STTx const &tx, ApplyFlags flags, beast::Journal journal)
Apply a transaction to an OpenView.
Definition apply.cpp:117
constexpr std::uint32_t tfInnerBatchTxn
Definition TxFlags.h:42
bool isTefFailure(TER x) noexcept
Definition TER.h:638
std::string debugTxstr(std::shared_ptr< STTx const > const &tx)
std::string debugTostr(OrderedTxs const &set)
ApplyFlags
Definition ApplyView.h:11
@ tapRETRY
Definition ApplyView.h:20
bool isTelLocal(TER x) noexcept
Definition TER.h:626
bool isTemMalformed(TER x) noexcept
Definition TER.h:632
T str(T... args)
T what(T... args)