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 if (sled->isFieldPresent(sfAMMID))
241 return tecNO_PERMISSION;
242 }
243
244 return tesSUCCESS;
245}
246
247TER
249{
250 auto const account = ctx_.tx[sfAccount];
251 auto const sle = ctx_.view().peek(keylet::account(account));
252 if (!sle)
253 return tefINTERNAL;
254
255 if (ctx_.view().rules().enabled(fixPayChanCancelAfter))
256 {
257 auto const closeTime = ctx_.view().info().parentCloseTime;
258 if (ctx_.tx[~sfCancelAfter] && after(closeTime, ctx_.tx[sfCancelAfter]))
259 return tecEXPIRED;
260 }
261
262 auto const dst = ctx_.tx[sfDestination];
263
264 // Create PayChan in ledger.
265 //
266 // Note that we we use the value from the sequence or ticket as the
267 // payChan sequence. For more explanation see comments in SeqProxy.h.
268 Keylet const payChanKeylet =
269 keylet::payChan(account, dst, ctx_.tx.getSeqProxy().value());
270 auto const slep = std::make_shared<SLE>(payChanKeylet);
271
272 // Funds held in this channel
273 (*slep)[sfAmount] = ctx_.tx[sfAmount];
274 // Amount channel has already paid
275 (*slep)[sfBalance] = ctx_.tx[sfAmount].zeroed();
276 (*slep)[sfAccount] = account;
277 (*slep)[sfDestination] = dst;
278 (*slep)[sfSettleDelay] = ctx_.tx[sfSettleDelay];
279 (*slep)[sfPublicKey] = ctx_.tx[sfPublicKey];
280 (*slep)[~sfCancelAfter] = ctx_.tx[~sfCancelAfter];
281 (*slep)[~sfSourceTag] = ctx_.tx[~sfSourceTag];
282 (*slep)[~sfDestinationTag] = ctx_.tx[~sfDestinationTag];
283
284 ctx_.view().insert(slep);
285
286 // Add PayChan to owner directory
287 {
288 auto const page = ctx_.view().dirInsert(
289 keylet::ownerDir(account),
290 payChanKeylet,
291 describeOwnerDir(account));
292 if (!page)
293 return tecDIR_FULL;
294 (*slep)[sfOwnerNode] = *page;
295 }
296
297 // Add PayChan to the recipient's owner directory
298 if (ctx_.view().rules().enabled(fixPayChanRecipientOwnerDir))
299 {
300 auto const page = ctx_.view().dirInsert(
301 keylet::ownerDir(dst), payChanKeylet, describeOwnerDir(dst));
302 if (!page)
303 return tecDIR_FULL;
304 (*slep)[sfDestinationNode] = *page;
305 }
306
307 // Deduct owner's balance, increment owner count
308 (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
310 ctx_.view().update(sle);
311
312 return tesSUCCESS;
313}
314
315//------------------------------------------------------------------------------
316
319{
320 return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()};
321}
322
323NotTEC
325{
326 if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
327 return temINVALID_FLAG;
328
329 if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
330 return ret;
331
332 if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero))
333 return temBAD_AMOUNT;
334
335 return preflight2(ctx);
336}
337
338TER
340{
341 Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]);
342 auto const slep = ctx_.view().peek(k);
343 if (!slep)
344 return tecNO_ENTRY;
345
346 AccountID const src = (*slep)[sfAccount];
347 auto const txAccount = ctx_.tx[sfAccount];
348 auto const expiration = (*slep)[~sfExpiration];
349
350 {
351 auto const cancelAfter = (*slep)[~sfCancelAfter];
352 auto const closeTime =
354 if ((cancelAfter && closeTime >= *cancelAfter) ||
355 (expiration && closeTime >= *expiration))
356 return closeChannel(
357 slep, ctx_.view(), k.key, ctx_.app.journal("View"));
358 }
359
360 if (src != txAccount)
361 // only the owner can add funds or extend
362 return tecNO_PERMISSION;
363
364 if (auto extend = ctx_.tx[~sfExpiration])
365 {
366 auto minExpiration =
368 (*slep)[sfSettleDelay];
369 if (expiration && *expiration < minExpiration)
370 minExpiration = *expiration;
371
372 if (*extend < minExpiration)
373 return temBAD_EXPIRATION;
374 (*slep)[~sfExpiration] = *extend;
375 ctx_.view().update(slep);
376 }
377
378 auto const sle = ctx_.view().peek(keylet::account(txAccount));
379 if (!sle)
380 return tefINTERNAL;
381
382 {
383 // Check reserve and funds availability
384 auto const balance = (*sle)[sfBalance];
385 auto const reserve =
386 ctx_.view().fees().accountReserve((*sle)[sfOwnerCount]);
387
388 if (balance < reserve)
390
391 if (balance < reserve + ctx_.tx[sfAmount])
392 return tecUNFUNDED;
393 }
394
395 // do not allow adding funds if dst does not exist
396 if (AccountID const dst = (*slep)[sfDestination];
397 !ctx_.view().read(keylet::account(dst)))
398 {
399 return tecNO_DST;
400 }
401
402 (*slep)[sfAmount] = (*slep)[sfAmount] + ctx_.tx[sfAmount];
403 ctx_.view().update(slep);
404
405 (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
406 ctx_.view().update(sle);
407
408 return tesSUCCESS;
409}
410
411//------------------------------------------------------------------------------
412
413NotTEC
415{
416 if (ctx.tx.isFieldPresent(sfCredentialIDs) &&
417 !ctx.rules.enabled(featureCredentials))
418 return temDISABLED;
419
420 if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
421 return ret;
422
423 auto const bal = ctx.tx[~sfBalance];
424 if (bal && (!isXRP(*bal) || *bal <= beast::zero))
425 return temBAD_AMOUNT;
426
427 auto const amt = ctx.tx[~sfAmount];
428 if (amt && (!isXRP(*amt) || *amt <= beast::zero))
429 return temBAD_AMOUNT;
430
431 if (bal && amt && *bal > *amt)
432 return temBAD_AMOUNT;
433
434 {
435 auto const flags = ctx.tx.getFlags();
436
437 if (ctx.rules.enabled(fix1543) && (flags & tfPayChanClaimMask))
438 return temINVALID_FLAG;
439
440 if ((flags & tfClose) && (flags & tfRenew))
441 return temMALFORMED;
442 }
443
444 if (auto const sig = ctx.tx[~sfSignature])
445 {
446 if (!(ctx.tx[~sfPublicKey] && bal))
447 return temMALFORMED;
448
449 // Check the signature
450 // The signature isn't needed if txAccount == src, but if it's
451 // present, check it
452
453 auto const reqBalance = bal->xrp();
454 auto const authAmt = amt ? amt->xrp() : reqBalance;
455
456 if (reqBalance > authAmt)
457 return temBAD_AMOUNT;
458
459 Keylet const k(ltPAYCHAN, ctx.tx[sfChannel]);
460 if (!publicKeyType(ctx.tx[sfPublicKey]))
461 return temMALFORMED;
462
463 PublicKey const pk(ctx.tx[sfPublicKey]);
464 Serializer msg;
465 serializePayChanAuthorization(msg, k.key, authAmt);
466 if (!verify(pk, msg.slice(), *sig, /*canonical*/ true))
467 return temBAD_SIGNATURE;
468 }
469
470 if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err))
471 return err;
472
473 return preflight2(ctx);
474}
475
476TER
478{
479 if (!ctx.view.rules().enabled(featureCredentials))
480 return Transactor::preclaim(ctx);
481
482 if (auto const err = credentials::valid(ctx, ctx.tx[sfAccount]);
483 !isTesSuccess(err))
484 return err;
485
486 return tesSUCCESS;
487}
488
489TER
491{
492 Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]);
493 auto const slep = ctx_.view().peek(k);
494 if (!slep)
495 return tecNO_TARGET;
496
497 AccountID const src = (*slep)[sfAccount];
498 AccountID const dst = (*slep)[sfDestination];
499 AccountID const txAccount = ctx_.tx[sfAccount];
500
501 auto const curExpiration = (*slep)[~sfExpiration];
502 {
503 auto const cancelAfter = (*slep)[~sfCancelAfter];
504 auto const closeTime =
506 if ((cancelAfter && closeTime >= *cancelAfter) ||
507 (curExpiration && closeTime >= *curExpiration))
508 return closeChannel(
509 slep, ctx_.view(), k.key, ctx_.app.journal("View"));
510 }
511
512 if (txAccount != src && txAccount != dst)
513 return tecNO_PERMISSION;
514
515 if (ctx_.tx[~sfBalance])
516 {
517 auto const chanBalance = slep->getFieldAmount(sfBalance).xrp();
518 auto const chanFunds = slep->getFieldAmount(sfAmount).xrp();
519 auto const reqBalance = ctx_.tx[sfBalance].xrp();
520
521 if (txAccount == dst && !ctx_.tx[~sfSignature])
522 return temBAD_SIGNATURE;
523
524 if (ctx_.tx[~sfSignature])
525 {
526 PublicKey const pk((*slep)[sfPublicKey]);
527 if (ctx_.tx[sfPublicKey] != pk)
528 return temBAD_SIGNER;
529 }
530
531 if (reqBalance > chanFunds)
532 return tecUNFUNDED_PAYMENT;
533
534 if (reqBalance <= chanBalance)
535 // nothing requested
536 return tecUNFUNDED_PAYMENT;
537
538 auto const sled = ctx_.view().peek(keylet::account(dst));
539 if (!sled)
540 return tecNO_DST;
541
542 // Obeying the lsfDisallowXRP flag was a bug. Piggyback on
543 // featureDepositAuth to remove the bug.
544 bool const depositAuth{ctx_.view().rules().enabled(featureDepositAuth)};
545 if (!depositAuth &&
546 (txAccount == src && (sled->getFlags() & lsfDisallowXRP)))
547 return tecNO_TARGET;
548
549 if (depositAuth)
550 {
551 if (auto err = verifyDepositPreauth(ctx_, txAccount, dst, sled);
552 !isTesSuccess(err))
553 return err;
554 }
555
556 (*slep)[sfBalance] = ctx_.tx[sfBalance];
557 XRPAmount const reqDelta = reqBalance - chanBalance;
558 XRPL_ASSERT(
559 reqDelta >= beast::zero,
560 "ripple::PayChanClaim::doApply : minimum balance delta");
561 (*sled)[sfBalance] = (*sled)[sfBalance] + reqDelta;
562 ctx_.view().update(sled);
563 ctx_.view().update(slep);
564 }
565
566 if (ctx_.tx.getFlags() & tfRenew)
567 {
568 if (src != txAccount)
569 return tecNO_PERMISSION;
570 (*slep)[~sfExpiration] = std::nullopt;
571 ctx_.view().update(slep);
572 }
573
574 if (ctx_.tx.getFlags() & tfClose)
575 {
576 // Channel will close immediately if dry or the receiver closes
577 if (dst == txAccount || (*slep)[sfBalance] == (*slep)[sfAmount])
578 return closeChannel(
579 slep, ctx_.view(), k.key, ctx_.app.journal("View"));
580
581 auto const settleExpiration =
583 (*slep)[sfSettleDelay];
584
585 if (!curExpiration || *curExpiration > settleExpiration)
586 {
587 (*slep)[~sfExpiration] = settleExpiration;
588 ctx_.view().update(slep);
589 }
590 }
591
592 return tesSUCCESS;
593}
594
595} // 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()
Definition: ApplyContext.h:55
Application & app
Definition: ApplyContext.h:48
beast::Journal const journal
Definition: ApplyContext.h:52
Writeable view to a ledger, for applying a transaction.
Definition: ApplyView.h:141
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.
Definition: ApplyView.cpp:190
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:315
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:414
static TER preclaim(PreclaimContext const &ctx)
Definition: PayChan.cpp:477
TER doApply() override
Definition: PayChan.cpp:490
static NotTEC preflight(PreflightContext const &ctx)
Definition: PayChan.cpp:175
TER doApply() override
Definition: PayChan.cpp:248
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:339
static NotTEC preflight(PreflightContext const &ctx)
Definition: PayChan.cpp:324
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
Definition: PayChan.cpp:318
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
SeqProxy getSeqProxy() const
Definition: STTx.cpp:213
constexpr std::uint32_t value() const
Definition: SeqProxy.h:82
Slice slice() const noexcept
Definition: Serializer.h:67
static TER preclaim(PreclaimContext const &ctx)
Definition: Transactor.h:147
ApplyContext & ctx_
Definition: Transactor.h:90
Class describing the consequences to the account of applying a transaction if the transaction consume...
Definition: applySteps.h:59
NotTEC checkFields(PreflightContext const &ctx)
TER valid(PreclaimContext const &ctx, AccountID const &src)
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:176
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition: Indexes.cpp:366
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Definition: Indexes.cpp:387
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
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:91
constexpr std::uint32_t tfRenew
Definition: TxFlags.h:135
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical=true) noexcept
Verify a signature on a message.
Definition: PublicKey.cpp:288
@ lsfRequireDestTag
@ lsfDisallowIncomingPayChan
@ lsfDisallowXRP
bool isTesSuccess(TER x)
Definition: TER.h:656
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition: View.cpp:925
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:83
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.
Definition: PublicKey.cpp:223
static bool adjustOwnerCount(ApplyContext &ctx, int count)
Definition: SetOracle.cpp:186
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:144
@ tecNO_ENTRY
Definition: TER.h:293
@ tecNO_DST
Definition: TER.h:277
@ tecUNFUNDED
Definition: TER.h:282
@ tecNO_TARGET
Definition: TER.h:291
@ tecDIR_FULL
Definition: TER.h:274
@ tecNO_PERMISSION
Definition: TER.h:292
@ tecDST_TAG_NEEDED
Definition: TER.h:296
@ tecUNFUNDED_PAYMENT
Definition: TER.h:272
@ tecINSUFFICIENT_RESERVE
Definition: TER.h:294
@ tecEXPIRED
Definition: TER.h:301
@ tesSUCCESS
Definition: TER.h:242
TER verifyDepositPreauth(ApplyContext &ctx, AccountID const &src, AccountID const &dst, std::shared_ptr< SLE > const &sleDst)
constexpr std::uint32_t tfClose
Definition: TxFlags.h:136
constexpr std::uint32_t tfPayChanClaimMask
Definition: TxFlags.h:137
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition: View.cpp:2127
constexpr std::uint32_t tfUniversalMask
Definition: TxFlags.h:62
@ terNO_ACCOUNT
Definition: TER.h:217
TERSubset< CanCvtToTER > TER
Definition: TER.h:627
@ 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.
Definition: protocol/Fees.h:49
A pair of SHAMap key and LedgerEntryType.
Definition: Keylet.h:39
uint256 key
Definition: Keylet.h:40
NetClock::time_point parentCloseTime
Definition: LedgerHeader.h:42
State information when determining if a tx is likely to claim a fee.
Definition: Transactor.h:55
ReadView const & view
Definition: Transactor.h:58
State information when preflighting a tx.
Definition: Transactor.h:34
T time_since_epoch(T... args)