mirror of
https://github.com/XRPLF/rippled.git
synced 2026-09-29 00:08:10 +00:00
migrate lending helpers
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/SLEWrappers.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h> // IWYU pragma: keep
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
@@ -48,7 +49,7 @@ namespace xrpl {
|
||||
[[nodiscard]] TER
|
||||
canApplyToBrokerCover(
|
||||
ReadView const& view,
|
||||
SLE::const_ref sleBroker,
|
||||
LoanBrokerEntry<ReadView> const& sleBroker,
|
||||
Asset const& vaultAsset,
|
||||
STAmount const& amount,
|
||||
beast::Journal j,
|
||||
@@ -214,7 +215,7 @@ adjustImpreciseNumber(
|
||||
}
|
||||
|
||||
inline int
|
||||
getAssetsTotalScale(SLE::const_ref vaultSle)
|
||||
getAssetsTotalScale(VaultEntry<ReadView> const& vaultSle)
|
||||
{
|
||||
if (!vaultSle)
|
||||
return Number::kMinExponent - 1; // LCOV_EXCL_LINE
|
||||
@@ -225,7 +226,10 @@ getAssetsTotalScale(SLE::const_ref vaultSle)
|
||||
// DebtTotal is a broker-level aggregate maintained at vault scale, so the
|
||||
// rounding must also use vault scale — never an individual loan's scale.
|
||||
inline Number
|
||||
minimumBrokerCover(Number const& debtTotal, TenthBips32 coverRateMinimum, SLE::const_ref vaultSle)
|
||||
minimumBrokerCover(
|
||||
Number const& debtTotal,
|
||||
TenthBips32 coverRateMinimum,
|
||||
VaultEntry<ReadView> const& vaultSle)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
vaultSle && vaultSle->getType() == ltVAULT, "xrpl::minimumBrokerCover : valid Vault sle");
|
||||
@@ -263,7 +267,7 @@ constructLoanState(
|
||||
// Constructs a valid LoanState object from a Loan object, which always has
|
||||
// rounded values
|
||||
LoanState
|
||||
constructRoundedLoanState(SLE::const_ref loan);
|
||||
constructRoundedLoanState(LoanEntry<ReadView> const& loan);
|
||||
|
||||
Number
|
||||
computeManagementFee(
|
||||
@@ -545,8 +549,8 @@ std::expected<LoanPaymentParts, TER>
|
||||
loanMakePayment(
|
||||
Asset const& asset,
|
||||
ApplyView& view,
|
||||
SLE::ref loan,
|
||||
SLE::const_ref brokerSle,
|
||||
LoanEntry<ApplyView>& loan,
|
||||
LoanBrokerEntry<ReadView> const& brokerSle,
|
||||
STAmount const& amount,
|
||||
LoanPaymentType const paymentType,
|
||||
beast::Journal j);
|
||||
|
||||
@@ -177,7 +177,10 @@ public:
|
||||
return j_;
|
||||
}
|
||||
|
||||
protected:
|
||||
// --- Constructors that adopt/resolve an SLE (public so the ReadOnlySLE /
|
||||
// WritableSLE aliases and the per-type wrappers can be built directly
|
||||
// from an already-fetched SLE or a keylet). ---
|
||||
|
||||
/** Constructor for read-only context */
|
||||
explicit SLEBase(
|
||||
SLE::const_pointer sle,
|
||||
@@ -233,6 +236,7 @@ protected:
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
view_ref_type view_{};
|
||||
|
||||
// Keylet is only meaningful for writable views, but we conditionally
|
||||
@@ -247,4 +251,15 @@ protected:
|
||||
beast::Journal j_;
|
||||
};
|
||||
|
||||
/** Generic (any-entry-type) SLE handles.
|
||||
*
|
||||
* Use these when the concrete ledger entry type is not known at a given site;
|
||||
* otherwise prefer the per-type wrappers in SLEWrappers.h.
|
||||
*
|
||||
* SLE::const_pointer / SLE::const_ref -> ReadOnlySLE
|
||||
* SLE::pointer / SLE::ref -> WritableSLE
|
||||
*/
|
||||
using ReadOnlySLE = SLEBase<ReadView>;
|
||||
using WritableSLE = SLEBase<ApplyView>;
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -14,8 +14,8 @@ namespace xrpl {
|
||||
* than translate the entry's "keylet parts" (the arguments to its keylet::
|
||||
* function) into a Keylet that the base class resolves against the view:
|
||||
*
|
||||
* AccountRoot<ApplyView> acct{id, view}; // peek (writable)
|
||||
* AccountRoot<ReadView> acct{id, readView}; // read (read-only)
|
||||
* AccountRootEntry<ApplyView> acct{id, view}; // peek (writable)
|
||||
* AccountRootEntry<ReadView> acct{id, readView}; // read (read-only)
|
||||
*
|
||||
* Domain-specific accessors will be layered onto each wrapper over time.
|
||||
*/
|
||||
@@ -23,10 +23,14 @@ namespace xrpl {
|
||||
// Ordered to match include/xrpl/protocol/detail/ledger_entries.macro.
|
||||
|
||||
template <typename ViewT>
|
||||
class NFTokenOffer : public SLEBase<ViewT>
|
||||
class NFTokenOfferEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit NFTokenOffer(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit NFTokenOfferEntry(
|
||||
AccountID const& owner,
|
||||
std::uint32_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -37,10 +41,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Check : public SLEBase<ViewT>
|
||||
class CheckEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Check(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit CheckEntry(
|
||||
AccountID const& id,
|
||||
std::uint32_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -51,10 +59,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class DID : public SLEBase<ViewT>
|
||||
class DIDEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit DID(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit DIDEntry(
|
||||
AccountID const& account,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
@@ -64,10 +76,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class NegativeUNL : public SLEBase<ViewT>
|
||||
class NegativeUNLEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit NegativeUNL(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit NegativeUNLEntry(
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::negativeUNL(), view, j)
|
||||
@@ -76,10 +92,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class NFTokenPage : public SLEBase<ViewT>
|
||||
class NFTokenPageEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit NFTokenPage(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit NFTokenPageEntry(
|
||||
Keylet const& page,
|
||||
uint256 const& token,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -90,10 +110,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class SignerList : public SLEBase<ViewT>
|
||||
class SignerListEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit SignerList(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit SignerListEntry(
|
||||
AccountID const& account,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
@@ -103,10 +127,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Ticket : public SLEBase<ViewT>
|
||||
class TicketEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Ticket(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit TicketEntry(
|
||||
AccountID const& id,
|
||||
std::uint32_t ticketSeq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -117,10 +145,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class AccountRoot : public SLEBase<ViewT>
|
||||
class AccountRootEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit AccountRoot(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit AccountRootEntry(
|
||||
AccountID const& id,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
@@ -130,10 +162,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class DirectoryNode : public SLEBase<ViewT>
|
||||
class DirectoryNodeEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit DirectoryNode(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit DirectoryNodeEntry(
|
||||
AccountID const& id,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
@@ -143,10 +179,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Amendments : public SLEBase<ViewT>
|
||||
class AmendmentsEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Amendments(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit AmendmentsEntry(
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::amendments(), view, j)
|
||||
@@ -155,10 +195,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class LedgerHashes : public SLEBase<ViewT>
|
||||
class LedgerHashesEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit LedgerHashes(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit LedgerHashesEntry(
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::skip(), view, j)
|
||||
@@ -167,10 +211,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Bridge : public SLEBase<ViewT>
|
||||
class BridgeEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Bridge(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit BridgeEntry(
|
||||
STXChainBridge const& bridge,
|
||||
STXChainBridge::ChainType chainType,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -181,10 +229,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Offer : public SLEBase<ViewT>
|
||||
class OfferEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Offer(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit OfferEntry(
|
||||
AccountID const& id,
|
||||
std::uint32_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -195,10 +247,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class DepositPreauth : public SLEBase<ViewT>
|
||||
class DepositPreauthEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit DepositPreauth(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit DepositPreauthEntry(
|
||||
AccountID const& owner,
|
||||
AccountID const& preauthorized,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -209,10 +265,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class XChainOwnedClaimID : public SLEBase<ViewT>
|
||||
class XChainOwnedClaimIDEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit XChainOwnedClaimID(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit XChainOwnedClaimIDEntry(
|
||||
STXChainBridge const& bridge,
|
||||
std::uint64_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -223,10 +283,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class RippleState : public SLEBase<ViewT>
|
||||
class RippleStateEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit RippleState(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit RippleStateEntry(
|
||||
AccountID const& id0,
|
||||
AccountID const& id1,
|
||||
Currency const& currency,
|
||||
@@ -238,10 +302,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class FeeSettings : public SLEBase<ViewT>
|
||||
class FeeSettingsEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit FeeSettings(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit FeeSettingsEntry(
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::feeSettings(), view, j)
|
||||
@@ -250,10 +318,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class XChainOwnedCreateAccountClaimID : public SLEBase<ViewT>
|
||||
class XChainOwnedCreateAccountClaimIDEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit XChainOwnedCreateAccountClaimID(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit XChainOwnedCreateAccountClaimIDEntry(
|
||||
STXChainBridge const& bridge,
|
||||
std::uint64_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -264,10 +336,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Escrow : public SLEBase<ViewT>
|
||||
class EscrowEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Escrow(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit EscrowEntry(
|
||||
AccountID const& src,
|
||||
std::uint32_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -278,10 +354,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class PayChannel : public SLEBase<ViewT>
|
||||
class PayChannelEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit PayChannel(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit PayChannelEntry(
|
||||
AccountID const& src,
|
||||
AccountID const& dst,
|
||||
std::uint32_t seq,
|
||||
@@ -293,10 +373,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class AMM : public SLEBase<ViewT>
|
||||
class AMMEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit AMM(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit AMMEntry(
|
||||
Asset const& issue1,
|
||||
Asset const& issue2,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -307,10 +391,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class MPTokenIssuance : public SLEBase<ViewT>
|
||||
class MPTokenIssuanceEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit MPTokenIssuance(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit MPTokenIssuanceEntry(
|
||||
std::uint32_t seq,
|
||||
AccountID const& issuer,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -321,10 +409,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class MPToken : public SLEBase<ViewT>
|
||||
class MPTokenEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit MPToken(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit MPTokenEntry(
|
||||
MPTID const& issuanceID,
|
||||
AccountID const& holder,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -335,10 +427,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Oracle : public SLEBase<ViewT>
|
||||
class OracleEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Oracle(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit OracleEntry(
|
||||
AccountID const& account,
|
||||
std::uint32_t documentID,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -349,10 +445,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Credential : public SLEBase<ViewT>
|
||||
class CredentialEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Credential(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit CredentialEntry(
|
||||
AccountID const& subject,
|
||||
AccountID const& issuer,
|
||||
Slice const& credType,
|
||||
@@ -364,10 +464,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class PermissionedDomain : public SLEBase<ViewT>
|
||||
class PermissionedDomainEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit PermissionedDomain(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit PermissionedDomainEntry(
|
||||
AccountID const& account,
|
||||
std::uint32_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -378,10 +482,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Delegate : public SLEBase<ViewT>
|
||||
class DelegateEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Delegate(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit DelegateEntry(
|
||||
AccountID const& account,
|
||||
AccountID const& authorizedAccount,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -392,10 +500,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Vault : public SLEBase<ViewT>
|
||||
class VaultEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Vault(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit VaultEntry(
|
||||
AccountID const& owner,
|
||||
std::uint32_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -406,10 +518,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class LoanBroker : public SLEBase<ViewT>
|
||||
class LoanBrokerEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit LoanBroker(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit LoanBrokerEntry(
|
||||
AccountID const& owner,
|
||||
std::uint32_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -420,10 +536,14 @@ public:
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Loan : public SLEBase<ViewT>
|
||||
class LoanEntry : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Loan(
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using SLEBase<ViewT>::SLEBase;
|
||||
|
||||
explicit LoanEntry(
|
||||
uint256 const& loanBrokerID,
|
||||
std::uint32_t loanSeq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
@@ -433,18 +553,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Sponsorship : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Sponsorship(
|
||||
AccountID const& sponsor,
|
||||
AccountID const& sponsee,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::sponsorship(sponsor, sponsee), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/STXChainBridge.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
@@ -363,20 +362,10 @@ struct KeyletDesc
|
||||
};
|
||||
|
||||
// This list should include all of the keylet functions that take a single
|
||||
// AccountID parameter.
|
||||
std::array<KeyletDesc<AccountID const&>, 6> const kDirectAccountKeylets{
|
||||
{{.function = &keylet::account, .expectedLEName = jss::AccountRoot, .includeInTests = false},
|
||||
{.function = &keylet::ownerDir, .expectedLEName = jss::DirectoryNode, .includeInTests = true},
|
||||
{.function = &keylet::signerList, .expectedLEName = jss::SignerList, .includeInTests = true},
|
||||
// It's normally impossible to create an item at nftpage_min, but
|
||||
// test it anyway, since the invariant checks for it.
|
||||
{.function = &keylet::nftokenPageMin,
|
||||
.expectedLEName = jss::NFTokenPage,
|
||||
.includeInTests = true},
|
||||
{.function = &keylet::nftokenPageMax,
|
||||
.expectedLEName = jss::NFTokenPage,
|
||||
.includeInTests = true},
|
||||
{.function = &keylet::did, .expectedLEName = jss::DID, .includeInTests = true}}};
|
||||
// AccountID parameter. Defined in Indexes.cpp so that this header does not
|
||||
// need to include jss.h (which transitively re-includes transactions.macro
|
||||
// and breaks headers processed inside the TRANSACTION_INCLUDE machinery).
|
||||
extern std::array<KeyletDesc<AccountID const&>, 6> const kDirectAccountKeylets;
|
||||
|
||||
MPTID
|
||||
makeMptID(std::uint32_t sequence, AccountID const& account);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/SLEWrappers.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
@@ -41,9 +42,9 @@ public:
|
||||
static TER
|
||||
defaultLoan(
|
||||
ApplyView& view,
|
||||
SLE::ref loanSle,
|
||||
SLE::ref brokerSle,
|
||||
SLE::ref vaultSle,
|
||||
LoanEntry<ApplyView>& loanSle,
|
||||
LoanBrokerEntry<ApplyView>& brokerSle,
|
||||
VaultEntry<ApplyView>& vaultSle,
|
||||
Asset const& vaultAsset,
|
||||
beast::Journal j);
|
||||
|
||||
@@ -52,8 +53,8 @@ public:
|
||||
static TER
|
||||
impairLoan(
|
||||
ApplyView& view,
|
||||
SLE::ref loanSle,
|
||||
SLE::ref vaultSle,
|
||||
LoanEntry<ApplyView>& loanSle,
|
||||
VaultEntry<ApplyView>& vaultSle,
|
||||
Asset const& vaultAsset,
|
||||
beast::Journal j);
|
||||
|
||||
@@ -62,8 +63,8 @@ public:
|
||||
[[nodiscard]] static TER
|
||||
unimpairLoan(
|
||||
ApplyView& view,
|
||||
SLE::ref loanSle,
|
||||
SLE::ref vaultSle,
|
||||
LoanEntry<ApplyView>& loanSle,
|
||||
VaultEntry<ApplyView>& vaultSle,
|
||||
Asset const& vaultAsset,
|
||||
beast::Journal j);
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace xrpl {
|
||||
[[nodiscard]] TER
|
||||
canApplyToBrokerCover(
|
||||
ReadView const& view,
|
||||
SLE::const_ref sleBroker,
|
||||
LoanBrokerEntry<ReadView> const& sleBroker,
|
||||
Asset const& vaultAsset,
|
||||
STAmount const& amount,
|
||||
beast::Journal j,
|
||||
@@ -1632,7 +1632,7 @@ constructLoanState(
|
||||
}
|
||||
|
||||
LoanState
|
||||
constructRoundedLoanState(SLE::const_ref loan)
|
||||
constructRoundedLoanState(LoanEntry<ReadView> const& loan)
|
||||
{
|
||||
return constructLoanState(
|
||||
loan->at(sfTotalValueOutstanding),
|
||||
@@ -1784,8 +1784,8 @@ std::expected<LoanPaymentParts, TER>
|
||||
loanMakePayment(
|
||||
Asset const& asset,
|
||||
ApplyView& view,
|
||||
SLE::ref loan,
|
||||
SLE::const_ref brokerSle,
|
||||
LoanEntry<ApplyView>& loan,
|
||||
LoanBrokerEntry<ReadView> const& brokerSle,
|
||||
STAmount const& amount,
|
||||
LoanPaymentType const paymentType,
|
||||
beast::Journal j)
|
||||
@@ -1836,7 +1836,7 @@ loanMakePayment(
|
||||
|
||||
XRPL_ASSERT(*totalValueOutstandingProxy > 0, "xrpl::loanMakePayment : valid total value");
|
||||
|
||||
view.update(loan);
|
||||
loan.update();
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// A late payment not flagged as late overrides all other options.
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/protocol/nftPageMask.h>
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
@@ -32,6 +33,23 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// This list should include all of the keylet functions that take a single
|
||||
// AccountID parameter. Declared in Indexes.h; defined here so the header need
|
||||
// not include jss.h.
|
||||
std::array<KeyletDesc<AccountID const&>, 6> const kDirectAccountKeylets{
|
||||
{{.function = &keylet::account, .expectedLEName = jss::AccountRoot, .includeInTests = false},
|
||||
{.function = &keylet::ownerDir, .expectedLEName = jss::DirectoryNode, .includeInTests = true},
|
||||
{.function = &keylet::signerList, .expectedLEName = jss::SignerList, .includeInTests = true},
|
||||
// It's normally impossible to create an item at nftpage_min, but
|
||||
// test it anyway, since the invariant checks for it.
|
||||
{.function = &keylet::nftokenPageMin,
|
||||
.expectedLEName = jss::NFTokenPage,
|
||||
.includeInTests = true},
|
||||
{.function = &keylet::nftokenPageMax,
|
||||
.expectedLEName = jss::NFTokenPage,
|
||||
.includeInTests = true},
|
||||
{.function = &keylet::did, .expectedLEName = jss::DID, .includeInTests = true}}};
|
||||
|
||||
/** Type-specific prefix for calculating ledger indices.
|
||||
|
||||
The identifier for a given object within the ledger is calculated based
|
||||
|
||||
@@ -161,7 +161,7 @@ determineClawAmount(
|
||||
SLE const& sleBroker,
|
||||
Asset const& vaultAsset,
|
||||
std::optional<STAmount> const& amount,
|
||||
SLE::const_ref vaultSle,
|
||||
VaultEntry<ReadView> const& vaultSle,
|
||||
Rules const& rules)
|
||||
{
|
||||
auto const maxClawAmount = [&]() {
|
||||
@@ -293,8 +293,8 @@ LoanBrokerCoverClawback::preclaim(PreclaimContext const& ctx)
|
||||
}
|
||||
}
|
||||
|
||||
auto const findClawAmount =
|
||||
determineClawAmount(*sleBroker, vaultAsset, amount, vault, ctx.view.rules());
|
||||
auto const findClawAmount = determineClawAmount(
|
||||
*sleBroker, vaultAsset, amount, VaultEntry<ReadView>{vault, ctx.view}, ctx.view.rules());
|
||||
if (!findClawAmount)
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "LoanBroker cover is already at minimum.";
|
||||
@@ -303,7 +303,12 @@ LoanBrokerCoverClawback::preclaim(PreclaimContext const& ctx)
|
||||
STAmount const& clawAmount = *findClawAmount;
|
||||
|
||||
if (auto const ret = canApplyToBrokerCover(
|
||||
ctx.view, sleBroker, vaultAsset, clawAmount, ctx.j, "LoanBrokerCoverClawback"))
|
||||
ctx.view,
|
||||
LoanBrokerEntry<ReadView>{sleBroker, ctx.view},
|
||||
vaultAsset,
|
||||
clawAmount,
|
||||
ctx.j,
|
||||
"LoanBrokerCoverClawback"))
|
||||
return ret;
|
||||
|
||||
// Explicitly check the balance of the trust line / MPT to make sure the
|
||||
@@ -356,8 +361,8 @@ LoanBrokerCoverClawback::doApply()
|
||||
|
||||
auto const vaultAsset = vault->at(sfAsset);
|
||||
|
||||
auto const findClawAmount =
|
||||
determineClawAmount(*sleBroker, vaultAsset, amount, vault, view().rules());
|
||||
auto const findClawAmount = determineClawAmount(
|
||||
*sleBroker, vaultAsset, amount, VaultEntry<ReadView>{vault, view()}, view().rules());
|
||||
if (!findClawAmount)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
STAmount const& clawAmount = *findClawAmount;
|
||||
|
||||
@@ -96,7 +96,12 @@ LoanBrokerCoverWithdraw::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
// Helper handles both IOU and MPT correctly without explicit branching.
|
||||
if (auto const ret = canApplyToBrokerCover(
|
||||
ctx.view, sleBroker, vaultAsset, amount, ctx.j, "LoanBrokerCoverWithdraw"))
|
||||
ctx.view,
|
||||
LoanBrokerEntry<ReadView>{sleBroker, ctx.view},
|
||||
vaultAsset,
|
||||
amount,
|
||||
ctx.j,
|
||||
"LoanBrokerCoverWithdraw"))
|
||||
return ret;
|
||||
|
||||
// The broker's pseudo-account is the source of funds.
|
||||
@@ -152,7 +157,9 @@ LoanBrokerCoverWithdraw::preclaim(PreclaimContext const& ctx)
|
||||
if (fix320Enabled)
|
||||
{
|
||||
return minimumBrokerCover(
|
||||
currentDebtTotal, TenthBips32{sleBroker->at(sfCoverRateMinimum)}, vault);
|
||||
currentDebtTotal,
|
||||
TenthBips32{sleBroker->at(sfCoverRateMinimum)},
|
||||
VaultEntry<ReadView>{vault, ctx.view});
|
||||
}
|
||||
|
||||
// Always round the minimum required up.
|
||||
|
||||
@@ -78,7 +78,7 @@ LoanBrokerDelete::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
// Any remaining debt should have been wiped out by the last Loan
|
||||
// Delete. This check is purely defensive.
|
||||
auto const scale = getAssetsTotalScale(vault);
|
||||
auto const scale = getAssetsTotalScale(VaultEntry<ReadView>{vault, ctx.view});
|
||||
|
||||
auto const rounded =
|
||||
roundToAsset(asset, debtTotal, scale, Number::RoundingMode::TowardsZero);
|
||||
|
||||
@@ -121,7 +121,7 @@ LoanDelete::doApply()
|
||||
roundToAsset(
|
||||
vaultSle->at(sfAsset),
|
||||
debtTotalProxy,
|
||||
getAssetsTotalScale(vaultSle),
|
||||
getAssetsTotalScale(VaultEntry<ReadView>{vaultSle, view}),
|
||||
Number::RoundingMode::TowardsZero) == beast::kZero,
|
||||
"xrpl::LoanDelete::doApply",
|
||||
"last loan, remaining debt rounds to zero");
|
||||
|
||||
@@ -128,7 +128,7 @@ LoanManage::preclaim(PreclaimContext const& ctx)
|
||||
}
|
||||
|
||||
static Number
|
||||
owedToVault(SLE::ref loanSle)
|
||||
owedToVault(LoanEntry<ApplyView> const& loanSle)
|
||||
{
|
||||
// Spec section 3.2.3.2, defines the default amount as
|
||||
//
|
||||
@@ -147,9 +147,9 @@ owedToVault(SLE::ref loanSle)
|
||||
TER
|
||||
LoanManage::defaultLoan(
|
||||
ApplyView& view,
|
||||
SLE::ref loanSle,
|
||||
SLE::ref brokerSle,
|
||||
SLE::ref vaultSle,
|
||||
LoanEntry<ApplyView>& loanSle,
|
||||
LoanBrokerEntry<ApplyView>& brokerSle,
|
||||
VaultEntry<ApplyView>& vaultSle,
|
||||
Asset const& vaultAsset,
|
||||
beast::Journal j)
|
||||
{
|
||||
@@ -251,7 +251,7 @@ LoanManage::defaultLoan(
|
||||
adjustImpreciseNumber(
|
||||
vaultLossUnrealizedProxy, -totalDefaultAmount, vaultAsset, vaultScale);
|
||||
}
|
||||
view.update(vaultSle);
|
||||
vaultSle.update();
|
||||
}
|
||||
|
||||
// Update the LoanBroker object:
|
||||
@@ -269,7 +269,7 @@ LoanManage::defaultLoan(
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
coverAvailableProxy -= defaultCovered;
|
||||
view.update(brokerSle);
|
||||
brokerSle.update();
|
||||
}
|
||||
|
||||
// Update the Loan object:
|
||||
@@ -282,7 +282,7 @@ LoanManage::defaultLoan(
|
||||
// Zero out the next due date. Since it's default, it'll be removed from
|
||||
// the object.
|
||||
loanSle->at(sfNextPaymentDueDate) = 0;
|
||||
view.update(loanSle);
|
||||
loanSle.update();
|
||||
|
||||
// Return funds from the LoanBroker pseudo-account to the
|
||||
// Vault pseudo-account:
|
||||
@@ -298,8 +298,8 @@ LoanManage::defaultLoan(
|
||||
TER
|
||||
LoanManage::impairLoan(
|
||||
ApplyView& view,
|
||||
SLE::ref loanSle,
|
||||
SLE::ref vaultSle,
|
||||
LoanEntry<ApplyView>& loanSle,
|
||||
VaultEntry<ApplyView>& vaultSle,
|
||||
Asset const& vaultAsset,
|
||||
beast::Journal j)
|
||||
{
|
||||
@@ -321,7 +321,7 @@ LoanManage::impairLoan(
|
||||
"corrupt the vault.";
|
||||
return tecLIMIT_EXCEEDED;
|
||||
}
|
||||
view.update(vaultSle);
|
||||
vaultSle.update();
|
||||
|
||||
// Update the Loan object
|
||||
loanSle->setFlag(lsfLoanImpaired);
|
||||
@@ -332,7 +332,7 @@ LoanManage::impairLoan(
|
||||
// move the next payment due date to now
|
||||
loanNextDueProxy = view.parentCloseTime().time_since_epoch().count();
|
||||
}
|
||||
view.update(loanSle);
|
||||
loanSle.update();
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
@@ -340,8 +340,8 @@ LoanManage::impairLoan(
|
||||
[[nodiscard]] TER
|
||||
LoanManage::unimpairLoan(
|
||||
ApplyView& view,
|
||||
SLE::ref loanSle,
|
||||
SLE::ref vaultSle,
|
||||
LoanEntry<ApplyView>& loanSle,
|
||||
VaultEntry<ApplyView>& vaultSle,
|
||||
Asset const& vaultAsset,
|
||||
beast::Journal j)
|
||||
{
|
||||
@@ -363,7 +363,7 @@ LoanManage::unimpairLoan(
|
||||
// Reverse the "paper loss"
|
||||
adjustImpreciseNumber(vaultLossUnrealizedProxy, -lossReversed, vaultAsset, vaultScale);
|
||||
|
||||
view.update(vaultSle);
|
||||
vaultSle.update();
|
||||
|
||||
// Update the Loan object
|
||||
loanSle->clearFlag(lsfLoanImpaired);
|
||||
@@ -381,7 +381,7 @@ LoanManage::unimpairLoan(
|
||||
loanSle->at(sfNextPaymentDueDate) =
|
||||
view.parentCloseTime().time_since_epoch().count() + paymentInterval;
|
||||
}
|
||||
view.update(loanSle);
|
||||
loanSle.update();
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
@@ -393,16 +393,16 @@ LoanManage::doApply()
|
||||
auto& view = ctx_.view();
|
||||
|
||||
auto const loanID = tx[sfLoanID];
|
||||
auto const loanSle = view.peek(keylet::loan(loanID));
|
||||
LoanEntry<ApplyView> loanSle{keylet::loan(loanID), view};
|
||||
if (!loanSle)
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
|
||||
auto const brokerID = loanSle->at(sfLoanBrokerID);
|
||||
auto const brokerSle = view.peek(keylet::loanBroker(brokerID));
|
||||
LoanBrokerEntry<ApplyView> brokerSle{keylet::loanBroker(brokerID), view};
|
||||
if (!brokerSle)
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
|
||||
auto const vaultSle = view.peek(keylet::vault(brokerSle->at(sfVaultID)));
|
||||
VaultEntry<ApplyView> vaultSle{keylet::vault(brokerSle->at(sfVaultID)), view};
|
||||
if (!vaultSle)
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
auto const vaultAsset = vaultSle->at(sfAsset);
|
||||
|
||||
@@ -287,19 +287,19 @@ LoanPay::doApply()
|
||||
auto const amount = tx[sfAmount];
|
||||
|
||||
auto const loanID = tx[sfLoanID];
|
||||
auto const loanSle = view.peek(keylet::loan(loanID));
|
||||
LoanEntry<ApplyView> loanSle{keylet::loan(loanID), view};
|
||||
if (!loanSle)
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
std::int32_t const loanScale = loanSle->at(sfLoanScale);
|
||||
|
||||
auto const brokerID = loanSle->at(sfLoanBrokerID);
|
||||
auto const brokerSle = view.peek(keylet::loanBroker(brokerID));
|
||||
LoanBrokerEntry<ApplyView> brokerSle{keylet::loanBroker(brokerID), view};
|
||||
if (!brokerSle)
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
auto const brokerOwner = brokerSle->at(sfOwner);
|
||||
auto const brokerPseudoAccount = brokerSle->at(sfAccount);
|
||||
auto const vaultID = brokerSle->at(sfVaultID);
|
||||
auto const vaultSle = view.peek(keylet::vault(vaultID));
|
||||
VaultEntry<ApplyView> vaultSle{keylet::vault(vaultID), view};
|
||||
if (!vaultSle)
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
auto const vaultPseudoAccount = vaultSle->at(sfAccount);
|
||||
@@ -392,7 +392,7 @@ LoanPay::doApply()
|
||||
|
||||
// If the payment computation completed without error, the loanSle object
|
||||
// has been modified.
|
||||
view.update(loanSle);
|
||||
loanSle.update();
|
||||
|
||||
XRPL_ASSERT_PARTS(
|
||||
// It is possible to pay 0 principal
|
||||
@@ -427,7 +427,7 @@ LoanPay::doApply()
|
||||
|
||||
//------------------------------------------------------
|
||||
// LoanBroker object state changes
|
||||
view.update(brokerSle);
|
||||
brokerSle.update();
|
||||
|
||||
auto assetsAvailableProxy = vaultSle->at(sfAssetsAvailable);
|
||||
auto assetsTotalProxy = vaultSle->at(sfAssetsTotal);
|
||||
@@ -468,7 +468,7 @@ LoanPay::doApply()
|
||||
|
||||
//------------------------------------------------------
|
||||
// Vault object state changes
|
||||
view.update(vaultSle);
|
||||
vaultSle.update();
|
||||
|
||||
Number const assetsAvailableBefore = *assetsAvailableProxy;
|
||||
Number const assetsTotalBefore = *assetsTotalProxy;
|
||||
|
||||
@@ -381,7 +381,7 @@ LoanSet::doApply()
|
||||
if (!brokerOwnerSle)
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
|
||||
auto const vaultSle = view.peek(keylet ::vault(brokerSle->at(sfVaultID)));
|
||||
VaultEntry<ApplyView> vaultSle{keylet::vault(brokerSle->at(sfVaultID)), view};
|
||||
if (!vaultSle)
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
auto const vaultPseudo = vaultSle->at(sfAccount);
|
||||
@@ -627,7 +627,7 @@ LoanSet::doApply()
|
||||
*vaultAvailableProxy <= *vaultTotalProxy,
|
||||
"xrpl::LoanSet::doApply",
|
||||
"assets available must not be greater than assets outstanding");
|
||||
view.update(vaultSle);
|
||||
vaultSle.update();
|
||||
|
||||
// Update the balances in the loan broker
|
||||
adjustImpreciseNumber(brokerSle->at(sfDebtTotal), newDebtDelta, vaultAsset, vaultScale);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/OpenView.h>
|
||||
#include <xrpl/ledger/helpers/SLEWrappers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -139,9 +140,9 @@ class LoanBroker_test : public beast::unit_test::Suite
|
||||
VaultInfo const& vault,
|
||||
VaultInfo const& badVault,
|
||||
std::function<jtx::JTx(jtx::JTx const&)> modifyJTx,
|
||||
std::function<void(SLE::const_ref)> checkBroker,
|
||||
std::function<void(SLE::const_ref)> changeBroker,
|
||||
std::function<void(SLE::const_ref)> checkChangedBroker)
|
||||
std::function<void(LoanBrokerEntry<ReadView> const&)> checkBroker,
|
||||
std::function<void(LoanBrokerEntry<ReadView> const&)> changeBroker,
|
||||
std::function<void(LoanBrokerEntry<ReadView> const&)> checkChangedBroker)
|
||||
{
|
||||
{
|
||||
auto const& asset = vault.asset.raw();
|
||||
@@ -219,7 +220,7 @@ class LoanBroker_test : public beast::unit_test::Suite
|
||||
BEAST_EXPECT(broker->at(sfDebtTotal) == 0);
|
||||
BEAST_EXPECT(broker->at(sfCoverAvailable) == 0);
|
||||
if (checkBroker)
|
||||
checkBroker(broker);
|
||||
checkBroker(LoanBrokerEntry<ReadView>{broker, *env.current()});
|
||||
|
||||
// if (auto const vaultSLE = env.le(keylet::vault(vault.vaultID)))
|
||||
//{
|
||||
@@ -469,14 +470,14 @@ class LoanBroker_test : public beast::unit_test::Suite
|
||||
|
||||
// Make modifications to the broker
|
||||
if (changeBroker)
|
||||
changeBroker(broker);
|
||||
changeBroker(LoanBrokerEntry<ReadView>{broker, *env.current()});
|
||||
|
||||
env.close();
|
||||
|
||||
// Check the results of modifications
|
||||
broker = env.le(keylet);
|
||||
if (BEAST_EXPECT(broker) && checkChangedBroker)
|
||||
checkChangedBroker(broker);
|
||||
checkChangedBroker(LoanBrokerEntry<ReadView>{broker, *env.current()});
|
||||
|
||||
// Verify that fields get removed when set to default values
|
||||
// Debt maximum: explicit 0
|
||||
@@ -722,7 +723,7 @@ class LoanBroker_test : public beast::unit_test::Suite
|
||||
badVault,
|
||||
// No modifications
|
||||
{},
|
||||
[&](SLE::const_ref broker) {
|
||||
[&](LoanBrokerEntry<ReadView> const& broker) {
|
||||
// Extra checks
|
||||
BEAST_EXPECT(!broker->isFieldPresent(sfManagementFeeRate));
|
||||
BEAST_EXPECT(!broker->isFieldPresent(sfCoverRateMinimum));
|
||||
@@ -735,7 +736,7 @@ class LoanBroker_test : public beast::unit_test::Suite
|
||||
|
||||
BEAST_EXPECT(env.ownerCount(alice) == aliceOriginalCount + 4);
|
||||
},
|
||||
[&](SLE::const_ref broker) {
|
||||
[&](LoanBrokerEntry<ReadView> const& broker) {
|
||||
// Modifications
|
||||
|
||||
// Update the fields
|
||||
@@ -795,7 +796,7 @@ class LoanBroker_test : public beast::unit_test::Suite
|
||||
kData(testData),
|
||||
kDebtMaximum(debtMax));
|
||||
},
|
||||
[&](SLE::const_ref broker) {
|
||||
[&](LoanBrokerEntry<ReadView> const& broker) {
|
||||
// Check the updated fields
|
||||
BEAST_EXPECT(checkVL(broker->at(sfData), testData));
|
||||
Number const expected = STAmount{vault.asset, Number(175, -1)};
|
||||
@@ -826,7 +827,7 @@ class LoanBroker_test : public beast::unit_test::Suite
|
||||
kCoverRateMinimum(TenthBips32(100)),
|
||||
kCoverRateLiquidation(TenthBips32(200)));
|
||||
},
|
||||
[&](SLE::const_ref broker) {
|
||||
[&](LoanBrokerEntry<ReadView> const& broker) {
|
||||
// Extra checks
|
||||
BEAST_EXPECT(broker->at(sfManagementFeeRate) == 123);
|
||||
BEAST_EXPECT(broker->at(sfCoverRateMinimum) == 100);
|
||||
@@ -834,14 +835,14 @@ class LoanBroker_test : public beast::unit_test::Suite
|
||||
BEAST_EXPECT(broker->at(sfDebtMaximum) == Number(9));
|
||||
BEAST_EXPECT(checkVL(broker->at(sfData), testData));
|
||||
},
|
||||
[&](SLE::const_ref broker) {
|
||||
[&](LoanBrokerEntry<ReadView> const& broker) {
|
||||
// Reset Data & Debt maximum to default values
|
||||
env(set(alice, vault.vaultID),
|
||||
kLoanBrokerId(broker->key()),
|
||||
kData(""),
|
||||
kDebtMaximum(Number(0)));
|
||||
},
|
||||
[&](SLE::const_ref broker) {
|
||||
[&](LoanBrokerEntry<ReadView> const& broker) {
|
||||
// Check the updated fields
|
||||
BEAST_EXPECT(!broker->isFieldPresent(sfData));
|
||||
BEAST_EXPECT(!broker->isFieldPresent(sfDebtMaximum));
|
||||
|
||||
@@ -211,7 +211,7 @@ protected:
|
||||
using namespace jtx;
|
||||
|
||||
auto const vaultSle = env.le(keylet::vault(vaultID));
|
||||
return getAssetsTotalScale(vaultSle);
|
||||
return getAssetsTotalScale(VaultEntry<ReadView>{vaultSle, *env.current()});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -440,7 +440,8 @@ protected:
|
||||
env.test.BEAST_EXPECT(loan->at(sfPeriodicPayment) == periodicPayment);
|
||||
env.test.BEAST_EXPECT(loan->at(sfFlags) == flags);
|
||||
|
||||
auto const ls = constructRoundedLoanState(loan);
|
||||
auto const ls =
|
||||
constructRoundedLoanState(LoanEntry<ReadView>{loan, *env.current()});
|
||||
|
||||
auto const interestRate = TenthBips32{loan->at(sfInterestRate)};
|
||||
auto const paymentInterval = loan->at(sfPaymentInterval);
|
||||
@@ -1108,7 +1109,8 @@ protected:
|
||||
// No reason for this not to exist
|
||||
return;
|
||||
}
|
||||
auto const current = constructRoundedLoanState(loanSle);
|
||||
auto const current =
|
||||
constructRoundedLoanState(LoanEntry<ReadView>{loanSle, *env.current()});
|
||||
auto const errors = nextTrueState - current;
|
||||
log << currencyLabel << " Loan balances: "
|
||||
<< "\n\tAmount taken: " << paymentComponents.trackedValueDelta
|
||||
@@ -6033,7 +6035,8 @@ protected:
|
||||
auto const loanSle = env.le(loanKeylet);
|
||||
if (!BEAST_EXPECT(loanSle))
|
||||
return;
|
||||
auto const state = constructRoundedLoanState(loanSle);
|
||||
auto const state =
|
||||
constructRoundedLoanState(LoanEntry<ReadView>{loanSle, *env.current()});
|
||||
|
||||
log << "Loan state:" << std::endl;
|
||||
log << " ValueOutstanding: " << state.valueOutstanding << std::endl;
|
||||
@@ -8257,7 +8260,8 @@ protected:
|
||||
return std::nullopt;
|
||||
if (!BEAST_EXPECT(tinyLoanSle->at(sfLoanScale) == -12) ||
|
||||
!BEAST_EXPECT(bigLoanSle->at(sfLoanScale) == -11) ||
|
||||
!BEAST_EXPECT(getAssetsTotalScale(vaultSle) == -11))
|
||||
!BEAST_EXPECT(
|
||||
getAssetsTotalScale(VaultEntry<ReadView>{vaultSle, *env.current()}) == -11))
|
||||
return std::nullopt;
|
||||
|
||||
// Use issuer clawback to reduce cover to the minimum the
|
||||
@@ -8384,7 +8388,8 @@ protected:
|
||||
|
||||
auto const coverAvail = brokerSle->at(sfCoverAvailable);
|
||||
auto const debtTotal = brokerSle->at(sfDebtTotal);
|
||||
auto const vaultScale = getAssetsTotalScale(vaultSle);
|
||||
auto const vaultScale =
|
||||
getAssetsTotalScale(VaultEntry<ReadView>{vaultSle, *env.current()});
|
||||
auto const debtScale = scale(debtTotal, asset);
|
||||
|
||||
// Sanity: debt scale differs from vault scale for this setup.
|
||||
@@ -8398,7 +8403,9 @@ protected:
|
||||
debtScale);
|
||||
}();
|
||||
auto const newMin = minimumBrokerCover(
|
||||
debtTotal, TenthBips32{c.brokerParams.coverRateMin}, vaultSle);
|
||||
debtTotal,
|
||||
TenthBips32{c.brokerParams.coverRateMin},
|
||||
VaultEntry<ReadView>{vaultSle, *env.current()});
|
||||
|
||||
// The new (vaultScale) minimum must be strictly larger than
|
||||
// the old (debtScale) minimum — that is the gap the amendment
|
||||
@@ -8482,7 +8489,8 @@ protected:
|
||||
auto const vaultSle = env.le(keylet::vault(c.broker.vaultID));
|
||||
if (!BEAST_EXPECT(vaultSle))
|
||||
return;
|
||||
auto const vaultScale = getAssetsTotalScale(vaultSle);
|
||||
auto const vaultScale =
|
||||
getAssetsTotalScale(VaultEntry<ReadView>{vaultSle, *env.current()});
|
||||
BEAST_EXPECT(vaultScale == -11);
|
||||
|
||||
// Now try to create a tiny additional loan. Principal is
|
||||
|
||||
Reference in New Issue
Block a user