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>
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>
123 AccountID const src = (*slep)[sfAccount];
126 auto const page = (*slep)[sfOwnerNode];
130 <<
"Could not remove paychan from src owner directory";
136 if (
auto const page = (*slep)[~sfDestinationNode];
137 page && view.
rules().enabled(fixPayChanRecipientOwnerDir))
139 auto const dst = (*slep)[sfDestination];
143 <<
"Could not remove paychan from dst owner directory";
154 (*slep)[sfAmount] >= (*slep)[sfBalance],
155 "ripple::closeChannel : minimum channel amount");
157 (*sle)[sfBalance] + (*slep)[sfAmount] - (*slep)[sfBalance];
183 if (!
isXRP(ctx.
tx[sfAmount]) || (ctx.
tx[sfAmount] <= beast::zero))
186 if (ctx.
tx[sfAccount] == ctx.
tx[sfDestination])
198 auto const account = ctx.
tx[sfAccount];
205 auto const balance = (*sle)[sfBalance];
209 if (balance < reserve)
212 if (balance < reserve + ctx.
tx[sfAmount])
216 auto const dst = ctx.
tx[sfDestination];
224 auto const flags = sled->getFlags();
256 auto const account =
ctx_.
tx[sfAccount];
268 auto const dst =
ctx_.
tx[sfDestination];
274 Keylet const payChanKeylet =
279 (*slep)[sfAmount] =
ctx_.
tx[sfAmount];
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];
300 (*slep)[sfOwnerNode] = *page;
310 (*slep)[sfDestinationNode] = *page;
314 (*sle)[sfBalance] = (*sle)[sfBalance] -
ctx_.
tx[sfAmount];
338 if (!
isXRP(ctx.
tx[sfAmount]) || (ctx.
tx[sfAmount] <= beast::zero))
352 AccountID const src = (*slep)[sfAccount];
353 auto const txAccount =
ctx_.
tx[sfAccount];
354 auto const expiration = (*slep)[~sfExpiration];
357 auto const cancelAfter = (*slep)[~sfCancelAfter];
358 auto const closeTime =
360 if ((cancelAfter && closeTime >= *cancelAfter) ||
361 (expiration && closeTime >= *expiration))
366 if (src != txAccount)
370 if (
auto extend =
ctx_.
tx[~sfExpiration])
374 (*slep)[sfSettleDelay];
375 if (expiration && *expiration < minExpiration)
376 minExpiration = *expiration;
378 if (*extend < minExpiration)
380 (*slep)[~sfExpiration] = *extend;
390 auto const balance = (*sle)[sfBalance];
394 if (balance < reserve)
397 if (balance < reserve +
ctx_.
tx[sfAmount])
402 if (
AccountID const dst = (*slep)[sfDestination];
408 (*slep)[sfAmount] = (*slep)[sfAmount] +
ctx_.
tx[sfAmount];
411 (*sle)[sfBalance] = (*sle)[sfBalance] -
ctx_.
tx[sfAmount];
429 auto const bal = ctx.
tx[~sfBalance];
430 if (bal && (!
isXRP(*bal) || *bal <= beast::zero))
433 auto const amt = ctx.
tx[~sfAmount];
434 if (amt && (!
isXRP(*amt) || *amt <= beast::zero))
437 if (bal && amt && *bal > *amt)
450 if (
auto const sig = ctx.
tx[~sfSignature])
452 if (!(ctx.
tx[~sfPublicKey] && bal))
459 auto const reqBalance = bal->xrp();
460 auto const authAmt = amt ? amt->xrp() : reqBalance;
462 if (reqBalance > authAmt)
465 Keylet const k(ltPAYCHAN, ctx.
tx[sfChannel]);
505 AccountID const src = (*slep)[sfAccount];
506 AccountID const dst = (*slep)[sfDestination];
509 auto const curExpiration = (*slep)[~sfExpiration];
511 auto const cancelAfter = (*slep)[~sfCancelAfter];
512 auto const closeTime =
514 if ((cancelAfter && closeTime >= *cancelAfter) ||
515 (curExpiration && closeTime >= *curExpiration))
520 if (txAccount != src && txAccount != dst)
525 auto const chanBalance = slep->getFieldAmount(sfBalance).xrp();
526 auto const chanFunds = slep->getFieldAmount(sfAmount).xrp();
527 auto const reqBalance =
ctx_.
tx[sfBalance].xrp();
529 if (txAccount == dst && !
ctx_.
tx[~sfSignature])
532 if (
ctx_.
tx[~sfSignature])
534 PublicKey const pk((*slep)[sfPublicKey]);
535 if (
ctx_.
tx[sfPublicKey] != pk)
539 if (reqBalance > chanFunds)
542 if (reqBalance <= chanBalance)
565 (*slep)[sfBalance] =
ctx_.
tx[sfBalance];
566 XRPAmount const reqDelta = reqBalance - chanBalance;
568 reqDelta >= beast::zero,
569 "ripple::PayChanClaim::doApply : minimum balance delta");
570 (*sled)[sfBalance] = (*sled)[sfBalance] + reqDelta;
577 if (src != txAccount)
586 if (dst == txAccount || (*slep)[sfBalance] == (*slep)[sfAmount])
590 auto const settleExpiration =
592 (*slep)[sfSettleDelay];
594 if (!curExpiration || *curExpiration > settleExpiration)
596 (*slep)[~sfExpiration] = settleExpiration;
A generic endpoint for log messages.
virtual beast::Journal journal(std::string const &name)=0
beast::Journal const journal
Writeable view to a ledger, for applying a transaction.
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.
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)
static TER preclaim(PreclaimContext const &ctx)
static NotTEC preflight(PreflightContext const &ctx)
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
static TER preclaim(PreclaimContext const &ctx)
static NotTEC preflight(PreflightContext const &ctx)
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
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.
bool isFieldPresent(SField const &field) const
std::uint32_t getFlags() const
std::uint32_t getSeqValue() const
Returns the first non-zero value of (Sequence, TicketSequence).
Slice slice() const noexcept
static TER preclaim(PreclaimContext const &ctx)
Class describing the consequences to the account of applying a transaction if the transaction consume...
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.
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
static TER closeChannel(std::shared_ptr< SLE > const &slep, ApplyView &view, uint256 const &key, beast::Journal j)
bool isXRP(AccountID const &c)
constexpr std::uint32_t tfRenew
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical=true) noexcept
Verify a signature on a message.
@ lsfDisallowIncomingPayChan
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
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)
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.
@ tecINSUFFICIENT_RESERVE
bool isTesSuccess(TER x) noexcept
constexpr std::uint32_t tfClose
constexpr std::uint32_t tfPayChanClaimMask
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
constexpr std::uint32_t tfUniversalMask
TERSubset< CanCvtToTER > TER
bool isPseudoAccount(std::shared_ptr< SLE const > sleAcct)
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
A pair of SHAMap key and LedgerEntryType.
State information when determining if a tx is likely to claim a fee.
State information when preflighting a tx.
T time_since_epoch(T... args)