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#include <xrpl/basics/Log.h>
25#include <xrpl/basics/chrono.h>
26#include <xrpl/protocol/Feature.h>
27#include <xrpl/protocol/Indexes.h>
28#include <xrpl/protocol/PayChan.h>
29#include <xrpl/protocol/PublicKey.h>
30#include <xrpl/protocol/TxFlags.h>
31#include <xrpl/protocol/XRPAmount.h>
32#include <xrpl/protocol/digest.h>
33#include <xrpl/protocol/st.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 auto const dst = ctx_.tx[sfDestination];
256
257 // Create PayChan in ledger.
258 //
259 // Note that we we use the value from the sequence or ticket as the
260 // payChan sequence. For more explanation see comments in SeqProxy.h.
261 Keylet const payChanKeylet =
262 keylet::payChan(account, dst, ctx_.tx.getSeqProxy().value());
263 auto const slep = std::make_shared<SLE>(payChanKeylet);
264
265 // Funds held in this channel
266 (*slep)[sfAmount] = ctx_.tx[sfAmount];
267 // Amount channel has already paid
268 (*slep)[sfBalance] = ctx_.tx[sfAmount].zeroed();
269 (*slep)[sfAccount] = account;
270 (*slep)[sfDestination] = dst;
271 (*slep)[sfSettleDelay] = ctx_.tx[sfSettleDelay];
272 (*slep)[sfPublicKey] = ctx_.tx[sfPublicKey];
273 (*slep)[~sfCancelAfter] = ctx_.tx[~sfCancelAfter];
274 (*slep)[~sfSourceTag] = ctx_.tx[~sfSourceTag];
275 (*slep)[~sfDestinationTag] = ctx_.tx[~sfDestinationTag];
276
277 ctx_.view().insert(slep);
278
279 // Add PayChan to owner directory
280 {
281 auto const page = ctx_.view().dirInsert(
282 keylet::ownerDir(account),
283 payChanKeylet,
284 describeOwnerDir(account));
285 if (!page)
286 return tecDIR_FULL;
287 (*slep)[sfOwnerNode] = *page;
288 }
289
290 // Add PayChan to the recipient's owner directory
291 if (ctx_.view().rules().enabled(fixPayChanRecipientOwnerDir))
292 {
293 auto const page = ctx_.view().dirInsert(
294 keylet::ownerDir(dst), payChanKeylet, describeOwnerDir(dst));
295 if (!page)
296 return tecDIR_FULL;
297 (*slep)[sfDestinationNode] = *page;
298 }
299
300 // Deduct owner's balance, increment owner count
301 (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
303 ctx_.view().update(sle);
304
305 return tesSUCCESS;
306}
307
308//------------------------------------------------------------------------------
309
312{
313 return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()};
314}
315
316NotTEC
318{
319 if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
320 return temINVALID_FLAG;
321
322 if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
323 return ret;
324
325 if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero))
326 return temBAD_AMOUNT;
327
328 return preflight2(ctx);
329}
330
331TER
333{
334 Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]);
335 auto const slep = ctx_.view().peek(k);
336 if (!slep)
337 return tecNO_ENTRY;
338
339 AccountID const src = (*slep)[sfAccount];
340 auto const txAccount = ctx_.tx[sfAccount];
341 auto const expiration = (*slep)[~sfExpiration];
342
343 {
344 auto const cancelAfter = (*slep)[~sfCancelAfter];
345 auto const closeTime =
347 if ((cancelAfter && closeTime >= *cancelAfter) ||
348 (expiration && closeTime >= *expiration))
349 return closeChannel(
350 slep, ctx_.view(), k.key, ctx_.app.journal("View"));
351 }
352
353 if (src != txAccount)
354 // only the owner can add funds or extend
355 return tecNO_PERMISSION;
356
357 if (auto extend = ctx_.tx[~sfExpiration])
358 {
359 auto minExpiration =
361 (*slep)[sfSettleDelay];
362 if (expiration && *expiration < minExpiration)
363 minExpiration = *expiration;
364
365 if (*extend < minExpiration)
366 return temBAD_EXPIRATION;
367 (*slep)[~sfExpiration] = *extend;
368 ctx_.view().update(slep);
369 }
370
371 auto const sle = ctx_.view().peek(keylet::account(txAccount));
372 if (!sle)
373 return tefINTERNAL;
374
375 {
376 // Check reserve and funds availability
377 auto const balance = (*sle)[sfBalance];
378 auto const reserve =
379 ctx_.view().fees().accountReserve((*sle)[sfOwnerCount]);
380
381 if (balance < reserve)
383
384 if (balance < reserve + ctx_.tx[sfAmount])
385 return tecUNFUNDED;
386 }
387
388 // do not allow adding funds if dst does not exist
389 if (AccountID const dst = (*slep)[sfDestination];
390 !ctx_.view().read(keylet::account(dst)))
391 {
392 return tecNO_DST;
393 }
394
395 (*slep)[sfAmount] = (*slep)[sfAmount] + ctx_.tx[sfAmount];
396 ctx_.view().update(slep);
397
398 (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
399 ctx_.view().update(sle);
400
401 return tesSUCCESS;
402}
403
404//------------------------------------------------------------------------------
405
406NotTEC
408{
409 if (ctx.tx.isFieldPresent(sfCredentialIDs) &&
410 !ctx.rules.enabled(featureCredentials))
411 return temDISABLED;
412
413 if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
414 return ret;
415
416 auto const bal = ctx.tx[~sfBalance];
417 if (bal && (!isXRP(*bal) || *bal <= beast::zero))
418 return temBAD_AMOUNT;
419
420 auto const amt = ctx.tx[~sfAmount];
421 if (amt && (!isXRP(*amt) || *amt <= beast::zero))
422 return temBAD_AMOUNT;
423
424 if (bal && amt && *bal > *amt)
425 return temBAD_AMOUNT;
426
427 {
428 auto const flags = ctx.tx.getFlags();
429
430 if (ctx.rules.enabled(fix1543) && (flags & tfPayChanClaimMask))
431 return temINVALID_FLAG;
432
433 if ((flags & tfClose) && (flags & tfRenew))
434 return temMALFORMED;
435 }
436
437 if (auto const sig = ctx.tx[~sfSignature])
438 {
439 if (!(ctx.tx[~sfPublicKey] && bal))
440 return temMALFORMED;
441
442 // Check the signature
443 // The signature isn't needed if txAccount == src, but if it's
444 // present, check it
445
446 auto const reqBalance = bal->xrp();
447 auto const authAmt = amt ? amt->xrp() : reqBalance;
448
449 if (reqBalance > authAmt)
450 return temBAD_AMOUNT;
451
452 Keylet const k(ltPAYCHAN, ctx.tx[sfChannel]);
453 if (!publicKeyType(ctx.tx[sfPublicKey]))
454 return temMALFORMED;
455
456 PublicKey const pk(ctx.tx[sfPublicKey]);
457 Serializer msg;
458 serializePayChanAuthorization(msg, k.key, authAmt);
459 if (!verify(pk, msg.slice(), *sig, /*canonical*/ true))
460 return temBAD_SIGNATURE;
461 }
462
463 if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err))
464 return err;
465
466 return preflight2(ctx);
467}
468
469TER
471{
472 if (!ctx.view.rules().enabled(featureCredentials))
473 return Transactor::preclaim(ctx);
474
475 if (auto const err = credentials::valid(ctx, ctx.tx[sfAccount]);
476 !isTesSuccess(err))
477 return err;
478
479 return tesSUCCESS;
480}
481
482TER
484{
485 Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]);
486 auto const slep = ctx_.view().peek(k);
487 if (!slep)
488 return tecNO_TARGET;
489
490 AccountID const src = (*slep)[sfAccount];
491 AccountID const dst = (*slep)[sfDestination];
492 AccountID const txAccount = ctx_.tx[sfAccount];
493
494 auto const curExpiration = (*slep)[~sfExpiration];
495 {
496 auto const cancelAfter = (*slep)[~sfCancelAfter];
497 auto const closeTime =
499 if ((cancelAfter && closeTime >= *cancelAfter) ||
500 (curExpiration && closeTime >= *curExpiration))
501 return closeChannel(
502 slep, ctx_.view(), k.key, ctx_.app.journal("View"));
503 }
504
505 if (txAccount != src && txAccount != dst)
506 return tecNO_PERMISSION;
507
508 if (ctx_.tx[~sfBalance])
509 {
510 auto const chanBalance = slep->getFieldAmount(sfBalance).xrp();
511 auto const chanFunds = slep->getFieldAmount(sfAmount).xrp();
512 auto const reqBalance = ctx_.tx[sfBalance].xrp();
513
514 if (txAccount == dst && !ctx_.tx[~sfSignature])
515 return temBAD_SIGNATURE;
516
517 if (ctx_.tx[~sfSignature])
518 {
519 PublicKey const pk((*slep)[sfPublicKey]);
520 if (ctx_.tx[sfPublicKey] != pk)
521 return temBAD_SIGNER;
522 }
523
524 if (reqBalance > chanFunds)
525 return tecUNFUNDED_PAYMENT;
526
527 if (reqBalance <= chanBalance)
528 // nothing requested
529 return tecUNFUNDED_PAYMENT;
530
531 auto const sled = ctx_.view().peek(keylet::account(dst));
532 if (!sled)
533 return tecNO_DST;
534
535 // Obeying the lsfDisallowXRP flag was a bug. Piggyback on
536 // featureDepositAuth to remove the bug.
537 bool const depositAuth{ctx_.view().rules().enabled(featureDepositAuth)};
538 if (!depositAuth &&
539 (txAccount == src && (sled->getFlags() & lsfDisallowXRP)))
540 return tecNO_TARGET;
541
542 if (depositAuth)
543 {
544 if (auto err = verifyDepositPreauth(ctx_, txAccount, dst, sled);
545 !isTesSuccess(err))
546 return err;
547 }
548
549 (*slep)[sfBalance] = ctx_.tx[sfBalance];
550 XRPAmount const reqDelta = reqBalance - chanBalance;
551 XRPL_ASSERT(
552 reqDelta >= beast::zero,
553 "ripple::PayChanClaim::doApply : minimum balance delta");
554 (*sled)[sfBalance] = (*sled)[sfBalance] + reqDelta;
555 ctx_.view().update(sled);
556 ctx_.view().update(slep);
557 }
558
559 if (ctx_.tx.getFlags() & tfRenew)
560 {
561 if (src != txAccount)
562 return tecNO_PERMISSION;
563 (*slep)[~sfExpiration] = std::nullopt;
564 ctx_.view().update(slep);
565 }
566
567 if (ctx_.tx.getFlags() & tfClose)
568 {
569 // Channel will close immediately if dry or the receiver closes
570 if (dst == txAccount || (*slep)[sfBalance] == (*slep)[sfAmount])
571 return closeChannel(
572 slep, ctx_.view(), k.key, ctx_.app.journal("View"));
573
574 auto const settleExpiration =
576 (*slep)[sfSettleDelay];
577
578 if (!curExpiration || *curExpiration > settleExpiration)
579 {
580 (*slep)[~sfExpiration] = settleExpiration;
581 ctx_.view().update(slep);
582 }
583 }
584
585 return tesSUCCESS;
586}
587
588} // namespace ripple
A generic endpoint for log messages.
Definition: Journal.h:59
Stream fatal() const
Definition: Journal.h:341
virtual beast::Journal journal(std::string const &name)=0
ApplyView & view()
Definition: ApplyContext.h:54
Application & app
Definition: ApplyContext.h:47
beast::Journal const journal
Definition: ApplyContext.h:51
Writeable view to a ledger, for applying a transaction.
Definition: ApplyView.h:140
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:189
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:314
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:407
static TER preclaim(PreclaimContext const &ctx)
Definition: PayChan.cpp:470
TER doApply() override
Definition: PayChan.cpp:483
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:332
static NotTEC preflight(PreflightContext const &ctx)
Definition: PayChan.cpp:317
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
Definition: PayChan.cpp:311
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:122
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:454
std::uint32_t getFlags() const
Definition: STObject.cpp:507
SeqProxy getSeqProxy() const
Definition: STTx.cpp:186
constexpr std::uint32_t value() const
Definition: SeqProxy.h:82
Slice slice() const noexcept
Definition: Serializer.h:66
static TER preclaim(PreclaimContext const &ctx)
Definition: Transactor.h:145
ApplyContext & ctx_
Definition: Transactor.h:88
Class describing the consequences to the account of applying a transaction if the transaction consume...
Definition: applySteps.h:58
NotTEC checkFields(PreflightContext const &ctx)
TER valid(PreclaimContext const &ctx, AccountID const &src)
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:160
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition: Indexes.cpp:350
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Definition: Indexes.cpp:371
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:128
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical=true) noexcept
Verify a signature on a message.
Definition: PublicKey.cpp:272
@ 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:82
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:207
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:134
@ 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
@ 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:129
constexpr std::uint32_t tfPayChanClaimMask
Definition: TxFlags.h:130
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:53
ReadView const & view
Definition: Transactor.h:56
State information when preflighting a tx.
Definition: Transactor.h:32
T time_since_epoch(T... args)