xrpld
Loading...
Searching...
No Matches
OpenLedger.cpp
1#include <xrpld/app/ledger/OpenLedger.h>
2
3#include <xrpld/app/main/Application.h>
4#include <xrpld/app/misc/TxQ.h>
5#include <xrpld/core/TimeKeeper.h>
6#include <xrpld/overlay/Overlay.h>
7
8#include <xrpl/basics/Log.h>
9#include <xrpl/beast/utility/Journal.h>
10#include <xrpl/beast/utility/instrumentation.h>
11#include <xrpl/core/HashRouter.h>
12#include <xrpl/ledger/ApplyView.h>
13#include <xrpl/ledger/Ledger.h>
14#include <xrpl/ledger/OpenView.h>
15#include <xrpl/ledger/ReadView.h>
16#include <xrpl/protocol/Rules.h>
17#include <xrpl/protocol/SField.h>
18#include <xrpl/protocol/STObject.h>
19#include <xrpl/protocol/STTx.h>
20#include <xrpl/protocol/Serializer.h>
21#include <xrpl/protocol/TER.h>
22#include <xrpl/protocol/TxFlags.h>
23#include <xrpl/shamap/SHAMap.h>
24#include <xrpl/tx/apply.h>
25
26#include <boost/range/adaptor/transformed.hpp>
27
28#include <xrpl.pb.h>
29
30#include <exception>
31#include <memory>
32#include <mutex>
33#include <sstream>
34#include <string>
35#include <string_view>
36#include <utility>
37#include <vector>
38
39namespace xrpl {
40
43 CachedSLEs& cache,
44 beast::Journal journal)
45 : j_(journal), cache_(cache), current_(create(ledger->rules(), ledger))
46{
47}
48
49bool
51{
53 return current_->txCount() == 0;
54}
55
58{
60 return current_;
61}
62
63bool
65{
66 std::scoped_lock const lock1(modifyMutex_);
68 auto const changed = f(*next, j_);
69 if (changed)
70 {
72 current_ = std::move(next);
73 }
74 return changed;
75}
76
77void
79 Application& app,
80 Rules const& rules,
82 OrderedTxs const& locals,
83 bool retriesFirst,
84 OrderedTxs& retries,
85 ApplyFlags flags,
86 std::string_view suffix,
87 modify_type const& f)
88{
89 JLOG(j_.trace()) << "accept ledger " << ledger->seq() << " " << suffix;
90 auto next = create(rules, ledger);
91 if (retriesFirst)
92 {
93 // Handle disputed tx, outside lock
95 apply(app, *next, *ledger, empty{}, retries, flags, j_);
96 }
97 // Block calls to modify, otherwise
98 // new tx going into the open ledger
99 // would get lost.
100 std::scoped_lock const lock1(modifyMutex_);
101 // Apply tx from the current open view
102 if (!current_->txs.empty())
103 {
104 apply(
105 app,
106 *next,
107 *ledger,
108 boost::adaptors::transform(
109 current_->txs,
111 p) { return p.first; }),
112 retries,
113 flags,
114 j_);
115 }
116 // Call the modifier
117 if (f)
118 f(*next, j_);
119 // Apply local tx
120 for (auto const& item : locals)
121 app.getTxQ().apply(app, *next, item.second, flags, j_);
122
123 // If we didn't relay this transaction recently, relay it to all peers
124 for (auto const& txpair : next->txs)
125 {
126 auto const& tx = txpair.first;
127 auto const txId = tx->getTransactionID();
128
129 // skip batch txns
130 // The flag should only be settable if Batch feature is enabled. If
131 // Batch is not enabled, the flag is always invalid, so don't relay it
132 // regardless.
133 // LCOV_EXCL_START
134 if (tx->isFlag(tfInnerBatchTxn))
135 {
136 XRPL_ASSERT(
137 txpair.second && txpair.second->isFieldPresent(sfParentBatchID),
138 "Inner Batch transaction missing sfParentBatchID");
139 continue;
140 }
141 // LCOV_EXCL_STOP
142
143 if (auto const toSkip = app.getHashRouter().shouldRelay(txId))
144 {
145 JLOG(j_.debug()) << "Relaying recovered tx " << txId;
146 protocol::TMTransaction msg;
147 Serializer s;
148
149 tx->add(s);
150 msg.set_rawtransaction(s.data(), s.size());
151 msg.set_status(protocol::tsNEW);
152 msg.set_receivetimestamp(app.getTimeKeeper().now().time_since_epoch().count());
153 app.getOverlay().relay(txId, msg, *toSkip);
154 }
155 }
156
157 // Switch to the new open view
158 std::scoped_lock const lock2(currentMutex_);
159 current_ = std::move(next);
160}
161
162//------------------------------------------------------------------------------
163
170
171auto
173 Application& app,
174 OpenView& view,
176 bool retry,
177 ApplyFlags flags,
179{
180 if (retry)
181 flags = flags | TapRetry;
182 // If it's in anybody's proposed set, try to keep it in the ledger
183 auto const result = xrpl::apply(app, view, *tx, flags, j);
184 if (result.applied || result.ter == terQUEUED)
185 return Result::Success;
186 if (isTefFailure(result.ter) || isTemMalformed(result.ter) || 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 xrpl
A generic endpoint for log messages.
Definition Journal.h:38
std::optional< std::set< PeerShortID > > shouldRelay(uint256 const &key)
Determines whether the hashed item should be relayed.
static Result applyOne(Application &app, OpenView &view, std::shared_ptr< STTx const > const &tx, bool retry, ApplyFlags flags, beast::Journal j)
beast::Journal const j_
Definition OpenLedger.h:35
bool modify(modify_type const &f)
Modify the open ledger.
std::function< bool(OpenView &, beast::Journal)> modify_type
Signature for modification functions.
Definition OpenLedger.h:53
bool empty() const
Returns true if there are no transactions.
std::mutex currentMutex_
Definition OpenLedger.h:38
std::shared_ptr< OpenView const > current() const
Returns a view to the current open ledger.
std::mutex modifyMutex_
Definition OpenLedger.h:37
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:192
CachedSLEs & cache_
Definition OpenLedger.h:36
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_view suffix="", modify_type const &f={})
Accept a new ledger.
Writable ledger view that accumulates state and tx changes.
Definition OpenView.h:45
virtual std::set< Peer::id_t > relay(protocol::TMProposeSet const &m, uint256 const &uid, PublicKey const &validator)=0
Relay a proposal.
Rules controlling protocol behavior.
Definition Rules.h:33
A SHAMap is both a radix tree with a fan-out of 16 and a Merkle tree.
Definition SHAMap.h:77
std::size_t size() const noexcept
Definition Serializer.h:50
void const * data() const noexcept
Definition Serializer.h:56
virtual TxQ & getTxQ()=0
virtual HashRouter & getHashRouter()=0
virtual Overlay & getOverlay()=0
virtual TimeKeeper & getTimeKeeper()=0
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:728
T make_shared(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
@ terQUEUED
Definition TER.h:217
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 FlagValue tfInnerBatchTxn
Definition TxFlags.h:43
ApplyResult apply(ServiceRegistry &registry, OpenView &view, STTx const &tx, ApplyFlags flags, beast::Journal journal)
Apply a transaction to an OpenView.
Definition apply.cpp:139
bool isTefFailure(TER x) noexcept
Definition TER.h:651
std::string debugTxstr(std::shared_ptr< STTx const > const &tx)
TaggedCache< uint256, SLE const > CachedSLEs
std::string debugTostr(OrderedTxs const &set)
ApplyFlags
Definition ApplyView.h:12
@ TapRetry
Definition ApplyView.h:21
bool isTelLocal(TER x) noexcept
Definition TER.h:639
constexpr struct xrpl::OpenLedgerT kOpenLedger
bool isTemMalformed(TER x) noexcept
Definition TER.h:645
CanonicalTXSet OrderedTxs
Definition OpenLedger.h:27
T str(T... args)
T what(T... args)