/
applySteps.h
341 lines (280 loc) · 9.6 KB
/
applySteps.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TX_APPLYSTEPS_H_INCLUDED
#define RIPPLE_TX_APPLYSTEPS_H_INCLUDED
#include <ripple/beast/utility/Journal.h>
#include <ripple/ledger/ApplyViewImpl.h>
namespace ripple {
class Application;
class STTx;
class TxQ;
/** Return true if the transaction can claim a fee (tec),
and the `ApplyFlags` do not allow soft failures.
*/
inline bool
isTecClaimHardFail(TER ter, ApplyFlags flags)
{
return isTecClaim(ter) && !(flags & tapRETRY);
}
/** Class describing the consequences to the account
of applying a transaction if the transaction consumes
the maximum XRP allowed.
*/
class TxConsequences
{
public:
/// Describes how the transaction affects subsequent
/// transactions
enum Category {
/// Moves currency around, creates offers, etc.
normal = 0,
/// Affects the ability of subsequent transactions
/// to claim a fee. Eg. `SetRegularKey`
blocker
};
private:
/// Describes how the transaction affects subsequent
/// transactions
bool isBlocker_;
/// Transaction fee
XRPAmount fee_;
/// Does NOT include the fee.
XRPAmount potentialSpend_;
/// SeqProxy of transaction.
SeqProxy seqProx_;
/// Number of sequences consumed.
std::uint32_t sequencesConsumed_;
public:
// Constructor if preflight returns a value other than tesSUCCESS.
// Asserts if tesSUCCESS is passed.
explicit TxConsequences(NotTEC pfresult);
/// Constructor if the STTx has no notable consequences for the TxQ.
explicit TxConsequences(STTx const& tx);
/// Constructor for a blocker.
TxConsequences(STTx const& tx, Category category);
/// Constructor for an STTx that may consume more XRP than the fee.
TxConsequences(STTx const& tx, XRPAmount potentialSpend);
/// Constructor for an STTx that consumes more than the usual sequences.
TxConsequences(STTx const& tx, std::uint32_t sequencesConsumed);
/// Copy constructor
TxConsequences(TxConsequences const&) = default;
/// Copy assignment operator
TxConsequences&
operator=(TxConsequences const&) = default;
/// Move constructor
TxConsequences(TxConsequences&&) = default;
/// Move assignment operator
TxConsequences&
operator=(TxConsequences&&) = default;
/// Fee
XRPAmount
fee() const
{
return fee_;
}
/// Potential Spend
XRPAmount const&
potentialSpend() const
{
return potentialSpend_;
}
/// SeqProxy
SeqProxy
seqProxy() const
{
return seqProx_;
}
/// Sequences consumed
std::uint32_t
sequencesConsumed() const
{
return sequencesConsumed_;
}
/// Returns true if the transaction is a blocker.
bool
isBlocker() const
{
return isBlocker_;
}
// Return the SeqProxy that would follow this.
SeqProxy
followingSeq() const
{
SeqProxy following = seqProx_;
following.advanceBy(sequencesConsumed());
return following;
}
};
/** Describes the results of the `preflight` check
@note All members are const to make it more difficult
to "fake" a result without calling `preflight`.
@see preflight, preclaim, doApply, apply
*/
struct PreflightResult
{
public:
/// From the input - the transaction
STTx const& tx;
/// From the input - the rules
Rules const rules;
/// Consequences of the transaction
TxConsequences const consequences;
/// From the input - the flags
ApplyFlags const flags;
/// From the input - the journal
beast::Journal const j;
/// Intermediate transaction result
NotTEC const ter;
/// Constructor
template <class Context>
PreflightResult(
Context const& ctx_,
std::pair<NotTEC, TxConsequences> const& result)
: tx(ctx_.tx)
, rules(ctx_.rules)
, consequences(result.second)
, flags(ctx_.flags)
, j(ctx_.j)
, ter(result.first)
{
}
PreflightResult(PreflightResult const&) = default;
/// Deleted copy assignment operator
PreflightResult&
operator=(PreflightResult const&) = delete;
};
/** Describes the results of the `preclaim` check
@note All members are const to make it more difficult
to "fake" a result without calling `preclaim`.
@see preflight, preclaim, doApply, apply
*/
struct PreclaimResult
{
public:
/// From the input - the ledger view
ReadView const& view;
/// From the input - the transaction
STTx const& tx;
/// From the input - the flags
ApplyFlags const flags;
/// From the input - the journal
beast::Journal const j;
/// Intermediate transaction result
TER const ter;
/// Success flag - whether the transaction is likely to
/// claim a fee
bool const likelyToClaimFee;
/// Constructor
template <class Context>
PreclaimResult(Context const& ctx_, TER ter_)
: view(ctx_.view)
, tx(ctx_.tx)
, flags(ctx_.flags)
, j(ctx_.j)
, ter(ter_)
, likelyToClaimFee(ter == tesSUCCESS || isTecClaimHardFail(ter, flags))
{
}
PreclaimResult(PreclaimResult const&) = default;
/// Deleted copy assignment operator
PreclaimResult&
operator=(PreclaimResult const&) = delete;
};
/** Gate a transaction based on static information.
The transaction is checked against all possible
validity constraints that do not require a ledger.
@param app The current running `Application`.
@param rules The `Rules` in effect at the time of the check.
@param tx The transaction to be checked.
@param flags `ApplyFlags` describing processing options.
@param j A journal.
@see PreflightResult, preclaim, doApply, apply
@return A `PreflightResult` object containing, among
other things, the `TER` code.
*/
PreflightResult
preflight(
Application& app,
Rules const& rules,
STTx const& tx,
ApplyFlags flags,
beast::Journal j);
/** Gate a transaction based on static ledger information.
The transaction is checked against all possible
validity constraints that DO require a ledger.
If preclaim succeeds, then the transaction is very
likely to claim a fee. This will determine if the
transaction is safe to relay without being applied
to the open ledger.
"Succeeds" in this case is defined as returning a
`tes` or `tec`, since both lead to claiming a fee.
@pre The transaction has been checked
and validated using `preflight`
@param preflightResult The result of a previous
call to `preflight` for the transaction.
@param app The current running `Application`.
@param view The open ledger that the transaction
will attempt to be applied to.
@see PreclaimResult, preflight, doApply, apply
@return A `PreclaimResult` object containing, among
other things the `TER` code and the base fee value for
this transaction.
*/
PreclaimResult
preclaim(
PreflightResult const& preflightResult,
Application& app,
OpenView const& view);
/** Compute only the expected base fee for a transaction.
Base fees are transaction specific, so any calculation
needing them must get the base fee for each transaction.
No validation is done or implied by this function.
Caller is responsible for handling any exceptions.
Since none should be thrown, that will usually
mean terminating.
@param view The current open ledger.
@param tx The transaction to be checked.
@return The base fee.
*/
XRPAmount
calculateBaseFee(ReadView const& view, STTx const& tx);
/** Return the minimum fee that an "ordinary" transaction would pay.
When computing the FeeLevel for a transaction the TxQ sometimes needs
the know what an "ordinary" or reference transaction would be required
to pay.
@param view The current open ledger.
@param tx The transaction so the correct multisigner count is used.
@return The base fee in XRPAmount.
*/
XRPAmount
calculateDefaultBaseFee(ReadView const& view, STTx const& tx);
/** Apply a prechecked transaction to an OpenView.
@pre The transaction has been checked
and validated using `preflight` and `preclaim`
@param preclaimResult The result of a previous
call to `preclaim` for the transaction.
@param app The current running `Application`.
@param view The open ledger that the transaction
will attempt to be applied to.
@see preflight, preclaim, apply
@return A pair with the `TER` and a `bool` indicating
whether or not the transaction was applied.
*/
std::pair<TER, bool>
doApply(PreclaimResult const& preclaimResult, Application& app, OpenView& view);
} // namespace ripple
#endif