rippled
Loading...
Searching...
No Matches
BuildLedger.cpp
1#include <xrpld/app/ledger/BuildLedger.h>
2#include <xrpld/app/ledger/LedgerReplay.h>
3#include <xrpld/app/ledger/OpenLedger.h>
4#include <xrpld/app/main/Application.h>
5
6#include <xrpl/ledger/CanonicalTXSet.h>
7#include <xrpl/ledger/Ledger.h>
8#include <xrpl/protocol/Feature.h>
9#include <xrpl/tx/apply.h>
10
11namespace xrpl {
12
13/* Generic buildLedgerImpl that dispatches to ApplyTxs invocable with signature
14 void(OpenView&, std::shared_ptr<Ledger> const&)
15 It is responsible for adding transactions to the open view to generate the
16 new ledger. It is generic since the mechanics differ for consensus
17 generated ledgers versus replayed ledgers.
18*/
19template <class ApplyTxs>
23 NetClock::time_point closeTime,
24 bool const closeTimeCorrect,
25 NetClock::duration closeResolution,
26 Application& app,
28 ApplyTxs&& applyTxs)
29{
30 auto built = std::make_shared<Ledger>(*parent, closeTime);
31
32 if (built->isFlagLedger())
33 {
34 built->updateNegativeUNL();
35 }
36
37 // Set up to write SHAMap changes to our database,
38 // perform updates, extract changes
39
40 {
41 OpenView accum(&*built);
42 XRPL_ASSERT(!accum.open(), "xrpl::buildLedgerImpl : valid ledger state");
43 applyTxs(accum, built);
44 accum.apply(*built);
45 }
46
47 built->updateSkipList();
48 {
49 // Write the final version of all modified SHAMap
50 // nodes to the node store to preserve the new LCL
51
52 int const asf = built->stateMap().flushDirty(hotACCOUNT_NODE);
53 int const tmf = built->txMap().flushDirty(hotTRANSACTION_NODE);
54 JLOG(j.debug()) << "Flushed " << asf << " accounts and " << tmf << " transaction nodes";
55 }
56 built->unshare();
57
58 // Accept ledger
59 XRPL_ASSERT(
60 built->header().seq < XRP_LEDGER_EARLIEST_FEES || built->read(keylet::fees()),
61 "xrpl::buildLedgerImpl : valid ledger fees");
62 built->setAccepted(closeTime, closeResolution, closeTimeCorrect);
63
64 return built;
65}
66
79 Application& app,
81 CanonicalTXSet& txns,
82 std::set<TxID>& failed,
83 OpenView& view,
85{
86 bool certainRetry = true;
87 std::size_t count = 0;
88
89 // Attempt to apply all of the retriable transactions
90 for (int pass = 0; pass < LEDGER_TOTAL_PASSES; ++pass)
91 {
92 JLOG(j.debug()) << (certainRetry ? "Pass: " : "Final pass: ") << pass << " begins ("
93 << txns.size() << " transactions)";
94 int changes = 0;
95
96 auto it = txns.begin();
97
98 while (it != txns.end())
99 {
100 auto const txid = it->first.getTXID();
101
102 try
103 {
104 if (pass == 0 && built->txExists(txid))
105 {
106 it = txns.erase(it);
107 continue;
108 }
109
110 switch (applyTransaction(app, view, *it->second, certainRetry, tapNONE, j))
111 {
113 it = txns.erase(it);
114 ++changes;
115 break;
116
118 failed.insert(txid);
119 it = txns.erase(it);
120 break;
121
123 ++it;
124 }
125 }
126 catch (std::exception const& ex)
127 {
128 JLOG(j.warn()) << "Transaction " << txid << " throws: " << ex.what();
129 failed.insert(txid);
130 it = txns.erase(it);
131 }
132 }
133
134 JLOG(j.debug()) << (certainRetry ? "Pass: " : "Final pass: ") << pass << " completed ("
135 << changes << " changes)";
136
137 // Accumulate changes.
138 count += changes;
139
140 // A non-retry pass made no changes
141 if ((changes == 0) && !certainRetry)
142 break;
143
144 // Stop retriable passes
145 if ((changes == 0) || (pass >= LEDGER_RETRY_PASSES))
146 certainRetry = false;
147 }
148
149 // If there are any transactions left, we must have
150 // tried them in at least one final pass
151 XRPL_ASSERT(txns.empty() || !certainRetry, "xrpl::applyTransactions : retry transactions");
152 return count;
153}
154
155// Build a ledger from consensus transactions
158 std::shared_ptr<Ledger const> const& parent,
159 NetClock::time_point closeTime,
160 bool const closeTimeCorrect,
161 NetClock::duration closeResolution,
162 Application& app,
163 CanonicalTXSet& txns,
164 std::set<TxID>& failedTxns,
166{
167 JLOG(j.debug()) << "Report: Transaction Set = " << txns.key() << ", close "
168 << closeTime.time_since_epoch().count()
169 << (closeTimeCorrect ? "" : " (incorrect)");
170
171 return buildLedgerImpl(
172 parent,
173 closeTime,
174 closeTimeCorrect,
175 closeResolution,
176 app,
177 j,
178 [&](OpenView& accum, std::shared_ptr<Ledger> const& built) {
179 JLOG(j.debug()) << "Attempting to apply " << txns.size() << " transactions";
180
181 auto const applied = applyTransactions(app, built, txns, failedTxns, accum, j);
182
183 if (!txns.empty() || !failedTxns.empty())
184 {
185 JLOG(j.debug()) << "Applied " << applied << " transactions; " << failedTxns.size()
186 << " failed and " << txns.size() << " will be retried. "
187 << "Total transactions in ledger (including Inner Batch): "
188 << accum.txCount();
189 }
190 else
191 JLOG(j.debug()) << "Applied " << applied << " transactions. "
192 << "Total transactions in ledger (including Inner Batch): "
193 << accum.txCount();
194 });
195}
196
197// Build a ledger by replaying
200 LedgerReplay const& replayData,
201 ApplyFlags applyFlags,
202 Application& app,
204{
205 auto const& replayLedger = replayData.replay();
206
207 JLOG(j.debug()) << "Report: Replay Ledger " << replayLedger->header().hash;
208
209 return buildLedgerImpl(
210 replayData.parent(),
211 replayLedger->header().closeTime,
212 ((replayLedger->header().closeFlags & sLCF_NoConsensusTime) == 0),
213 replayLedger->header().closeTimeResolution,
214 app,
215 j,
216 [&](OpenView& accum, std::shared_ptr<Ledger> const& built) {
217 for (auto& tx : replayData.orderedTxns())
218 applyTransaction(app, accum, *tx.second, false, applyFlags, j);
219 });
220}
221
222} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:40
Stream debug() const
Definition Journal.h:301
Stream warn() const
Definition Journal.h:313
Holds transactions which were deferred to the next pass of consensus.
const_iterator begin() const
const_iterator erase(const_iterator const &it)
const_iterator end() const
uint256 const & key() const
std::shared_ptr< Ledger const > const & replay() const
std::shared_ptr< Ledger const > const & parent() const
Writable ledger view that accumulates state and tx changes.
Definition OpenView.h:45
std::size_t txCount() const
Return the number of tx inserted since creation.
Definition OpenView.cpp:103
bool open() const override
Returns true if this reflects an open ledger.
Definition OpenView.h:166
void apply(TxsRawView &to) const
Apply changes.
Definition OpenView.cpp:109
T empty(T... args)
T insert(T... args)
T is_same_v
Keylet const & fees() noexcept
The (fixed) index of the object containing the ledger fees.
Definition Indexes.cpp:200
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
static constexpr std::uint32_t XRP_LEDGER_EARLIEST_FEES
The XRP Ledger mainnet's earliest ledger with a FeeSettings object.
std::size_t applyTransactions(Application &app, std::shared_ptr< Ledger const > const &built, CanonicalTXSet &txns, std::set< TxID > &failed, OpenView &view, beast::Journal j)
Apply a set of consensus transactions to a ledger.
ApplyTransactionResult applyTransaction(ServiceRegistry &registry, OpenView &view, STTx const &tx, bool retryAssured, ApplyFlags flags, beast::Journal journal)
Transaction application helper.
Definition apply.cpp:207
@ Success
Applied to this ledger.
@ Retry
Should be retried in this ledger.
@ Fail
Should not be retried in this ledger.
@ hotTRANSACTION_NODE
Definition NodeObject.h:16
@ hotACCOUNT_NODE
Definition NodeObject.h:15
static std::uint32_t const sLCF_NoConsensusTime
std::shared_ptr< Ledger > buildLedger(std::shared_ptr< Ledger const > const &parent, NetClock::time_point closeTime, bool const closeTimeCorrect, NetClock::duration closeResolution, Application &app, CanonicalTXSet &txns, std::set< TxID > &failedTxs, beast::Journal j)
Build a new ledger by applying consensus transactions.
ApplyFlags
Definition ApplyView.h:10
@ tapNONE
Definition ApplyView.h:11
std::shared_ptr< Ledger > buildLedgerImpl(std::shared_ptr< Ledger const > const &parent, NetClock::time_point closeTime, bool const closeTimeCorrect, NetClock::duration closeResolution, Application &app, beast::Journal j, ApplyTxs &&applyTxs)
T size(T... args)
T time_since_epoch(T... args)
T what(T... args)