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/misc/CredentialHelpers.h>
21#include <xrpld/app/tx/detail/PayChan.h>
22#include <xrpld/ledger/ApplyView.h>
23#include <xrpld/ledger/View.h>
24
25#include <xrpl/basics/Log.h>
26#include <xrpl/basics/chrono.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
290 ctx_.view().insert(slep);
291
292 // Add PayChan to owner directory
293 {
294 auto const page = ctx_.view().dirInsert(
295 keylet::ownerDir(account),
296 payChanKeylet,
297 describeOwnerDir(account));
298 if (!page)
299 return tecDIR_FULL;
300 (*slep)[sfOwnerNode] = *page;
301 }
302
303 // Add PayChan to the recipient's owner directory
304 if (ctx_.view().rules().enabled(fixPayChanRecipientOwnerDir))
305 {
306 auto const page = ctx_.view().dirInsert(
307 keylet::ownerDir(dst), payChanKeylet, describeOwnerDir(dst));
308 if (!page)
309 return tecDIR_FULL;
310 (*slep)[sfDestinationNode] = *page;
311 }
312
313 // Deduct owner's balance, increment owner count
314 (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
316 ctx_.view().update(sle);
317
318 return tesSUCCESS;
319}
320
321//------------------------------------------------------------------------------
322
325{
326 return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()};
327}
328
329NotTEC
331{
332 if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
333 return temINVALID_FLAG;
334
335 if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
336 return ret;
337
338 if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero))
339 return temBAD_AMOUNT;
340
341 return preflight2(ctx);
342}
343
344TER
346{
347 Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]);
348 auto const slep = ctx_.view().peek(k);
349 if (!slep)
350 return tecNO_ENTRY;
351
352 AccountID const src = (*slep)[sfAccount];
353 auto const txAccount = ctx_.tx[sfAccount];
354 auto const expiration = (*slep)[~sfExpiration];
355
356 {
357 auto const cancelAfter = (*slep)[~sfCancelAfter];
358 auto const closeTime =
360 if ((cancelAfter && closeTime >= *cancelAfter) ||
361 (expiration && closeTime >= *expiration))
362 return closeChannel(
363 slep, ctx_.view(), k.key, ctx_.app.journal("View"));
364 }
365
366 if (src != txAccount)
367 // only the owner can add funds or extend
368 return tecNO_PERMISSION;
369
370 if (auto extend = ctx_.tx[~sfExpiration])
371 {
372 auto minExpiration =
374 (*slep)[sfSettleDelay];
375 if (expiration && *expiration < minExpiration)
376 minExpiration = *expiration;
377
378 if (*extend < minExpiration)
379 return temBAD_EXPIRATION;
380 (*slep)[~sfExpiration] = *extend;
381 ctx_.view().update(slep);
382 }
383
384 auto const sle = ctx_.view().peek(keylet::account(txAccount));
385 if (!sle)
386 return tefINTERNAL;
387
388 {
389 // Check reserve and funds availability
390 auto const balance = (*sle)[sfBalance];
391 auto const reserve =
392 ctx_.view().fees().accountReserve((*sle)[sfOwnerCount]);
393
394 if (balance < reserve)
396
397 if (balance < reserve + ctx_.tx[sfAmount])
398 return tecUNFUNDED;
399 }
400
401 // do not allow adding funds if dst does not exist
402 if (AccountID const dst = (*slep)[sfDestination];
403 !ctx_.view().read(keylet::account(dst)))
404 {
405 return tecNO_DST;
406 }
407
408 (*slep)[sfAmount] = (*slep)[sfAmount] + ctx_.tx[sfAmount];
409 ctx_.view().update(slep);
410
411 (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
412 ctx_.view().update(sle);
413
414 return tesSUCCESS;
415}
416
417//------------------------------------------------------------------------------
418
419NotTEC
421{
422 if (ctx.tx.isFieldPresent(sfCredentialIDs) &&
423 !ctx.rules.enabled(featureCredentials))
424 return temDISABLED;
425
426 if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
427 return ret;
428
429 auto const bal = ctx.tx[~sfBalance];
430 if (bal && (!isXRP(*bal) || *bal <= beast::zero))
431 return temBAD_AMOUNT;
432
433 auto const amt = ctx.tx[~sfAmount];
434 if (amt && (!isXRP(*amt) || *amt <= beast::zero))
435 return temBAD_AMOUNT;
436
437 if (bal && amt && *bal > *amt)
438 return temBAD_AMOUNT;
439
440 {
441 auto const flags = ctx.tx.getFlags();
442
443 if (ctx.rules.enabled(fix1543) && (flags & tfPayChanClaimMask))
444 return temINVALID_FLAG;
445
446 if ((flags & tfClose) && (flags & tfRenew))
447 return temMALFORMED;
448 }
449
450 if (auto const sig = ctx.tx[~sfSignature])
451 {
452 if (!(ctx.tx[~sfPublicKey] && bal))
453 return temMALFORMED;
454
455 // Check the signature
456 // The signature isn't needed if txAccount == src, but if it's
457 // present, check it
458
459 auto const reqBalance = bal->xrp();
460 auto const authAmt = amt ? amt->xrp() : reqBalance;
461
462 if (reqBalance > authAmt)
463 return temBAD_AMOUNT;
464
465 Keylet const k(ltPAYCHAN, ctx.tx[sfChannel]);
466 if (!publicKeyType(ctx.tx[sfPublicKey]))
467 return temMALFORMED;
468
469 PublicKey const pk(ctx.tx[sfPublicKey]);
470 Serializer msg;
471 serializePayChanAuthorization(msg, k.key, authAmt);
472 if (!verify(pk, msg.slice(), *sig, /*canonical*/ true))
473 return temBAD_SIGNATURE;
474 }
475
476 if (auto const err = credentials::checkFields(ctx.tx, ctx.j);
477 !isTesSuccess(err))
478 return err;
479
480 return preflight2(ctx);
481}
482
483TER
485{
486 if (!ctx.view.rules().enabled(featureCredentials))
487 return Transactor::preclaim(ctx);
488
489 if (auto const err =
490 credentials::valid(ctx.tx, ctx.view, ctx.tx[sfAccount], ctx.j);
491 !isTesSuccess(err))
492 return err;
493
494 return tesSUCCESS;
495}
496
497TER
499{
500 Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]);
501 auto const slep = ctx_.view().peek(k);
502 if (!slep)
503 return tecNO_TARGET;
504
505 AccountID const src = (*slep)[sfAccount];
506 AccountID const dst = (*slep)[sfDestination];
507 AccountID const txAccount = ctx_.tx[sfAccount];
508
509 auto const curExpiration = (*slep)[~sfExpiration];
510 {
511 auto const cancelAfter = (*slep)[~sfCancelAfter];
512 auto const closeTime =
514 if ((cancelAfter && closeTime >= *cancelAfter) ||
515 (curExpiration && closeTime >= *curExpiration))
516 return closeChannel(
517 slep, ctx_.view(), k.key, ctx_.app.journal("View"));
518 }
519
520 if (txAccount != src && txAccount != dst)
521 return tecNO_PERMISSION;
522
523 if (ctx_.tx[~sfBalance])
524 {
525 auto const chanBalance = slep->getFieldAmount(sfBalance).xrp();
526 auto const chanFunds = slep->getFieldAmount(sfAmount).xrp();
527 auto const reqBalance = ctx_.tx[sfBalance].xrp();
528
529 if (txAccount == dst && !ctx_.tx[~sfSignature])
530 return temBAD_SIGNATURE;
531
532 if (ctx_.tx[~sfSignature])
533 {
534 PublicKey const pk((*slep)[sfPublicKey]);
535 if (ctx_.tx[sfPublicKey] != pk)
536 return temBAD_SIGNER;
537 }
538
539 if (reqBalance > chanFunds)
540 return tecUNFUNDED_PAYMENT;
541
542 if (reqBalance <= chanBalance)
543 // nothing requested
544 return tecUNFUNDED_PAYMENT;
545
546 auto const sled = ctx_.view().peek(keylet::account(dst));
547 if (!sled)
548 return tecNO_DST;
549
550 // Obeying the lsfDisallowXRP flag was a bug. Piggyback on
551 // featureDepositAuth to remove the bug.
552 bool const depositAuth{ctx_.view().rules().enabled(featureDepositAuth)};
553 if (!depositAuth &&
554 (txAccount == src && (sled->getFlags() & lsfDisallowXRP)))
555 return tecNO_TARGET;
556
557 if (depositAuth)
558 {
559 if (auto err = verifyDepositPreauth(
560 ctx_.tx, ctx_.view(), txAccount, dst, sled, ctx_.journal);
561 !isTesSuccess(err))
562 return err;
563 }
564
565 (*slep)[sfBalance] = ctx_.tx[sfBalance];
566 XRPAmount const reqDelta = reqBalance - chanBalance;
567 XRPL_ASSERT(
568 reqDelta >= beast::zero,
569 "ripple::PayChanClaim::doApply : minimum balance delta");
570 (*sled)[sfBalance] = (*sled)[sfBalance] + reqDelta;
571 ctx_.view().update(sled);
572 ctx_.view().update(slep);
573 }
574
575 if (ctx_.tx.getFlags() & tfRenew)
576 {
577 if (src != txAccount)
578 return tecNO_PERMISSION;
579 (*slep)[~sfExpiration] = std::nullopt;
580 ctx_.view().update(slep);
581 }
582
583 if (ctx_.tx.getFlags() & tfClose)
584 {
585 // Channel will close immediately if dry or the receiver closes
586 if (dst == txAccount || (*slep)[sfBalance] == (*slep)[sfAmount])
587 return closeChannel(
588 slep, ctx_.view(), k.key, ctx_.app.journal("View"));
589
590 auto const settleExpiration =
592 (*slep)[sfSettleDelay];
593
594 if (!curExpiration || *curExpiration > settleExpiration)
595 {
596 (*slep)[~sfExpiration] = settleExpiration;
597 ctx_.view().update(slep);
598 }
599 }
600
601 return tesSUCCESS;
602}
603
604} // 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:144
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:318
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:420
static TER preclaim(PreclaimContext const &ctx)
Definition PayChan.cpp:484
TER doApply() override
Definition PayChan.cpp:498
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:345
static NotTEC preflight(PreflightContext const &ctx)
Definition PayChan.cpp:330
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
Definition PayChan.cpp:324
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:200
ApplyContext & ctx_
Definition Transactor.h:140
Class describing the consequences to the account of applying a transaction if the transaction consume...
Definition applySteps.h:59
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:132
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical=true) noexcept
Verify a signature on a message.
@ lsfRequireDestTag
@ lsfDisallowIncomingPayChan
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition View.cpp:1048
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.
static bool adjustOwnerCount(ApplyContext &ctx, int count)
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:133
constexpr std::uint32_t tfPayChanClaimMask
Definition TxFlags.h:134
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition View.cpp:3179
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:1139
@ 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:79
ReadView const & view
Definition Transactor.h:82
beast::Journal const j
Definition Transactor.h:87
State information when preflighting a tx.
Definition Transactor.h:34
beast::Journal const j
Definition Transactor.h:41
T time_since_epoch(T... args)