20#include <xrpld/app/paths/detail/AmountSpec.h>
21#include <xrpld/ledger/PaymentSandbox.h>
22#include <xrpld/ledger/View.h>
23#include <xrpl/beast/utility/instrumentation.h>
24#include <xrpl/protocol/Feature.h>
25#include <xrpl/protocol/SField.h>
26#include <xrpl/protocol/STAccount.h>
49 STAmount const& preCreditSenderBalance)
53 "ripple::detail::DeferredCredits::credit : sender is not receiver");
56 "ripple::detail::DeferredCredits::credit : positive amount");
64 if (sender < receiver)
83 if (sender < receiver)
86 v.lowAcctCredits += amount;
100 auto& mapVal = r.first->second;
123 Key const k = makeKey(main, other, currency);
124 auto i = credits_.find(k);
125 if (i == credits_.end())
128 auto const& v = i->second;
133 v.highAcctCredits, v.lowAcctCredits, v.lowAcctOrigBalance);
139 v.lowAcctCredits, v.highAcctCredits, -v.lowAcctOrigBalance);
152 auto& toVal = r.first->second;
153 auto const& fromVal = i.second;
154 toVal.lowAcctCredits += fromVal.lowAcctCredits;
155 toVal.highAcctCredits += fromVal.highAcctCredits;
165 auto& toVal = r.first->second;
166 auto const& fromVal = i.second;
193 auto delta = amount.
zeroed();
194 auto lastBal = amount;
195 auto minBal = amount;
196 for (
auto curSB =
this; curSB; curSB = curSB->ps_)
198 if (
auto adj = curSB->tab_.adjustments(account, issuer, currency))
200 delta += adj->debits;
201 lastBal = adj->origBalance;
202 if (lastBal < minBal)
211 auto adjustedAmt =
std::min({amount, lastBal - delta, minBal});
212 adjustedAmt.setIssuer(amount.
getIssuer());
214 if (
isXRP(issuer) && adjustedAmt < beast::zero)
229 for (
auto curSB =
this; curSB; curSB = curSB->ps_)
231 if (
auto adj = curSB->tab_.ownerCount(account))
244 tab_.
credit(from, to, amount, preCreditBalance);
259 XRPL_ASSERT(!
ps_,
"ripple::PaymentSandbox::apply : non-null sandbox");
266 XRPL_ASSERT(
ps_ == &to,
"ripple::PaymentSandbox::apply : matching sandbox");
283 auto each = [&result](
299 auto const bt = before->getType();
304 highID = (*before)[sfAccount];
305 oldBalance = (*before)[sfBalance];
306 newBalance = oldBalance.
zeroed();
309 lowID = (*before)[sfLowLimit].getIssuer();
310 highID = (*before)[sfHighLimit].getIssuer();
311 oldBalance = (*before)[sfBalance];
312 newBalance = oldBalance.
zeroed();
324 auto const at =
after->getType();
329 highID = (*after)[sfAccount];
330 newBalance = (*after)[sfBalance];
331 oldBalance = newBalance.
zeroed();
334 lowID = (*after)[sfLowLimit].getIssuer();
335 highID = (*after)[sfHighLimit].getIssuer();
336 newBalance = (*after)[sfBalance];
337 oldBalance = newBalance.
zeroed();
349 auto const at =
after->getType();
351 at == before->getType(),
352 "ripple::PaymentSandbox::balanceChanges : after and before "
358 highID = (*after)[sfAccount];
359 oldBalance = (*before)[sfBalance];
360 newBalance = (*after)[sfBalance];
363 lowID = (*after)[sfLowLimit].getIssuer();
364 highID = (*after)[sfHighLimit].getIssuer();
365 oldBalance = (*before)[sfBalance];
366 newBalance = (*after)[sfBalance];
376 auto delta = newBalance - oldBalance;
382 r.first->second += delta;
389 r.first->second += delta;
A wrapper which makes credits unavailable to balances.
XRPAmount xrpDestroyed() const
std::uint32_t ownerCountHook(AccountID const &account, std::uint32_t count) const override
std::map< std::tuple< AccountID, AccountID, Currency >, STAmount > balanceChanges(ReadView const &view) const
void creditHook(AccountID const &from, AccountID const &to, STAmount const &amount, STAmount const &preCreditBalance) override
void apply(RawView &to)
Apply changes to base view.
detail::DeferredCredits tab_
STAmount balanceHook(AccountID const &account, AccountID const &issuer, STAmount const &amount) const override
void adjustOwnerCountHook(AccountID const &account, std::uint32_t cur, std::uint32_t next) override
PaymentSandbox const * ps_
Interface for ledger entry changes.
Currency const & getCurrency() const
bool negative() const noexcept
AccountID const & getIssuer() const
STAmount zeroed() const
Returns a zero value with the same issuer and currency.
XRPAmount const & dropsDestroyed() const
void visit(ReadView const &base, std::function< void(uint256 const &key, bool isDelete, std::shared_ptr< SLE const > const &before, std::shared_ptr< SLE const > const &after)> const &func) const
void apply(RawView &to) const
detail::ApplyStateTable items_
std::optional< Adjustment > adjustments(AccountID const &main, AccountID const &other, Currency const ¤cy) const
void credit(AccountID const &sender, AccountID const &receiver, STAmount const &amount, STAmount const &preCreditSenderBalance)
void apply(DeferredCredits &to)
std::map< AccountID, std::uint32_t > ownerCounts_
void ownerCount(AccountID const &id, std::uint32_t cur, std::uint32_t next)
std::map< Key, Value > credits_
static Key makeKey(AccountID const &a1, AccountID const &a2, Currency const &c)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
bool isXRP(AccountID const &c)
AccountID const & xrpAccount()
Compute AccountID from public key.
static bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
STAmount lowAcctOrigBalance