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 xrpl {
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{
100 AccountID const src = (*slep)[sfAccount];
101 // Remove PayChan from owner directory
102 {
103 auto const page = (*slep)[sfOwnerNode];
104 if (!view.dirRemove(keylet::ownerDir(src), page, key, true))
105 {
106 // LCOV_EXCL_START
107 JLOG(j.fatal()) << "Could not remove paychan from src owner directory";
108 return tefBAD_LEDGER;
109 // LCOV_EXCL_STOP
110 }
111 }
112
113 // Remove PayChan from recipient's owner directory, if present.
114 if (auto const page = (*slep)[~sfDestinationNode])
115 {
116 auto const dst = (*slep)[sfDestination];
117 if (!view.dirRemove(keylet::ownerDir(dst), *page, key, true))
118 {
119 // LCOV_EXCL_START
120 JLOG(j.fatal()) << "Could not remove paychan from dst owner directory";
121 return tefBAD_LEDGER;
122 // LCOV_EXCL_STOP
123 }
124 }
125
126 // Transfer amount back to owner, decrement owner count
127 auto const sle = view.peek(keylet::account(src));
128 if (!sle)
129 return tefINTERNAL; // LCOV_EXCL_LINE
130
131 XRPL_ASSERT((*slep)[sfAmount] >= (*slep)[sfBalance], "xrpl::closeChannel : minimum channel amount");
132 (*sle)[sfBalance] = (*sle)[sfBalance] + (*slep)[sfAmount] - (*slep)[sfBalance];
133 adjustOwnerCount(view, sle, -1, j);
134 view.update(sle);
135
136 // Remove PayChan from ledger
137 view.erase(slep);
138 return tesSUCCESS;
139}
140
141//------------------------------------------------------------------------------
142
143TxConsequences
145{
146 return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()};
147}
148
149NotTEC
151{
152 if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero))
153 return temBAD_AMOUNT;
154
155 if (ctx.tx[sfAccount] == ctx.tx[sfDestination])
156 return temDST_IS_SRC;
157
158 if (!publicKeyType(ctx.tx[sfPublicKey]))
159 return temMALFORMED;
160
161 return tesSUCCESS;
162}
163
164TER
166{
167 auto const account = ctx.tx[sfAccount];
168 auto const sle = ctx.view.read(keylet::account(account));
169 if (!sle)
170 return terNO_ACCOUNT;
171
172 // Check reserve and funds availability
173 {
174 auto const balance = (*sle)[sfBalance];
175 auto const reserve = ctx.view.fees().accountReserve((*sle)[sfOwnerCount] + 1);
176
177 if (balance < reserve)
179
180 if (balance < reserve + ctx.tx[sfAmount])
181 return tecUNFUNDED;
182 }
183
184 auto const dst = ctx.tx[sfDestination];
185
186 {
187 // Check destination account
188 auto const sled = ctx.view.read(keylet::account(dst));
189 if (!sled)
190 return tecNO_DST;
191
192 auto const flags = sled->getFlags();
193
194 // Check if they have disallowed incoming payment channels
195 if (flags & lsfDisallowIncomingPayChan)
196 return tecNO_PERMISSION;
197
198 if ((flags & lsfRequireDestTag) && !ctx.tx[~sfDestinationTag])
199 return tecDST_TAG_NEEDED;
200
201 // Pseudo-accounts cannot receive payment channels, other than native
202 // to their underlying ledger object - implemented in their respective
203 // transaction types. Note, this is not amendment-gated because all
204 // writes to pseudo-account discriminator fields **are** amendment
205 // gated, hence the behaviour of this check will always match the
206 // currently active amendments.
207 if (isPseudoAccount(sled))
208 return tecNO_PERMISSION;
209 }
210
211 return tesSUCCESS;
212}
213
214TER
216{
217 auto const account = ctx_.tx[sfAccount];
218 auto const sle = ctx_.view().peek(keylet::account(account));
219 if (!sle)
220 return tefINTERNAL; // LCOV_EXCL_LINE
221
222 if (ctx_.view().rules().enabled(fixPayChanCancelAfter))
223 {
224 auto const closeTime = ctx_.view().header().parentCloseTime;
225 if (ctx_.tx[~sfCancelAfter] && after(closeTime, ctx_.tx[sfCancelAfter]))
226 return tecEXPIRED;
227 }
228
229 auto const dst = ctx_.tx[sfDestination];
230
231 // Create PayChan in ledger.
232 //
233 // Note that we we use the value from the sequence or ticket as the
234 // payChan sequence. For more explanation see comments in SeqProxy.h.
235 Keylet const payChanKeylet = keylet::payChan(account, dst, ctx_.tx.getSeqValue());
236 auto const slep = std::make_shared<SLE>(payChanKeylet);
237
238 // Funds held in this channel
239 (*slep)[sfAmount] = ctx_.tx[sfAmount];
240 // Amount channel has already paid
241 (*slep)[sfBalance] = ctx_.tx[sfAmount].zeroed();
242 (*slep)[sfAccount] = account;
243 (*slep)[sfDestination] = dst;
244 (*slep)[sfSettleDelay] = ctx_.tx[sfSettleDelay];
245 (*slep)[sfPublicKey] = ctx_.tx[sfPublicKey];
246 (*slep)[~sfCancelAfter] = ctx_.tx[~sfCancelAfter];
247 (*slep)[~sfSourceTag] = ctx_.tx[~sfSourceTag];
248 (*slep)[~sfDestinationTag] = ctx_.tx[~sfDestinationTag];
249 if (ctx_.view().rules().enabled(fixIncludeKeyletFields))
250 {
251 (*slep)[sfSequence] = ctx_.tx.getSeqValue();
252 }
253
254 ctx_.view().insert(slep);
255
256 // Add PayChan to owner directory
257 {
258 auto const page = ctx_.view().dirInsert(keylet::ownerDir(account), payChanKeylet, describeOwnerDir(account));
259 if (!page)
260 return tecDIR_FULL; // LCOV_EXCL_LINE
261 (*slep)[sfOwnerNode] = *page;
262 }
263
264 // Add PayChan to the recipient's owner directory
265 {
266 auto const page = ctx_.view().dirInsert(keylet::ownerDir(dst), payChanKeylet, describeOwnerDir(dst));
267 if (!page)
268 return tecDIR_FULL; // LCOV_EXCL_LINE
269 (*slep)[sfDestinationNode] = *page;
270 }
271
272 // Deduct owner's balance, increment owner count
273 (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
275 ctx_.view().update(sle);
276
277 return tesSUCCESS;
278}
279
280//------------------------------------------------------------------------------
281
284{
285 return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()};
286}
287
288NotTEC
290{
291 if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero))
292 return temBAD_AMOUNT;
293
294 return tesSUCCESS;
295}
296
297TER
299{
300 Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]);
301 auto const slep = ctx_.view().peek(k);
302 if (!slep)
303 return tecNO_ENTRY;
304
305 AccountID const src = (*slep)[sfAccount];
306 auto const txAccount = ctx_.tx[sfAccount];
307 auto const expiration = (*slep)[~sfExpiration];
308
309 {
310 auto const cancelAfter = (*slep)[~sfCancelAfter];
311 auto const closeTime = ctx_.view().header().parentCloseTime.time_since_epoch().count();
312 if ((cancelAfter && closeTime >= *cancelAfter) || (expiration && closeTime >= *expiration))
313 return closeChannel(slep, ctx_.view(), k.key, ctx_.app.journal("View"));
314 }
315
316 if (src != txAccount)
317 // only the owner can add funds or extend
318 return tecNO_PERMISSION;
319
320 if (auto extend = ctx_.tx[~sfExpiration])
321 {
322 auto minExpiration = ctx_.view().header().parentCloseTime.time_since_epoch().count() + (*slep)[sfSettleDelay];
323 if (expiration && *expiration < minExpiration)
324 minExpiration = *expiration;
325
326 if (*extend < minExpiration)
327 return temBAD_EXPIRATION;
328 (*slep)[~sfExpiration] = *extend;
329 ctx_.view().update(slep);
330 }
331
332 auto const sle = ctx_.view().peek(keylet::account(txAccount));
333 if (!sle)
334 return tefINTERNAL; // LCOV_EXCL_LINE
335
336 {
337 // Check reserve and funds availability
338 auto const balance = (*sle)[sfBalance];
339 auto const reserve = ctx_.view().fees().accountReserve((*sle)[sfOwnerCount]);
340
341 if (balance < reserve)
343
344 if (balance < reserve + ctx_.tx[sfAmount])
345 return tecUNFUNDED;
346 }
347
348 // do not allow adding funds if dst does not exist
349 if (AccountID const dst = (*slep)[sfDestination]; !ctx_.view().read(keylet::account(dst)))
350 {
351 return tecNO_DST;
352 }
353
354 (*slep)[sfAmount] = (*slep)[sfAmount] + ctx_.tx[sfAmount];
355 ctx_.view().update(slep);
356
357 (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
358 ctx_.view().update(sle);
359
360 return tesSUCCESS;
361}
362
363//------------------------------------------------------------------------------
364
365bool
367{
368 return !ctx.tx.isFieldPresent(sfCredentialIDs) || ctx.rules.enabled(featureCredentials);
369}
370
376
377NotTEC
379{
380 auto const bal = ctx.tx[~sfBalance];
381 if (bal && (!isXRP(*bal) || *bal <= beast::zero))
382 return temBAD_AMOUNT;
383
384 auto const amt = ctx.tx[~sfAmount];
385 if (amt && (!isXRP(*amt) || *amt <= beast::zero))
386 return temBAD_AMOUNT;
387
388 if (bal && amt && *bal > *amt)
389 return temBAD_AMOUNT;
390
391 {
392 auto const flags = ctx.tx.getFlags();
393
394 if ((flags & tfClose) && (flags & tfRenew))
395 return temMALFORMED;
396 }
397
398 if (auto const sig = ctx.tx[~sfSignature])
399 {
400 if (!(ctx.tx[~sfPublicKey] && bal))
401 return temMALFORMED;
402
403 // Check the signature
404 // The signature isn't needed if txAccount == src, but if it's
405 // present, check it
406
407 auto const reqBalance = bal->xrp();
408 auto const authAmt = amt ? amt->xrp() : reqBalance;
409
410 if (reqBalance > authAmt)
411 return temBAD_AMOUNT;
412
413 Keylet const k(ltPAYCHAN, ctx.tx[sfChannel]);
414 if (!publicKeyType(ctx.tx[sfPublicKey]))
415 return temMALFORMED;
416
417 PublicKey const pk(ctx.tx[sfPublicKey]);
418 Serializer msg;
419 serializePayChanAuthorization(msg, k.key, authAmt);
420 if (!verify(pk, msg.slice(), *sig))
421 return temBAD_SIGNATURE;
422 }
423
424 if (auto const err = credentials::checkFields(ctx.tx, ctx.j); !isTesSuccess(err))
425 return err;
426
427 return tesSUCCESS;
428}
429
430TER
432{
433 if (!ctx.view.rules().enabled(featureCredentials))
434 return Transactor::preclaim(ctx);
435
436 if (auto const err = credentials::valid(ctx.tx, ctx.view, ctx.tx[sfAccount], ctx.j); !isTesSuccess(err))
437 return err;
438
439 return tesSUCCESS;
440}
441
442TER
444{
445 Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]);
446 auto const slep = ctx_.view().peek(k);
447 if (!slep)
448 return tecNO_TARGET;
449
450 AccountID const src = (*slep)[sfAccount];
451 AccountID const dst = (*slep)[sfDestination];
452 AccountID const txAccount = ctx_.tx[sfAccount];
453
454 auto const curExpiration = (*slep)[~sfExpiration];
455 {
456 auto const cancelAfter = (*slep)[~sfCancelAfter];
457 auto const closeTime = ctx_.view().header().parentCloseTime.time_since_epoch().count();
458 if ((cancelAfter && closeTime >= *cancelAfter) || (curExpiration && closeTime >= *curExpiration))
459 return closeChannel(slep, ctx_.view(), k.key, ctx_.app.journal("View"));
460 }
461
462 if (txAccount != src && txAccount != dst)
463 return tecNO_PERMISSION;
464
465 if (ctx_.tx[~sfBalance])
466 {
467 auto const chanBalance = slep->getFieldAmount(sfBalance).xrp();
468 auto const chanFunds = slep->getFieldAmount(sfAmount).xrp();
469 auto const reqBalance = ctx_.tx[sfBalance].xrp();
470
471 if (txAccount == dst && !ctx_.tx[~sfSignature])
472 return temBAD_SIGNATURE;
473
474 if (ctx_.tx[~sfSignature])
475 {
476 PublicKey const pk((*slep)[sfPublicKey]);
477 if (ctx_.tx[sfPublicKey] != pk)
478 return temBAD_SIGNER;
479 }
480
481 if (reqBalance > chanFunds)
482 return tecUNFUNDED_PAYMENT;
483
484 if (reqBalance <= chanBalance)
485 // nothing requested
486 return tecUNFUNDED_PAYMENT;
487
488 auto const sled = ctx_.view().peek(keylet::account(dst));
489 if (!sled)
490 return tecNO_DST;
491
492 if (auto err = verifyDepositPreauth(ctx_.tx, ctx_.view(), txAccount, dst, sled, ctx_.journal);
493 !isTesSuccess(err))
494 return err;
495
496 (*slep)[sfBalance] = ctx_.tx[sfBalance];
497 XRPAmount const reqDelta = reqBalance - chanBalance;
498 XRPL_ASSERT(reqDelta >= beast::zero, "xrpl::PayChanClaim::doApply : minimum balance delta");
499 (*sled)[sfBalance] = (*sled)[sfBalance] + reqDelta;
500 ctx_.view().update(sled);
501 ctx_.view().update(slep);
502 }
503
504 if (ctx_.tx.getFlags() & tfRenew)
505 {
506 if (src != txAccount)
507 return tecNO_PERMISSION;
508 (*slep)[~sfExpiration] = std::nullopt;
509 ctx_.view().update(slep);
510 }
511
512 if (ctx_.tx.getFlags() & tfClose)
513 {
514 // Channel will close immediately if dry or the receiver closes
515 if (dst == txAccount || (*slep)[sfBalance] == (*slep)[sfAmount])
516 return closeChannel(slep, ctx_.view(), k.key, ctx_.app.journal("View"));
517
518 auto const settleExpiration =
519 ctx_.view().header().parentCloseTime.time_since_epoch().count() + (*slep)[sfSettleDelay];
520
521 if (!curExpiration || *curExpiration > settleExpiration)
522 {
523 (*slep)[~sfExpiration] = settleExpiration;
524 ctx_.view().update(slep);
525 }
526 }
527
528 return tesSUCCESS;
529}
530
531} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:41
Stream fatal() const
Definition Journal.h:325
virtual beast::Journal journal(std::string const &name)=0
STTx const & tx
beast::Journal const journal
ApplyView & view()
Application & app
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:115
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 erase(std::shared_ptr< SLE > const &sle)=0
Remove a peeked SLE.
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:284
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
TER doApply() override
Definition PayChan.cpp:443
static std::uint32_t getFlagsMask(PreflightContext const &ctx)
Definition PayChan.cpp:372
static TER preclaim(PreclaimContext const &ctx)
Definition PayChan.cpp:431
static bool checkExtraFeatures(PreflightContext const &ctx)
Definition PayChan.cpp:366
static NotTEC preflight(PreflightContext const &ctx)
Definition PayChan.cpp:378
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
Definition PayChan.cpp:144
TER doApply() override
Definition PayChan.cpp:215
static TER preclaim(PreclaimContext const &ctx)
Definition PayChan.cpp:165
static NotTEC preflight(PreflightContext const &ctx)
Definition PayChan.cpp:150
static NotTEC preflight(PreflightContext const &ctx)
Definition PayChan.cpp:289
TER doApply() override
Definition PayChan.cpp:298
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
Definition PayChan.cpp:283
A public key.
Definition PublicKey.h:43
virtual Rules const & rules() const =0
Returns the tx processing rules.
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
virtual LedgerHeader const & header() const =0
Returns information about the ledger.
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:118
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:439
std::uint32_t getFlags() const
Definition STObject.cpp:492
std::uint32_t getSeqValue() const
Returns the first non-zero value of (Sequence, TicketSequence).
Definition STTx.cpp:208
Slice slice() const noexcept
Definition Serializer.h:45
static TER preclaim(PreclaimContext const &ctx)
Definition Transactor.h:199
ApplyContext & ctx_
Definition Transactor.h:109
Class describing the consequences to the account of applying a transaction if the transaction consume...
Definition applySteps.h:38
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 ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:325
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Definition Indexes.cpp:346
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:160
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
@ terNO_ACCOUNT
Definition TER.h:198
bool isXRP(AccountID const &c)
Definition AccountID.h:71
constexpr std::uint32_t tfPayChanClaimMask
Definition TxFlags.h:117
static TER closeChannel(std::shared_ptr< SLE > const &slep, ApplyView &view, uint256 const &key, beast::Journal j)
Definition PayChan.cpp:98
@ tefBAD_LEDGER
Definition TER.h:151
@ tefINTERNAL
Definition TER.h:154
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig) noexcept
Verify a signature on a message.
void serializePayChanAuthorization(Serializer &msg, uint256 const &key, XRPAmount const &amt)
TER verifyDepositPreauth(STTx const &tx, ApplyView &view, AccountID const &src, AccountID const &dst, std::shared_ptr< SLE > const &sleDst, beast::Journal j)
constexpr std::uint32_t tfRenew
Definition TxFlags.h:115
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
bool isPseudoAccount(std::shared_ptr< SLE const > sleAcct, std::set< SField const * > const &pseudoFieldFilter={})
Definition View.cpp:1020
TERSubset< CanCvtToTER > TER
Definition TER.h:621
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:941
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition View.cpp:3436
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition View.cpp:955
constexpr std::uint32_t tfClose
Definition TxFlags.h:116
@ temBAD_EXPIRATION
Definition TER.h:72
@ temDST_IS_SRC
Definition TER.h:89
@ temMALFORMED
Definition TER.h:68
@ temBAD_AMOUNT
Definition TER.h:70
@ temBAD_SIGNATURE
Definition TER.h:86
@ temBAD_SIGNER
Definition TER.h:96
bool isTesSuccess(TER x) noexcept
Definition TER.h:650
@ tecDIR_FULL
Definition TER.h:269
@ tecUNFUNDED_PAYMENT
Definition TER.h:267
@ tecNO_ENTRY
Definition TER.h:288
@ tecNO_TARGET
Definition TER.h:286
@ tecEXPIRED
Definition TER.h:296
@ tecINSUFFICIENT_RESERVE
Definition TER.h:289
@ tecNO_PERMISSION
Definition TER.h:287
@ tecDST_TAG_NEEDED
Definition TER.h:291
@ tecNO_DST
Definition TER.h:272
@ tecUNFUNDED
Definition TER.h:277
@ lsfDisallowIncomingPayChan
@ lsfRequireDestTag
@ tesSUCCESS
Definition TER.h:226
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:54
ReadView const & view
Definition Transactor.h:57
beast::Journal const j
Definition Transactor.h:62
State information when preflighting a tx.
Definition Transactor.h:16
beast::Journal const j
Definition Transactor.h:23
T time_since_epoch(T... args)