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