rippled
Loading...
Searching...
No Matches
PayChan.cpp
1#include <xrpld/app/tx/detail/PayChan.h>
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/chrono.h>
5#include <xrpl/ledger/ApplyView.h>
6#include <xrpl/ledger/CredentialHelpers.h>
7#include <xrpl/ledger/View.h>
8#include <xrpl/protocol/Feature.h>
9#include <xrpl/protocol/Indexes.h>
10#include <xrpl/protocol/PayChan.h>
11#include <xrpl/protocol/PublicKey.h>
12#include <xrpl/protocol/TxFlags.h>
13#include <xrpl/protocol/XRPAmount.h>
14#include <xrpl/protocol/digest.h>
15
16namespace ripple {
17
18/*
19 PaymentChannel
20
21 Payment channels permit off-ledger checkpoints of XRP payments flowing
22 in a single direction. A channel sequesters the owner's XRP in its own
23 ledger entry. The owner can authorize the recipient to claim up to a
24 given balance by giving the receiver a signed message (off-ledger). The
25 recipient can use this signed message to claim any unpaid balance while
26 the channel remains open. The owner can top off the line as needed. If
27 the channel has not paid out all its funds, the owner must wait out a
28 delay to close the channel to give the recipient a chance to supply any
29 claims. The recipient can close the channel at any time. Any transaction
30 that touches the channel after the expiration time will close the
31 channel. The total amount paid increases monotonically as newer claims
32 are issued. When the channel is closed any remaining balance is returned
33 to the owner. Channels are intended to permit intermittent off-ledger
34 settlement of ILP trust lines as balances get substantial. For
35 bidirectional channels, a payment channel can be used in each direction.
36
37 PaymentChannelCreate
38
39 Create a unidirectional channel. The parameters are:
40 Destination
41 The recipient at the end of the channel.
42 Amount
43 The amount of XRP to deposit in the channel immediately.
44 SettleDelay
45 The amount of time everyone but the recipient must wait for a
46 superior claim.
47 PublicKey
48 The key that will sign claims against the channel.
49 CancelAfter (optional)
50 Any channel transaction that touches this channel after the
51 `CancelAfter` time will close it.
52 DestinationTag (optional)
53 Destination tags allow the different accounts inside of a Hosted
54 Wallet to be mapped back onto the Ripple ledger. The destination tag
55 tells the server to which account in the Hosted Wallet the funds are
56 intended to go to. Required if the destination has lsfRequireDestTag
57 set.
58 SourceTag (optional)
59 Source tags allow the different accounts inside of a Hosted Wallet
60 to be mapped back onto the Ripple ledger. Source tags are similar to
61 destination tags but are for the channel owner to identify their own
62 transactions.
63
64 PaymentChannelFund
65
66 Add additional funds to the payment channel. Only the channel owner may
67 use this transaction. The parameters are:
68 Channel
69 The 256-bit ID of the channel.
70 Amount
71 The amount of XRP to add.
72 Expiration (optional)
73 Time the channel closes. The transaction will fail if the expiration
74 times does not satisfy the SettleDelay constraints.
75
76 PaymentChannelClaim
77
78 Place a claim against an existing channel. The parameters are:
79 Channel
80 The 256-bit ID of the channel.
81 Balance (optional)
82 The total amount of XRP delivered after this claim is processed
83 (optional, not needed if just closing). Amount (optional) The amount of XRP
84 the signature is for (not needed if equal to Balance or just closing the
85 line). Signature (optional) Authorization for the balance above, signed by
86 the owner (optional, not needed if closing or owner is performing the
87 transaction). The signature if for the following message: CLM\0 followed by
88 the 256-bit channel ID, and a 64-bit integer drops. PublicKey (optional) The
89 public key that made the signature (optional, required if a signature is
90 present) Flags tfClose Request that the channel be closed tfRenew Request
91 that the channel's expiration be reset. Only the owner may renew a channel.
92
93*/
94
95//------------------------------------------------------------------------------
96
97static TER
99 std::shared_ptr<SLE> const& slep,
100 ApplyView& view,
101 uint256 const& key,
103{
104 AccountID const src = (*slep)[sfAccount];
105 // Remove PayChan from owner directory
106 {
107 auto const page = (*slep)[sfOwnerNode];
108 if (!view.dirRemove(keylet::ownerDir(src), page, key, true))
109 {
110 // LCOV_EXCL_START
111 JLOG(j.fatal())
112 << "Could not remove paychan from src owner directory";
113 return tefBAD_LEDGER;
114 // LCOV_EXCL_STOP
115 }
116 }
117
118 // Remove PayChan from recipient's owner directory, if present.
119 if (auto const page = (*slep)[~sfDestinationNode])
120 {
121 auto const dst = (*slep)[sfDestination];
122 if (!view.dirRemove(keylet::ownerDir(dst), *page, key, true))
123 {
124 // LCOV_EXCL_START
125 JLOG(j.fatal())
126 << "Could not remove paychan from dst owner directory";
127 return tefBAD_LEDGER;
128 // LCOV_EXCL_STOP
129 }
130 }
131
132 // Transfer amount back to owner, decrement owner count
133 auto const sle = view.peek(keylet::account(src));
134 if (!sle)
135 return tefINTERNAL; // LCOV_EXCL_LINE
136
137 XRPL_ASSERT(
138 (*slep)[sfAmount] >= (*slep)[sfBalance],
139 "ripple::closeChannel : minimum channel amount");
140 (*sle)[sfBalance] =
141 (*sle)[sfBalance] + (*slep)[sfAmount] - (*slep)[sfBalance];
142 adjustOwnerCount(view, sle, -1, j);
143 view.update(sle);
144
145 // Remove PayChan from ledger
146 view.erase(slep);
147 return tesSUCCESS;
148}
149
150//------------------------------------------------------------------------------
151
152TxConsequences
154{
155 return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()};
156}
157
158NotTEC
160{
161 if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero))
162 return temBAD_AMOUNT;
163
164 if (ctx.tx[sfAccount] == ctx.tx[sfDestination])
165 return temDST_IS_SRC;
166
167 if (!publicKeyType(ctx.tx[sfPublicKey]))
168 return temMALFORMED;
169
170 return tesSUCCESS;
171}
172
173TER
175{
176 auto const account = ctx.tx[sfAccount];
177 auto const sle = ctx.view.read(keylet::account(account));
178 if (!sle)
179 return terNO_ACCOUNT;
180
181 // Check reserve and funds availability
182 {
183 auto const balance = (*sle)[sfBalance];
184 auto const reserve =
185 ctx.view.fees().accountReserve((*sle)[sfOwnerCount] + 1);
186
187 if (balance < reserve)
189
190 if (balance < reserve + ctx.tx[sfAmount])
191 return tecUNFUNDED;
192 }
193
194 auto const dst = ctx.tx[sfDestination];
195
196 {
197 // Check destination account
198 auto const sled = ctx.view.read(keylet::account(dst));
199 if (!sled)
200 return tecNO_DST;
201
202 auto const flags = sled->getFlags();
203
204 // Check if they have disallowed incoming payment channels
205 if (flags & lsfDisallowIncomingPayChan)
206 return tecNO_PERMISSION;
207
208 if ((flags & lsfRequireDestTag) && !ctx.tx[~sfDestinationTag])
209 return tecDST_TAG_NEEDED;
210
211 // Pseudo-accounts cannot receive payment channels, other than native
212 // to their underlying ledger object - implemented in their respective
213 // transaction types. Note, this is not amendment-gated because all
214 // writes to pseudo-account discriminator fields **are** amendment
215 // gated, hence the behaviour of this check will always match the
216 // currently active amendments.
217 if (isPseudoAccount(sled))
218 return tecNO_PERMISSION;
219 }
220
221 return tesSUCCESS;
222}
223
224TER
226{
227 auto const account = ctx_.tx[sfAccount];
228 auto const sle = ctx_.view().peek(keylet::account(account));
229 if (!sle)
230 return tefINTERNAL; // LCOV_EXCL_LINE
231
232 if (ctx_.view().rules().enabled(fixPayChanCancelAfter))
233 {
234 auto const closeTime = ctx_.view().info().parentCloseTime;
235 if (ctx_.tx[~sfCancelAfter] && after(closeTime, ctx_.tx[sfCancelAfter]))
236 return tecEXPIRED;
237 }
238
239 auto const dst = ctx_.tx[sfDestination];
240
241 // Create PayChan in ledger.
242 //
243 // Note that we we use the value from the sequence or ticket as the
244 // payChan sequence. For more explanation see comments in SeqProxy.h.
245 Keylet const payChanKeylet =
246 keylet::payChan(account, dst, ctx_.tx.getSeqValue());
247 auto const slep = std::make_shared<SLE>(payChanKeylet);
248
249 // Funds held in this channel
250 (*slep)[sfAmount] = ctx_.tx[sfAmount];
251 // Amount channel has already paid
252 (*slep)[sfBalance] = ctx_.tx[sfAmount].zeroed();
253 (*slep)[sfAccount] = account;
254 (*slep)[sfDestination] = dst;
255 (*slep)[sfSettleDelay] = ctx_.tx[sfSettleDelay];
256 (*slep)[sfPublicKey] = ctx_.tx[sfPublicKey];
257 (*slep)[~sfCancelAfter] = ctx_.tx[~sfCancelAfter];
258 (*slep)[~sfSourceTag] = ctx_.tx[~sfSourceTag];
259 (*slep)[~sfDestinationTag] = ctx_.tx[~sfDestinationTag];
260 if (ctx_.view().rules().enabled(fixIncludeKeyletFields))
261 {
262 (*slep)[sfSequence] = ctx_.tx.getSeqValue();
263 }
264
265 ctx_.view().insert(slep);
266
267 // Add PayChan to owner directory
268 {
269 auto const page = ctx_.view().dirInsert(
270 keylet::ownerDir(account),
271 payChanKeylet,
272 describeOwnerDir(account));
273 if (!page)
274 return tecDIR_FULL; // LCOV_EXCL_LINE
275 (*slep)[sfOwnerNode] = *page;
276 }
277
278 // Add PayChan to the recipient's owner directory
279 {
280 auto const page = ctx_.view().dirInsert(
281 keylet::ownerDir(dst), payChanKeylet, describeOwnerDir(dst));
282 if (!page)
283 return tecDIR_FULL; // LCOV_EXCL_LINE
284 (*slep)[sfDestinationNode] = *page;
285 }
286
287 // Deduct owner's balance, increment owner count
288 (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
290 ctx_.view().update(sle);
291
292 return tesSUCCESS;
293}
294
295//------------------------------------------------------------------------------
296
299{
300 return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()};
301}
302
303NotTEC
305{
306 if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero))
307 return temBAD_AMOUNT;
308
309 return tesSUCCESS;
310}
311
312TER
314{
315 Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]);
316 auto const slep = ctx_.view().peek(k);
317 if (!slep)
318 return tecNO_ENTRY;
319
320 AccountID const src = (*slep)[sfAccount];
321 auto const txAccount = ctx_.tx[sfAccount];
322 auto const expiration = (*slep)[~sfExpiration];
323
324 {
325 auto const cancelAfter = (*slep)[~sfCancelAfter];
326 auto const closeTime =
328 if ((cancelAfter && closeTime >= *cancelAfter) ||
329 (expiration && closeTime >= *expiration))
330 return closeChannel(
331 slep, ctx_.view(), k.key, ctx_.app.journal("View"));
332 }
333
334 if (src != txAccount)
335 // only the owner can add funds or extend
336 return tecNO_PERMISSION;
337
338 if (auto extend = ctx_.tx[~sfExpiration])
339 {
340 auto minExpiration =
342 (*slep)[sfSettleDelay];
343 if (expiration && *expiration < minExpiration)
344 minExpiration = *expiration;
345
346 if (*extend < minExpiration)
347 return temBAD_EXPIRATION;
348 (*slep)[~sfExpiration] = *extend;
349 ctx_.view().update(slep);
350 }
351
352 auto const sle = ctx_.view().peek(keylet::account(txAccount));
353 if (!sle)
354 return tefINTERNAL; // LCOV_EXCL_LINE
355
356 {
357 // Check reserve and funds availability
358 auto const balance = (*sle)[sfBalance];
359 auto const reserve =
360 ctx_.view().fees().accountReserve((*sle)[sfOwnerCount]);
361
362 if (balance < reserve)
364
365 if (balance < reserve + ctx_.tx[sfAmount])
366 return tecUNFUNDED;
367 }
368
369 // do not allow adding funds if dst does not exist
370 if (AccountID const dst = (*slep)[sfDestination];
371 !ctx_.view().read(keylet::account(dst)))
372 {
373 return tecNO_DST;
374 }
375
376 (*slep)[sfAmount] = (*slep)[sfAmount] + ctx_.tx[sfAmount];
377 ctx_.view().update(slep);
378
379 (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
380 ctx_.view().update(sle);
381
382 return tesSUCCESS;
383}
384
385//------------------------------------------------------------------------------
386
387bool
389{
390 return !ctx.tx.isFieldPresent(sfCredentialIDs) ||
391 ctx.rules.enabled(featureCredentials);
392}
393
399
400NotTEC
402{
403 auto const bal = ctx.tx[~sfBalance];
404 if (bal && (!isXRP(*bal) || *bal <= beast::zero))
405 return temBAD_AMOUNT;
406
407 auto const amt = ctx.tx[~sfAmount];
408 if (amt && (!isXRP(*amt) || *amt <= beast::zero))
409 return temBAD_AMOUNT;
410
411 if (bal && amt && *bal > *amt)
412 return temBAD_AMOUNT;
413
414 {
415 auto const flags = ctx.tx.getFlags();
416
417 if ((flags & tfClose) && (flags & tfRenew))
418 return temMALFORMED;
419 }
420
421 if (auto const sig = ctx.tx[~sfSignature])
422 {
423 if (!(ctx.tx[~sfPublicKey] && bal))
424 return temMALFORMED;
425
426 // Check the signature
427 // The signature isn't needed if txAccount == src, but if it's
428 // present, check it
429
430 auto const reqBalance = bal->xrp();
431 auto const authAmt = amt ? amt->xrp() : reqBalance;
432
433 if (reqBalance > authAmt)
434 return temBAD_AMOUNT;
435
436 Keylet const k(ltPAYCHAN, ctx.tx[sfChannel]);
437 if (!publicKeyType(ctx.tx[sfPublicKey]))
438 return temMALFORMED;
439
440 PublicKey const pk(ctx.tx[sfPublicKey]);
441 Serializer msg;
442 serializePayChanAuthorization(msg, k.key, authAmt);
443 if (!verify(pk, msg.slice(), *sig, /*canonical*/ true))
444 return temBAD_SIGNATURE;
445 }
446
447 if (auto const err = credentials::checkFields(ctx.tx, ctx.j);
448 !isTesSuccess(err))
449 return err;
450
451 return tesSUCCESS;
452}
453
454TER
456{
457 if (!ctx.view.rules().enabled(featureCredentials))
458 return Transactor::preclaim(ctx);
459
460 if (auto const err =
461 credentials::valid(ctx.tx, ctx.view, ctx.tx[sfAccount], ctx.j);
462 !isTesSuccess(err))
463 return err;
464
465 return tesSUCCESS;
466}
467
468TER
470{
471 Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]);
472 auto const slep = ctx_.view().peek(k);
473 if (!slep)
474 return tecNO_TARGET;
475
476 AccountID const src = (*slep)[sfAccount];
477 AccountID const dst = (*slep)[sfDestination];
478 AccountID const txAccount = ctx_.tx[sfAccount];
479
480 auto const curExpiration = (*slep)[~sfExpiration];
481 {
482 auto const cancelAfter = (*slep)[~sfCancelAfter];
483 auto const closeTime =
485 if ((cancelAfter && closeTime >= *cancelAfter) ||
486 (curExpiration && closeTime >= *curExpiration))
487 return closeChannel(
488 slep, ctx_.view(), k.key, ctx_.app.journal("View"));
489 }
490
491 if (txAccount != src && txAccount != dst)
492 return tecNO_PERMISSION;
493
494 if (ctx_.tx[~sfBalance])
495 {
496 auto const chanBalance = slep->getFieldAmount(sfBalance).xrp();
497 auto const chanFunds = slep->getFieldAmount(sfAmount).xrp();
498 auto const reqBalance = ctx_.tx[sfBalance].xrp();
499
500 if (txAccount == dst && !ctx_.tx[~sfSignature])
501 return temBAD_SIGNATURE;
502
503 if (ctx_.tx[~sfSignature])
504 {
505 PublicKey const pk((*slep)[sfPublicKey]);
506 if (ctx_.tx[sfPublicKey] != pk)
507 return temBAD_SIGNER;
508 }
509
510 if (reqBalance > chanFunds)
511 return tecUNFUNDED_PAYMENT;
512
513 if (reqBalance <= chanBalance)
514 // nothing requested
515 return tecUNFUNDED_PAYMENT;
516
517 auto const sled = ctx_.view().peek(keylet::account(dst));
518 if (!sled)
519 return tecNO_DST;
520
521 if (auto err = verifyDepositPreauth(
522 ctx_.tx, ctx_.view(), txAccount, dst, sled, ctx_.journal);
523 !isTesSuccess(err))
524 return err;
525
526 (*slep)[sfBalance] = ctx_.tx[sfBalance];
527 XRPAmount const reqDelta = reqBalance - chanBalance;
528 XRPL_ASSERT(
529 reqDelta >= beast::zero,
530 "ripple::PayChanClaim::doApply : minimum balance delta");
531 (*sled)[sfBalance] = (*sled)[sfBalance] + reqDelta;
532 ctx_.view().update(sled);
533 ctx_.view().update(slep);
534 }
535
536 if (ctx_.tx.getFlags() & tfRenew)
537 {
538 if (src != txAccount)
539 return tecNO_PERMISSION;
540 (*slep)[~sfExpiration] = std::nullopt;
541 ctx_.view().update(slep);
542 }
543
544 if (ctx_.tx.getFlags() & tfClose)
545 {
546 // Channel will close immediately if dry or the receiver closes
547 if (dst == txAccount || (*slep)[sfBalance] == (*slep)[sfAmount])
548 return closeChannel(
549 slep, ctx_.view(), k.key, ctx_.app.journal("View"));
550
551 auto const settleExpiration =
553 (*slep)[sfSettleDelay];
554
555 if (!curExpiration || *curExpiration > settleExpiration)
556 {
557 (*slep)[~sfExpiration] = settleExpiration;
558 ctx_.view().update(slep);
559 }
560 }
561
562 return tesSUCCESS;
563}
564
565} // namespace ripple
A generic endpoint for log messages.
Definition Journal.h:41
Stream fatal() const
Definition Journal.h:333
virtual beast::Journal journal(std::string const &name)=0
ApplyView & view()
Application & app
beast::Journal const journal
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:124
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Insert an entry to a directory.
Definition ApplyView.h:300
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
virtual void erase(std::shared_ptr< SLE > const &sle)=0
Remove a peeked SLE.
static NotTEC preflight(PreflightContext const &ctx)
Definition PayChan.cpp:401
static TER preclaim(PreclaimContext const &ctx)
Definition PayChan.cpp:455
static std::uint32_t getFlagsMask(PreflightContext const &ctx)
Definition PayChan.cpp:395
static bool checkExtraFeatures(PreflightContext const &ctx)
Definition PayChan.cpp:388
TER doApply() override
Definition PayChan.cpp:469
static NotTEC preflight(PreflightContext const &ctx)
Definition PayChan.cpp:159
TER doApply() override
Definition PayChan.cpp:225
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
Definition PayChan.cpp:153
static TER preclaim(PreclaimContext const &ctx)
Definition PayChan.cpp:174
TER doApply() override
Definition PayChan.cpp:313
static NotTEC preflight(PreflightContext const &ctx)
Definition PayChan.cpp:304
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
Definition PayChan.cpp:298
A public key.
Definition PublicKey.h:43
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
virtual LedgerInfo const & info() const =0
Returns information about the ledger.
virtual Rules const & rules() const =0
Returns the tx processing rules.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:111
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:465
std::uint32_t getFlags() const
Definition STObject.cpp:518
std::uint32_t getSeqValue() const
Returns the first non-zero value of (Sequence, TicketSequence).
Definition STTx.cpp:212
Slice slice() const noexcept
Definition Serializer.h:47
static TER preclaim(PreclaimContext const &ctx)
Definition Transactor.h:214
ApplyContext & ctx_
Definition Transactor.h:124
Class describing the consequences to the account of applying a transaction if the transaction consume...
Definition applySteps.h:39
T is_same_v
NotTEC checkFields(STTx const &tx, beast::Journal j)
TER valid(STTx const &tx, ReadView const &view, AccountID const &src, beast::Journal j)
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:165
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:355
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Definition Indexes.cpp:376
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
static TER closeChannel(std::shared_ptr< SLE > const &slep, ApplyView &view, uint256 const &key, beast::Journal j)
Definition PayChan.cpp:98
bool isXRP(AccountID const &c)
Definition AccountID.h:71
constexpr std::uint32_t tfRenew
Definition TxFlags.h:115
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical=true) noexcept
Verify a signature on a message.
@ lsfRequireDestTag
@ lsfDisallowIncomingPayChan
void adjustOwnerCount(ApplyView &view, std::shared_ptr< SLE > const &sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
Definition View.cpp:1013
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition View.cpp:1031
TER verifyDepositPreauth(STTx const &tx, ApplyView &view, AccountID const &src, AccountID const &dst, std::shared_ptr< SLE > const &sleDst, beast::Journal j)
void serializePayChanAuthorization(Serializer &msg, uint256 const &key, XRPAmount const &amt)
@ tefBAD_LEDGER
Definition TER.h:151
@ tefINTERNAL
Definition TER.h:154
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
@ tecNO_ENTRY
Definition TER.h:288
@ tecNO_DST
Definition TER.h:272
@ tecUNFUNDED
Definition TER.h:277
@ tecNO_TARGET
Definition TER.h:286
@ tecDIR_FULL
Definition TER.h:269
@ tecNO_PERMISSION
Definition TER.h:287
@ tecDST_TAG_NEEDED
Definition TER.h:291
@ tecUNFUNDED_PAYMENT
Definition TER.h:267
@ tecINSUFFICIENT_RESERVE
Definition TER.h:289
@ tecEXPIRED
Definition TER.h:296
@ tesSUCCESS
Definition TER.h:226
bool isTesSuccess(TER x) noexcept
Definition TER.h:659
constexpr std::uint32_t tfClose
Definition TxFlags.h:116
constexpr std::uint32_t tfPayChanClaimMask
Definition TxFlags.h:117
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition View.cpp:3247
@ terNO_ACCOUNT
Definition TER.h:198
TERSubset< CanCvtToTER > TER
Definition TER.h:630
bool isPseudoAccount(std::shared_ptr< SLE const > sleAcct)
Definition View.cpp:1099
@ temBAD_AMOUNT
Definition TER.h:70
@ temBAD_SIGNER
Definition TER.h:96
@ temMALFORMED
Definition TER.h:68
@ temBAD_EXPIRATION
Definition TER.h:72
@ temDST_IS_SRC
Definition TER.h:89
@ temBAD_SIGNATURE
Definition TER.h:86
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:20
uint256 key
Definition Keylet.h:21
NetClock::time_point parentCloseTime
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:61
ReadView const & view
Definition Transactor.h:64
beast::Journal const j
Definition Transactor.h:69
State information when preflighting a tx.
Definition Transactor.h:16
beast::Journal const j
Definition Transactor.h:23
T time_since_epoch(T... args)