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/core/TimeKeeper.h>
5#include <xrpld/overlay/Message.h>
6#include <xrpld/overlay/Overlay.h>
7
8#include <xrpl/core/HashRouter.h>
9#include <xrpl/ledger/CachedView.h>
10#include <xrpl/protocol/TxFlags.h>
11#include <xrpl/tx/apply.h>
12
13#include <boost/range/adaptor/transformed.hpp>
14
15namespace xrpl {
16
19 CachedSLEs& cache,
20 beast::Journal journal)
21 : j_(journal), cache_(cache), current_(create(ledger->rules(), ledger))
22{
23}
24
25bool
27{
29 return current_->txCount() == 0;
30}
31
34{
36 return current_;
37}
38
39bool
41{
42 std::lock_guard const lock1(modify_mutex_);
44 auto const changed = f(*next, j_);
45 if (changed)
46 {
48 current_ = std::move(next);
49 }
50 return changed;
51}
52
53void
55 Application& app,
56 Rules const& rules,
58 OrderedTxs const& locals,
59 bool retriesFirst,
60 OrderedTxs& retries,
61 ApplyFlags flags,
62 std::string const& suffix,
63 modify_type const& f)
64{
65 JLOG(j_.trace()) << "accept ledger " << ledger->seq() << " " << suffix;
66 auto next = create(rules, ledger);
67 if (retriesFirst)
68 {
69 // Handle disputed tx, outside lock
71 apply(app, *next, *ledger, empty{}, retries, flags, j_);
72 }
73 // Block calls to modify, otherwise
74 // new tx going into the open ledger
75 // would get lost.
76 std::lock_guard const lock1(modify_mutex_);
77 // Apply tx from the current open view
78 if (!current_->txs.empty())
79 {
80 apply(
81 app,
82 *next,
83 *ledger,
84 boost::adaptors::transform(
85 current_->txs,
87 p) { return p.first; }),
88 retries,
89 flags,
90 j_);
91 }
92 // Call the modifier
93 if (f)
94 f(*next, j_);
95 // Apply local tx
96 for (auto const& item : locals)
97 app.getTxQ().apply(app, *next, item.second, flags, j_);
98
99 // If we didn't relay this transaction recently, relay it to all peers
100 for (auto const& txpair : next->txs)
101 {
102 auto const& tx = txpair.first;
103 auto const txId = tx->getTransactionID();
104
105 // skip batch txns
106 // The flag should only be settable if Batch feature is enabled. If
107 // Batch is not enabled, the flag is always invalid, so don't relay it
108 // regardless.
109 // LCOV_EXCL_START
110 if (tx->isFlag(tfInnerBatchTxn))
111 {
112 XRPL_ASSERT(
113 txpair.second && txpair.second->isFieldPresent(sfParentBatchID),
114 "Inner Batch transaction missing sfParentBatchID");
115 continue;
116 }
117 // LCOV_EXCL_STOP
118
119 if (auto const toSkip = app.getHashRouter().shouldRelay(txId))
120 {
121 JLOG(j_.debug()) << "Relaying recovered tx " << txId;
122 protocol::TMTransaction msg;
123 Serializer s;
124
125 tx->add(s);
126 msg.set_rawtransaction(s.data(), s.size());
127 msg.set_status(protocol::tsNEW);
128 msg.set_receivetimestamp(app.getTimeKeeper().now().time_since_epoch().count());
129 app.getOverlay().relay(txId, msg, *toSkip);
130 }
131 }
132
133 // Switch to the new open view
134 std::lock_guard const lock2(current_mutex_);
135 current_ = std::move(next);
136}
137
138//------------------------------------------------------------------------------
139
146
147auto
149 Application& app,
150 OpenView& view,
152 bool retry,
153 ApplyFlags flags,
155{
156 if (retry)
157 flags = flags | tapRETRY;
158 // If it's in anybody's proposed set, try to keep it in the ledger
159 auto const result = xrpl::apply(app, view, *tx, flags, j);
160 if (result.applied || result.ter == terQUEUED)
161 return Result::success;
162 if (isTefFailure(result.ter) || isTemMalformed(result.ter) || isTelLocal(result.ter))
163 return Result::failure;
164 return Result::retry;
165}
166
167//------------------------------------------------------------------------------
168
171{
173 ss << tx->getTransactionID();
174 return ss.str().substr(0, 4);
175}
176
179{
181 for (auto const& item : set)
182 ss << debugTxstr(item.second) << ", ";
183 return ss.str();
184}
185
188{
190 for (auto const& item : set)
191 {
192 try
193 {
194 SerialIter sit(item.slice());
195 auto const tx = std::make_shared<STTx const>(sit);
196 ss << debugTxstr(tx) << ", ";
197 }
198 catch (std::exception const& ex)
199 {
200 ss << "THROW:" << ex.what() << ", ";
201 }
202 }
203 return ss.str();
204}
205
208{
210 for (auto const& item : view->txs)
211 ss << debugTxstr(item.first) << ", ";
212 return ss.str();
213}
214
215} // 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 HashRouter & getHashRouter()=0
virtual Overlay & getOverlay()=0
virtual TimeKeeper & getTimeKeeper()=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:686
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 FlagValue tfInnerBatchTxn
Definition TxFlags.h:41
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:124
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)