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
176{
177 // 0 means "Allow any flags"
178 return ctx.rules.enabled(fix1543) ? tfUniversalMask : 0;
179}
180
181NotTEC
183{
184 if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero))
185 return temBAD_AMOUNT;
186
187 if (ctx.tx[sfAccount] == ctx.tx[sfDestination])
188 return temDST_IS_SRC;
189
190 if (!publicKeyType(ctx.tx[sfPublicKey]))
191 return temMALFORMED;
192
193 return tesSUCCESS;
194}
195
196TER
198{
199 auto const account = ctx.tx[sfAccount];
200 auto const sle = ctx.view.read(keylet::account(account));
201 if (!sle)
202 return terNO_ACCOUNT;
203
204 // Check reserve and funds availability
205 {
206 auto const balance = (*sle)[sfBalance];
207 auto const reserve =
208 ctx.view.fees().accountReserve((*sle)[sfOwnerCount] + 1);
209
210 if (balance < reserve)
212
213 if (balance < reserve + ctx.tx[sfAmount])
214 return tecUNFUNDED;
215 }
216
217 auto const dst = ctx.tx[sfDestination];
218
219 {
220 // Check destination account
221 auto const sled = ctx.view.read(keylet::account(dst));
222 if (!sled)
223 return tecNO_DST;
224
225 auto const flags = sled->getFlags();
226
227 // Check if they have disallowed incoming payment channels
228 if (ctx.view.rules().enabled(featureDisallowIncoming) &&
230 return tecNO_PERMISSION;
231
232 if ((flags & lsfRequireDestTag) && !ctx.tx[~sfDestinationTag])
233 return tecDST_TAG_NEEDED;
234
235 // Obeying the lsfDisallowXRP flag was a bug. Piggyback on
236 // featureDepositAuth to remove the bug.
237 if (!ctx.view.rules().enabled(featureDepositAuth) &&
238 (flags & lsfDisallowXRP))
239 return tecNO_TARGET;
240
241 // Pseudo-accounts cannot receive payment channels, other than native
242 // to their underlying ledger object - implemented in their respective
243 // transaction types. Note, this is not amendment-gated because all
244 // writes to pseudo-account discriminator fields **are** amendment
245 // gated, hence the behaviour of this check will always match the
246 // currently active amendments.
247 if (isPseudoAccount(sled))
248 return tecNO_PERMISSION;
249 }
250
251 return tesSUCCESS;
252}
253
254TER
256{
257 auto const account = ctx_.tx[sfAccount];
258 auto const sle = ctx_.view().peek(keylet::account(account));
259 if (!sle)
260 return tefINTERNAL;
261
262 if (ctx_.view().rules().enabled(fixPayChanCancelAfter))
263 {
264 auto const closeTime = ctx_.view().info().parentCloseTime;
265 if (ctx_.tx[~sfCancelAfter] && after(closeTime, ctx_.tx[sfCancelAfter]))
266 return tecEXPIRED;
267 }
268
269 auto const dst = ctx_.tx[sfDestination];
270
271 // Create PayChan in ledger.
272 //
273 // Note that we we use the value from the sequence or ticket as the
274 // payChan sequence. For more explanation see comments in SeqProxy.h.
275 Keylet const payChanKeylet =
276 keylet::payChan(account, dst, ctx_.tx.getSeqValue());
277 auto const slep = std::make_shared<SLE>(payChanKeylet);
278
279 // Funds held in this channel
280 (*slep)[sfAmount] = ctx_.tx[sfAmount];
281 // Amount channel has already paid
282 (*slep)[sfBalance] = ctx_.tx[sfAmount].zeroed();
283 (*slep)[sfAccount] = account;
284 (*slep)[sfDestination] = dst;
285 (*slep)[sfSettleDelay] = ctx_.tx[sfSettleDelay];
286 (*slep)[sfPublicKey] = ctx_.tx[sfPublicKey];
287 (*slep)[~sfCancelAfter] = ctx_.tx[~sfCancelAfter];
288 (*slep)[~sfSourceTag] = ctx_.tx[~sfSourceTag];
289 (*slep)[~sfDestinationTag] = ctx_.tx[~sfDestinationTag];
290 if (ctx_.view().rules().enabled(fixIncludeKeyletFields))
291 {
292 (*slep)[sfSequence] = ctx_.tx.getSeqValue();
293 }
294
295 ctx_.view().insert(slep);
296
297 // Add PayChan to owner directory
298 {
299 auto const page = ctx_.view().dirInsert(
300 keylet::ownerDir(account),
301 payChanKeylet,
302 describeOwnerDir(account));
303 if (!page)
304 return tecDIR_FULL;
305 (*slep)[sfOwnerNode] = *page;
306 }
307
308 // Add PayChan to the recipient's owner directory
309 if (ctx_.view().rules().enabled(fixPayChanRecipientOwnerDir))
310 {
311 auto const page = ctx_.view().dirInsert(
312 keylet::ownerDir(dst), payChanKeylet, describeOwnerDir(dst));
313 if (!page)
314 return tecDIR_FULL;
315 (*slep)[sfDestinationNode] = *page;
316 }
317
318 // Deduct owner's balance, increment owner count
319 (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
321 ctx_.view().update(sle);
322
323 return tesSUCCESS;
324}
325
326//------------------------------------------------------------------------------
327
330{
331 return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()};
332}
333
336{
337 // 0 means "Allow any flags"
338 return ctx.rules.enabled(fix1543) ? tfUniversalMask : 0;
339}
340
341NotTEC
343{
344 if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero))
345 return temBAD_AMOUNT;
346
347 return tesSUCCESS;
348}
349
350TER
352{
353 Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]);
354 auto const slep = ctx_.view().peek(k);
355 if (!slep)
356 return tecNO_ENTRY;
357
358 AccountID const src = (*slep)[sfAccount];
359 auto const txAccount = ctx_.tx[sfAccount];
360 auto const expiration = (*slep)[~sfExpiration];
361
362 {
363 auto const cancelAfter = (*slep)[~sfCancelAfter];
364 auto const closeTime =
366 if ((cancelAfter && closeTime >= *cancelAfter) ||
367 (expiration && closeTime >= *expiration))
368 return closeChannel(
369 slep, ctx_.view(), k.key, ctx_.app.journal("View"));
370 }
371
372 if (src != txAccount)
373 // only the owner can add funds or extend
374 return tecNO_PERMISSION;
375
376 if (auto extend = ctx_.tx[~sfExpiration])
377 {
378 auto minExpiration =
380 (*slep)[sfSettleDelay];
381 if (expiration && *expiration < minExpiration)
382 minExpiration = *expiration;
383
384 if (*extend < minExpiration)
385 return temBAD_EXPIRATION;
386 (*slep)[~sfExpiration] = *extend;
387 ctx_.view().update(slep);
388 }
389
390 auto const sle = ctx_.view().peek(keylet::account(txAccount));
391 if (!sle)
392 return tefINTERNAL;
393
394 {
395 // Check reserve and funds availability
396 auto const balance = (*sle)[sfBalance];
397 auto const reserve =
398 ctx_.view().fees().accountReserve((*sle)[sfOwnerCount]);
399
400 if (balance < reserve)
402
403 if (balance < reserve + ctx_.tx[sfAmount])
404 return tecUNFUNDED;
405 }
406
407 // do not allow adding funds if dst does not exist
408 if (AccountID const dst = (*slep)[sfDestination];
409 !ctx_.view().read(keylet::account(dst)))
410 {
411 return tecNO_DST;
412 }
413
414 (*slep)[sfAmount] = (*slep)[sfAmount] + ctx_.tx[sfAmount];
415 ctx_.view().update(slep);
416
417 (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
418 ctx_.view().update(sle);
419
420 return tesSUCCESS;
421}
422
423//------------------------------------------------------------------------------
424
425bool
427{
428 return !ctx.tx.isFieldPresent(sfCredentialIDs) ||
429 ctx.rules.enabled(featureCredentials);
430}
431
434{
435 // 0 means "Allow any flags"
436 return ctx.rules.enabled(fix1543) ? tfPayChanClaimMask : 0;
437}
438
439NotTEC
441{
442 auto const bal = ctx.tx[~sfBalance];
443 if (bal && (!isXRP(*bal) || *bal <= beast::zero))
444 return temBAD_AMOUNT;
445
446 auto const amt = ctx.tx[~sfAmount];
447 if (amt && (!isXRP(*amt) || *amt <= beast::zero))
448 return temBAD_AMOUNT;
449
450 if (bal && amt && *bal > *amt)
451 return temBAD_AMOUNT;
452
453 {
454 auto const flags = ctx.tx.getFlags();
455
456 if ((flags & tfClose) && (flags & tfRenew))
457 return temMALFORMED;
458 }
459
460 if (auto const sig = ctx.tx[~sfSignature])
461 {
462 if (!(ctx.tx[~sfPublicKey] && bal))
463 return temMALFORMED;
464
465 // Check the signature
466 // The signature isn't needed if txAccount == src, but if it's
467 // present, check it
468
469 auto const reqBalance = bal->xrp();
470 auto const authAmt = amt ? amt->xrp() : reqBalance;
471
472 if (reqBalance > authAmt)
473 return temBAD_AMOUNT;
474
475 Keylet const k(ltPAYCHAN, ctx.tx[sfChannel]);
476 if (!publicKeyType(ctx.tx[sfPublicKey]))
477 return temMALFORMED;
478
479 PublicKey const pk(ctx.tx[sfPublicKey]);
480 Serializer msg;
481 serializePayChanAuthorization(msg, k.key, authAmt);
482 if (!verify(pk, msg.slice(), *sig, /*canonical*/ true))
483 return temBAD_SIGNATURE;
484 }
485
486 if (auto const err = credentials::checkFields(ctx.tx, ctx.j);
487 !isTesSuccess(err))
488 return err;
489
490 return tesSUCCESS;
491}
492
493TER
495{
496 if (!ctx.view.rules().enabled(featureCredentials))
497 return Transactor::preclaim(ctx);
498
499 if (auto const err =
500 credentials::valid(ctx.tx, ctx.view, ctx.tx[sfAccount], ctx.j);
501 !isTesSuccess(err))
502 return err;
503
504 return tesSUCCESS;
505}
506
507TER
509{
510 Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]);
511 auto const slep = ctx_.view().peek(k);
512 if (!slep)
513 return tecNO_TARGET;
514
515 AccountID const src = (*slep)[sfAccount];
516 AccountID const dst = (*slep)[sfDestination];
517 AccountID const txAccount = ctx_.tx[sfAccount];
518
519 auto const curExpiration = (*slep)[~sfExpiration];
520 {
521 auto const cancelAfter = (*slep)[~sfCancelAfter];
522 auto const closeTime =
524 if ((cancelAfter && closeTime >= *cancelAfter) ||
525 (curExpiration && closeTime >= *curExpiration))
526 return closeChannel(
527 slep, ctx_.view(), k.key, ctx_.app.journal("View"));
528 }
529
530 if (txAccount != src && txAccount != dst)
531 return tecNO_PERMISSION;
532
533 if (ctx_.tx[~sfBalance])
534 {
535 auto const chanBalance = slep->getFieldAmount(sfBalance).xrp();
536 auto const chanFunds = slep->getFieldAmount(sfAmount).xrp();
537 auto const reqBalance = ctx_.tx[sfBalance].xrp();
538
539 if (txAccount == dst && !ctx_.tx[~sfSignature])
540 return temBAD_SIGNATURE;
541
542 if (ctx_.tx[~sfSignature])
543 {
544 PublicKey const pk((*slep)[sfPublicKey]);
545 if (ctx_.tx[sfPublicKey] != pk)
546 return temBAD_SIGNER;
547 }
548
549 if (reqBalance > chanFunds)
550 return tecUNFUNDED_PAYMENT;
551
552 if (reqBalance <= chanBalance)
553 // nothing requested
554 return tecUNFUNDED_PAYMENT;
555
556 auto const sled = ctx_.view().peek(keylet::account(dst));
557 if (!sled)
558 return tecNO_DST;
559
560 // Obeying the lsfDisallowXRP flag was a bug. Piggyback on
561 // featureDepositAuth to remove the bug.
562 bool const depositAuth{ctx_.view().rules().enabled(featureDepositAuth)};
563 if (!depositAuth &&
564 (txAccount == src && (sled->getFlags() & lsfDisallowXRP)))
565 return tecNO_TARGET;
566
567 if (depositAuth)
568 {
569 if (auto err = verifyDepositPreauth(
570 ctx_.tx, ctx_.view(), txAccount, dst, sled, ctx_.journal);
571 !isTesSuccess(err))
572 return err;
573 }
574
575 (*slep)[sfBalance] = ctx_.tx[sfBalance];
576 XRPAmount const reqDelta = reqBalance - chanBalance;
577 XRPL_ASSERT(
578 reqDelta >= beast::zero,
579 "ripple::PayChanClaim::doApply : minimum balance delta");
580 (*sled)[sfBalance] = (*sled)[sfBalance] + reqDelta;
581 ctx_.view().update(sled);
582 ctx_.view().update(slep);
583 }
584
585 if (ctx_.tx.getFlags() & tfRenew)
586 {
587 if (src != txAccount)
588 return tecNO_PERMISSION;
589 (*slep)[~sfExpiration] = std::nullopt;
590 ctx_.view().update(slep);
591 }
592
593 if (ctx_.tx.getFlags() & tfClose)
594 {
595 // Channel will close immediately if dry or the receiver closes
596 if (dst == txAccount || (*slep)[sfBalance] == (*slep)[sfAmount])
597 return closeChannel(
598 slep, ctx_.view(), k.key, ctx_.app.journal("View"));
599
600 auto const settleExpiration =
602 (*slep)[sfSettleDelay];
603
604 if (!curExpiration || *curExpiration > settleExpiration)
605 {
606 (*slep)[~sfExpiration] = settleExpiration;
607 ctx_.view().update(slep);
608 }
609 }
610
611 return tesSUCCESS;
612}
613
614} // 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:440
static TER preclaim(PreclaimContext const &ctx)
Definition PayChan.cpp:494
static std::uint32_t getFlagsMask(PreflightContext const &ctx)
Definition PayChan.cpp:433
static bool checkExtraFeatures(PreflightContext const &ctx)
Definition PayChan.cpp:426
TER doApply() override
Definition PayChan.cpp:508
static NotTEC preflight(PreflightContext const &ctx)
Definition PayChan.cpp:182
TER doApply() override
Definition PayChan.cpp:255
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
Definition PayChan.cpp:169
static std::uint32_t getFlagsMask(PreflightContext const &ctx)
Definition PayChan.cpp:175
static TER preclaim(PreclaimContext const &ctx)
Definition PayChan.cpp:197
TER doApply() override
Definition PayChan.cpp:351
static std::uint32_t getFlagsMask(PreflightContext const &ctx)
Definition PayChan.cpp:335
static NotTEC preflight(PreflightContext const &ctx)
Definition PayChan.cpp:342
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
Definition PayChan.cpp:329
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:233
ApplyContext & ctx_
Definition Transactor.h:143
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
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.
@ 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
@ 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)