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 ripple {
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,
85 [](std::pair<
88 return p.first;
89 }),
90 retries,
91 flags,
92 j_);
93 }
94 // Call the modifier
95 if (f)
96 f(*next, j_);
97 // Apply local tx
98 for (auto const& item : locals)
99 app.getTxQ().apply(app, *next, item.second, flags, j_);
100
101 // If we didn't relay this transaction recently, relay it to all peers
102 for (auto const& txpair : next->txs)
103 {
104 auto const& tx = txpair.first;
105 auto const txId = tx->getTransactionID();
106
107 // skip batch txns
108 // LCOV_EXCL_START
109 if (tx->isFlag(tfInnerBatchTxn) && rules.enabled(featureBatch))
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(
128 app.timeKeeper().now().time_since_epoch().count());
129 app.overlay().relay(txId, msg, *toSkip);
130 }
131 }
132
133 // Switch to the new open view
135 current_ = std::move(next);
136}
137
138//------------------------------------------------------------------------------
139
142 Rules const& rules,
143 std::shared_ptr<Ledger const> const& ledger)
144{
147 rules,
149}
150
151auto
153 Application& app,
154 OpenView& view,
156 bool retry,
157 ApplyFlags flags,
159{
160 if (retry)
161 flags = flags | tapRETRY;
162 // If it's in anybody's proposed set, try to keep it in the ledger
163 auto const result = ripple::apply(app, view, *tx, flags, j);
164 if (result.applied || result.ter == terQUEUED)
165 return Result::success;
166 if (isTefFailure(result.ter) || isTemMalformed(result.ter) ||
167 isTelLocal(result.ter))
168 return Result::failure;
169 return Result::retry;
170}
171
172//------------------------------------------------------------------------------
173
176{
178 ss << tx->getTransactionID();
179 return ss.str().substr(0, 4);
180}
181
184{
186 for (auto const& item : set)
187 ss << debugTxstr(item.second) << ", ";
188 return ss.str();
189}
190
193{
195 for (auto const& item : set)
196 {
197 try
198 {
199 SerialIter sit(item.slice());
200 auto const tx = std::make_shared<STTx const>(sit);
201 ss << debugTxstr(tx) << ", ";
202 }
203 catch (std::exception const& ex)
204 {
205 ss << "THROW:" << ex.what() << ", ";
206 }
207 }
208 return ss.str();
209}
210
213{
215 for (auto const& item : view->txs)
216 ss << debugTxstr(item.first) << ", ";
217 return ss.str();
218}
219
220} // namespace ripple
A generic endpoint for log messages.
Definition Journal.h:41
Stream debug() const
Definition Journal.h:309
Stream trace() const
Severity stream access functions.
Definition Journal.h:303
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.
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.
CachedSLEs & cache_
Definition OpenLedger.h:36
std::shared_ptr< OpenView > create(Rules const &rules, std::shared_ptr< Ledger const > const &ledger)
bool empty() const
Returns true if there are no transactions.
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
std::mutex modify_mutex_
Definition OpenLedger.h:37
static Result apply_one(Application &app, OpenView &view, std::shared_ptr< STTx const > const &tx, bool retry, ApplyFlags flags, beast::Journal j)
std::shared_ptr< OpenView const > current_
Definition OpenLedger.h:39
beast::Journal const j_
Definition OpenLedger.h:35
std::shared_ptr< OpenView const > current() const
Returns a view to the current open ledger.
std::mutex current_mutex_
Definition OpenLedger.h:38
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
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:111
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:53
void const * data() const noexcept
Definition Serializer.h:59
Map/cache combination.
Definition TaggedCache.h:43
time_point now() const override
Returns the current time, using the server's clock.
Definition TimeKeeper.h:45
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:710
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
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,...
bool isTefFailure(TER x) noexcept
Definition TER.h:647
std::string debugTostr(OrderedTxs const &set)
ApplyResult apply(Application &app, OpenView &view, STTx const &tx, ApplyFlags flags, beast::Journal journal)
Apply a transaction to an OpenView.
Definition apply.cpp:127
bool isTemMalformed(TER x) noexcept
Definition TER.h:641
@ tapRETRY
Definition ApplyView.h:20
@ terQUEUED
Definition TER.h:206
bool isTelLocal(TER x) noexcept
Definition TER.h:635
std::string debugTxstr(std::shared_ptr< STTx const > const &tx)
constexpr std::uint32_t tfInnerBatchTxn
Definition TxFlags.h:42
T str(T... args)
T what(T... args)