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