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