mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-21 03:26:01 +00:00
[WIP] Define remaining transactions, start implementing LoanBrokerSet
- Does not build - Transactions: LoanDelete, LoanManage, LoanDraw, LoanPay - LoanBrokerSet creation mostly done. Need update. - Also added a lookup table for pseudo account fields.
This commit is contained in:
@@ -82,6 +82,26 @@ std::size_t constexpr maxDeletableTokenOfferEntries = 500;
|
|||||||
*/
|
*/
|
||||||
std::uint16_t constexpr maxTransferFee = 50000;
|
std::uint16_t constexpr maxTransferFee = 50000;
|
||||||
|
|
||||||
|
/** The maximum management fee rate allowed in lending.
|
||||||
|
|
||||||
|
TODO: Is this a good name?
|
||||||
|
|
||||||
|
Valid values for the the management fee charged by the Lending Protocol are
|
||||||
|
between 0 and 10000 inclusive. A value of 1 is equivalent to 1/10 basis
|
||||||
|
point fee or 0.001%.
|
||||||
|
*/
|
||||||
|
std::uint16_t constexpr maxFeeRate = 10'000;
|
||||||
|
|
||||||
|
/** The maximum coverage rate allowed in lending.
|
||||||
|
|
||||||
|
TODO: Is this a good name?
|
||||||
|
|
||||||
|
Valid values for the coverage rate charged by the Lending Protocol for first
|
||||||
|
loss capital operations are between 0 and 100000 inclusive. A value of 1 is
|
||||||
|
equivalent to 1/10 bps or 0.001%.
|
||||||
|
*/
|
||||||
|
std::uint16_t constexpr maxCoverRate = 100'000;
|
||||||
|
|
||||||
/** The maximum length of a URI inside an NFT */
|
/** The maximum length of a URI inside an NFT */
|
||||||
std::size_t constexpr maxTokenURILength = 256;
|
std::size_t constexpr maxTokenURILength = 256;
|
||||||
|
|
||||||
|
|||||||
@@ -237,6 +237,13 @@ constexpr std::uint32_t const tfVaultCreateMask = ~(tfUniversal | tfVaultPrivate
|
|||||||
// True, indicates the load supports overpayments
|
// True, indicates the load supports overpayments
|
||||||
constexpr std::uint32_t const tfLoanOverpayment = 0x00010000;
|
constexpr std::uint32_t const tfLoanOverpayment = 0x00010000;
|
||||||
constexpr std::uint32_t const tfLoanSetMask = ~(tfUniversal | tfLoanOverpayment);
|
constexpr std::uint32_t const tfLoanSetMask = ~(tfUniversal | tfLoanOverpayment);
|
||||||
|
|
||||||
|
// LoanManage flags:
|
||||||
|
constexpr std::uint32_t const tfLoanDefault = 0x00010000;
|
||||||
|
constexpr std::uint32_t const tfLoanImpair = 0x00010000;
|
||||||
|
constexpr std::uint32_t const tfLoanUnimpair = 0x00010000;
|
||||||
|
constexpr std::uint32_t const tfLoanManageMask = ~(tfUniversal | tfLoanDefault | tfLoanImpair | tfLoanUnimpair);
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|||||||
@@ -501,12 +501,12 @@ LEDGER_ENTRY(ltLOAN_BROKER, 0x0084, LoanBroker, loan_broker, ({
|
|||||||
{sfOwner, soeREQUIRED},
|
{sfOwner, soeREQUIRED},
|
||||||
{sfData, soeDEFAULT},
|
{sfData, soeDEFAULT},
|
||||||
{sfManagementFeeRate, soeDEFAULT},
|
{sfManagementFeeRate, soeDEFAULT},
|
||||||
{sfOwnerCount, soeREQUIRED},
|
{sfOwnerCount, soeDEFAULT},
|
||||||
{sfDebtTotal, soeREQUIRED},
|
{sfDebtTotal, soeDEFAULT},
|
||||||
{sfDebtMaximum, soeREQUIRED},
|
{sfDebtMaximum, soeDEFAULT},
|
||||||
{sfCoverAvailable, soeREQUIRED},
|
{sfCoverAvailable, soeDEFAULT},
|
||||||
{sfCoverRateMinimum, soeREQUIRED},
|
{sfCoverRateMinimum, soeDEFAULT},
|
||||||
{sfCoverRateLiquidation, soeREQUIRED},
|
{sfCoverRateLiquidation, soeDEFAULT},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
/** A ledger object representing a loan between a Borrower and a Loan Broker
|
/** A ledger object representing a loan between a Borrower and a Loan Broker
|
||||||
|
|||||||
@@ -211,6 +211,7 @@ TYPED_SFIELD(sfHookSetTxnID, UINT256, 33)
|
|||||||
TYPED_SFIELD(sfDomainID, UINT256, 34)
|
TYPED_SFIELD(sfDomainID, UINT256, 34)
|
||||||
TYPED_SFIELD(sfVaultID, UINT256, 35)
|
TYPED_SFIELD(sfVaultID, UINT256, 35)
|
||||||
TYPED_SFIELD(sfLoanBrokerID, UINT256, 36)
|
TYPED_SFIELD(sfLoanBrokerID, UINT256, 36)
|
||||||
|
TYPED_SFIELD(sfLoanID, UINT256, 37)
|
||||||
|
|
||||||
// number (common)
|
// number (common)
|
||||||
TYPED_SFIELD(sfNumber, NUMBER, 1)
|
TYPED_SFIELD(sfNumber, NUMBER, 1)
|
||||||
|
|||||||
@@ -508,7 +508,6 @@ TRANSACTION(ttVAULT_CLAWBACK, 69, VaultClawback, ({
|
|||||||
{sfAmount, soeOPTIONAL, soeMPTSupported},
|
{sfAmount, soeOPTIONAL, soeMPTSupported},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
#if 0
|
|
||||||
/** This transaction creates and updates a Loan Broker */
|
/** This transaction creates and updates a Loan Broker */
|
||||||
TRANSACTION(ttLOAN_BROKER_SET, 70, LoanBrokerSet, ({
|
TRANSACTION(ttLOAN_BROKER_SET, 70, LoanBrokerSet, ({
|
||||||
{sfVaultID, soeREQUIRED},
|
{sfVaultID, soeREQUIRED},
|
||||||
@@ -520,6 +519,7 @@ TRANSACTION(ttLOAN_BROKER_SET, 70, LoanBrokerSet, ({
|
|||||||
{sfCoverRateLiquidation, soeDEFAULT},
|
{sfCoverRateLiquidation, soeDEFAULT},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
#if 0
|
||||||
/** This transaction deletes a Loan Broker */
|
/** This transaction deletes a Loan Broker */
|
||||||
TRANSACTION(ttLOAN_BROKER_DELETE, 71, LoanBrokerDelete, ({
|
TRANSACTION(ttLOAN_BROKER_DELETE, 71, LoanBrokerDelete, ({
|
||||||
{sfLoanBrokerID, soeREQUIRED},
|
{sfLoanBrokerID, soeREQUIRED},
|
||||||
@@ -556,6 +556,28 @@ TRANSACTION(ttLOAN_SET, 74, LoanSet, ({
|
|||||||
{sfPaymentInterval, soeOPTIONAL},
|
{sfPaymentInterval, soeOPTIONAL},
|
||||||
{sfGracePeriod, soeOPTIONAL},
|
{sfGracePeriod, soeOPTIONAL},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
/** This transaction deletes an existing Loan */
|
||||||
|
TRANSACTION(ttLOAN_DELETE, 75, LoanDelete, ({
|
||||||
|
{sfLoanID, soeREQUIRED},
|
||||||
|
}))
|
||||||
|
|
||||||
|
/** This transaction is used to change the delinquency status of an existing Loan */
|
||||||
|
TRANSACTION(ttLOAN_MANAGE, 76, LoanManage, ({
|
||||||
|
{sfLoanID, soeREQUIRED},
|
||||||
|
}))
|
||||||
|
|
||||||
|
/** The Borrower uses this transaction to draws funds from the Loan. */
|
||||||
|
TRANSACTION(ttLOAN_DRAW, 77, LoanDraw, ({
|
||||||
|
{sfLoanID, soeREQUIRED},
|
||||||
|
{sfAmount, soeREQUIRED},
|
||||||
|
}))
|
||||||
|
|
||||||
|
/** The Borrower uses this transaction to make a Payment on the Loan. */
|
||||||
|
TRANSACTION(ttLOAN_PAY, 77, LoanPay, ({
|
||||||
|
{sfLoanID, soeREQUIRED},
|
||||||
|
{sfAmount, soeREQUIRED},
|
||||||
|
}))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** This system-generated transaction type is used to update the status of the various amendments.
|
/** This system-generated transaction type is used to update the status of the various amendments.
|
||||||
|
|||||||
205
src/xrpld/app/tx/detail/LoanBroker.cpp
Normal file
205
src/xrpld/app/tx/detail/LoanBroker.cpp
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2022 Ripple Labs Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#include <xrpld/app/tx/detail/LoanBroker.h>
|
||||||
|
#include <xrpld/app/tx/detail/SignerEntries.h>
|
||||||
|
#include <xrpld/app/tx/detail/Transactor.h>
|
||||||
|
#include <xrpld/app/tx/detail/VaultCreate.h>
|
||||||
|
#include <xrpld/ledger/ApplyView.h>
|
||||||
|
#include <xrpld/ledger/View.h>
|
||||||
|
|
||||||
|
#include <xrpl/basics/Log.h>
|
||||||
|
#include <xrpl/basics/Number.h>
|
||||||
|
#include <xrpl/basics/chrono.h>
|
||||||
|
#include <xrpl/beast/utility/Journal.h>
|
||||||
|
#include <xrpl/beast/utility/instrumentation.h>
|
||||||
|
#include <xrpl/protocol/AccountID.h>
|
||||||
|
#include <xrpl/protocol/Feature.h>
|
||||||
|
#include <xrpl/protocol/Indexes.h>
|
||||||
|
#include <xrpl/protocol/PublicKey.h>
|
||||||
|
#include <xrpl/protocol/SField.h>
|
||||||
|
#include <xrpl/protocol/STAmount.h>
|
||||||
|
#include <xrpl/protocol/STObject.h>
|
||||||
|
#include <xrpl/protocol/STXChainBridge.h>
|
||||||
|
#include <xrpl/protocol/TER.h>
|
||||||
|
#include <xrpl/protocol/TxFlags.h>
|
||||||
|
#include <xrpl/protocol/XRPAmount.h>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
|
||||||
|
bool
|
||||||
|
lendingProtocolEnabled(PreflightContext const& ctx)
|
||||||
|
{
|
||||||
|
return ctx.rules.enabled(featureLendingProtocol) &&
|
||||||
|
VaultCreate::isEnabled(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
LoanBrokerSet::isEnabled(PreflightContext const& ctx)
|
||||||
|
{
|
||||||
|
return lendingProtocolEnabled(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint32_t
|
||||||
|
LoanBrokerSet::getFlagsMask(PreflightContext const& ctx)
|
||||||
|
{
|
||||||
|
return tfUniversalMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotTEC
|
||||||
|
LoanBrokerSet::doPreflight(PreflightContext const& ctx)
|
||||||
|
{
|
||||||
|
auto const& tx = ctx.tx;
|
||||||
|
if (!validDataLength(tx[~sfData], maxDataPayloadLength))
|
||||||
|
return temINVALID;
|
||||||
|
if (!validNumericRange(tx[~sfManagementFeeRate], 0, maxFeeRate))
|
||||||
|
return temINVALID;
|
||||||
|
if (!validNumericRange(tx[~sfCoverRateMinimum], 0, maxCoverRate))
|
||||||
|
return temINVALID;
|
||||||
|
if (!validNumericRange(tx[~sfCoverRateLiquidation], 0, maxCoverRate))
|
||||||
|
return temINVALID;
|
||||||
|
|
||||||
|
if (tx.isFieldPresent(sfLoanBrokerID))
|
||||||
|
{
|
||||||
|
// Fixed fields can not be specified if we're modifying an existing
|
||||||
|
// LoanBroker Object
|
||||||
|
if (tx.isFieldPresent(sfManagementFeeRate) ||
|
||||||
|
tx.isFieldPresent(sfCoverRateMinimum) ||
|
||||||
|
tx.isFieldPresent(sfCoverRateLiquidation))
|
||||||
|
return temINVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tesSUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
TER
|
||||||
|
LoanBrokerSet::preclaim(PreclaimContext const& ctx)
|
||||||
|
{
|
||||||
|
auto const& tx = ctx.tx;
|
||||||
|
|
||||||
|
auto const account = tx[sfAccount];
|
||||||
|
if (auto const brokerID = tx[~sfLoanBrokerID])
|
||||||
|
{
|
||||||
|
auto const sleBroker = ctx.view.read(keylet::loanbroker(*brokerID));
|
||||||
|
if (!sleBroker)
|
||||||
|
{
|
||||||
|
JLOG(ctx.j.warn()) << "LoanBroker does not exist.";
|
||||||
|
return tecNO_ENTRY;
|
||||||
|
}
|
||||||
|
if (tx[sfVaultID] != sleBroker->at(sfVaultID))
|
||||||
|
{
|
||||||
|
JLOG(ctx.j.warn())
|
||||||
|
<< "Can not change VaultID on an existing LoanBroker.";
|
||||||
|
return tecNO_PERMISSION;
|
||||||
|
}
|
||||||
|
if (account != sleBroker->at(sfOwner))
|
||||||
|
{
|
||||||
|
JLOG(ctx.j.warn()) << "Account is not the owner of the LoanBroker.";
|
||||||
|
return tecNO_PERMISSION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto const vaultID = tx[sfVaultID];
|
||||||
|
auto const sleVault = ctx.view.read(keylet::vault(vaultID));
|
||||||
|
if (!sleVault)
|
||||||
|
{
|
||||||
|
JLOG(ctx.j.warn()) << "Vault does not exist.";
|
||||||
|
return tecNO_ENTRY;
|
||||||
|
}
|
||||||
|
if (account != sleVault->at(sfOwner))
|
||||||
|
{
|
||||||
|
JLOG(ctx.j.warn()) << "Account is not the owner of the Vault.";
|
||||||
|
return tecNO_PERMISSION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tesSUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
TER
|
||||||
|
LoanBrokerSet::doApply()
|
||||||
|
{
|
||||||
|
auto const& tx = ctx_.tx;
|
||||||
|
auto& view = ctx_.view();
|
||||||
|
|
||||||
|
if (auto const brokerID = tx[~sfLoanBrokerID])
|
||||||
|
{
|
||||||
|
// Modify an existing LoanBroker
|
||||||
|
auto const sleBroker = view.read(keylet::loanbroker(*brokerID));
|
||||||
|
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Create a new LoanBroker pointing back to the given Vault
|
||||||
|
auto const vaultID = tx[sfVaultID];
|
||||||
|
auto const sleVault = view.read(keylet::vault(vaultID));
|
||||||
|
auto const vaultPseudoID = sleVault->at(sfAccount);
|
||||||
|
auto const sequence = tx.getSeqValue();
|
||||||
|
|
||||||
|
auto owner = view.peek(keylet::account(account_));
|
||||||
|
auto broker =
|
||||||
|
std::make_shared<SLE>(keylet::loanbroker(account_, sequence));
|
||||||
|
|
||||||
|
if (auto const ter = dirLink(view, account_, broker))
|
||||||
|
return ter;
|
||||||
|
if (auto const ter = dirLink(view, vaultPseudoID, broker))
|
||||||
|
return ter;
|
||||||
|
|
||||||
|
adjustOwnerCount(view, owner, 1, j_);
|
||||||
|
auto ownerCount = owner->at(sfOwnerCount);
|
||||||
|
if (mPriorBalance < view.fees().accountReserve(ownerCount))
|
||||||
|
return tecINSUFFICIENT_RESERVE;
|
||||||
|
|
||||||
|
auto maybePseudo = createPseudoAccount(
|
||||||
|
view, broker->key(), PseudoAccountOwnerType::LoanBroker);
|
||||||
|
if (!maybePseudo)
|
||||||
|
return maybePseudo.error();
|
||||||
|
auto& pseudo = *maybePseudo;
|
||||||
|
auto pseudoId = pseudo->at(sfAccount);
|
||||||
|
|
||||||
|
if (auto ter = addEmptyHolding(
|
||||||
|
view, pseudoId, mPriorBalance, sleVault->at(sfAsset), j_))
|
||||||
|
return ter;
|
||||||
|
|
||||||
|
// Initialize data fields:
|
||||||
|
broker->at(sfSequence) = sequence;
|
||||||
|
broker->at(sfVaultID) = vaultID;
|
||||||
|
broker->at(sfOwner) = account_;
|
||||||
|
broker->at(sfAccount) = pseudoId;
|
||||||
|
if (auto const data = tx[~sfData])
|
||||||
|
broker->at(sfData) = *data;
|
||||||
|
if (auto const rate = tx[~sfManagementFeeRate])
|
||||||
|
broker->at(sfManagementFeeRate) = *rate;
|
||||||
|
if (auto const debtMax = tx[~sfDebtMaximum]; debtMax && *debtMax)
|
||||||
|
broker->at(sfDebtMaximum) = *debtMax;
|
||||||
|
if (auto const coverMin = tx[~sfCoverRateMinimum])
|
||||||
|
broker->at(sfCoverRateMinimum) = *coverMin;
|
||||||
|
if (auto const coverLiq = tx[~sfCoverRateLiquidation])
|
||||||
|
broker->at(sfCoverRateLiquidation) = *coverLiq;
|
||||||
|
|
||||||
|
view.insert(broker);
|
||||||
|
}
|
||||||
|
|
||||||
|
return temDISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace ripple
|
||||||
60
src/xrpld/app/tx/detail/LoanBroker.h
Normal file
60
src/xrpld/app/tx/detail/LoanBroker.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2022 Ripple Labs Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef RIPPLE_TX_LOANBROKER_H_INCLUDED
|
||||||
|
#define RIPPLE_TX_LOANBROKER_H_INCLUDED
|
||||||
|
|
||||||
|
#include <xrpld/app/tx/detail/Transactor.h>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
|
||||||
|
// Lending protocol has dependencies, so capture them here.
|
||||||
|
bool
|
||||||
|
lendingProtocolEnabled(PreflightContext const& ctx);
|
||||||
|
|
||||||
|
class LoanBrokerSet : public Transactor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||||
|
|
||||||
|
explicit LoanBrokerSet(ApplyContext& ctx) : Transactor(ctx)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
isEnabled(PreflightContext const& ctx);
|
||||||
|
|
||||||
|
static std::uint32_t
|
||||||
|
getFlagsMask(PreflightContext const& ctx);
|
||||||
|
|
||||||
|
static NotTEC
|
||||||
|
doPreflight(PreflightContext const& ctx);
|
||||||
|
|
||||||
|
static TER
|
||||||
|
preclaim(PreclaimContext const& ctx);
|
||||||
|
|
||||||
|
TER
|
||||||
|
doApply() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace ripple
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -205,6 +205,16 @@ Transactor::Transactor(ApplyContext& ctx)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Transactor::validDataLength(
|
||||||
|
std::optional<Slice> const& slice,
|
||||||
|
std::size_t maxLength)
|
||||||
|
{
|
||||||
|
if (!slice)
|
||||||
|
return true;
|
||||||
|
return !slice->empty() && slice->length() <= maxLength;
|
||||||
|
}
|
||||||
|
|
||||||
XRPAmount
|
XRPAmount
|
||||||
Transactor::calculateBaseFee(ReadView const& view, STTx const& tx)
|
Transactor::calculateBaseFee(ReadView const& view, STTx const& tx)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -146,10 +146,6 @@ public:
|
|||||||
static XRPAmount
|
static XRPAmount
|
||||||
calculateBaseFee(ReadView const& view, STTx const& tx);
|
calculateBaseFee(ReadView const& view, STTx const& tx);
|
||||||
|
|
||||||
// Base class always returns true
|
|
||||||
static bool
|
|
||||||
isEnabled(PreflightContext const& ctx);
|
|
||||||
|
|
||||||
/* Do NOT define a preflight function in a derived class.
|
/* Do NOT define a preflight function in a derived class.
|
||||||
Instead, define
|
Instead, define
|
||||||
|
|
||||||
@@ -212,6 +208,17 @@ protected:
|
|||||||
Fees const& fees,
|
Fees const& fees,
|
||||||
ApplyFlags flags);
|
ApplyFlags flags);
|
||||||
|
|
||||||
|
// Base class always returns true
|
||||||
|
static bool
|
||||||
|
isEnabled(PreflightContext const& ctx);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
validDataLength(std::optional<Slice> const& slice, std::size_t maxLength);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static bool
|
||||||
|
validNumericRange(std::optional<T> value, T min, T max);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::pair<TER, XRPAmount>
|
std::pair<TER, XRPAmount>
|
||||||
reset(XRPAmount fee);
|
reset(XRPAmount fee);
|
||||||
@@ -272,6 +279,15 @@ Transactor::preflight(PreflightContext const& ctx)
|
|||||||
return detail::preflight2(ctx);
|
return detail::preflight2(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool
|
||||||
|
Transactor::validNumericRange(std::optional<T> value, T min, T max)
|
||||||
|
{
|
||||||
|
if (!value)
|
||||||
|
return true;
|
||||||
|
return value >= min && value <= max;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -53,11 +53,8 @@ VaultCreate::getFlagsMask(PreflightContext const& ctx)
|
|||||||
NotTEC
|
NotTEC
|
||||||
VaultCreate::doPreflight(PreflightContext const& ctx)
|
VaultCreate::doPreflight(PreflightContext const& ctx)
|
||||||
{
|
{
|
||||||
if (auto const data = ctx.tx[~sfData])
|
if (!validDataLength(ctx.tx[~sfData], maxDataPayloadLength))
|
||||||
{
|
|
||||||
if (data->empty() || data->length() > maxDataPayloadLength)
|
|
||||||
return temMALFORMED;
|
return temMALFORMED;
|
||||||
}
|
|
||||||
|
|
||||||
if (auto const withdrawalPolicy = ctx.tx[~sfWithdrawalPolicy])
|
if (auto const withdrawalPolicy = ctx.tx[~sfWithdrawalPolicy])
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#include <xrpld/app/tx/detail/DepositPreauth.h>
|
#include <xrpld/app/tx/detail/DepositPreauth.h>
|
||||||
#include <xrpld/app/tx/detail/Escrow.h>
|
#include <xrpld/app/tx/detail/Escrow.h>
|
||||||
#include <xrpld/app/tx/detail/LedgerStateFix.h>
|
#include <xrpld/app/tx/detail/LedgerStateFix.h>
|
||||||
|
#include <xrpld/app/tx/detail/LoanBroker.h>
|
||||||
#include <xrpld/app/tx/detail/MPTokenAuthorize.h>
|
#include <xrpld/app/tx/detail/MPTokenAuthorize.h>
|
||||||
#include <xrpld/app/tx/detail/MPTokenIssuanceCreate.h>
|
#include <xrpld/app/tx/detail/MPTokenIssuanceCreate.h>
|
||||||
#include <xrpld/app/tx/detail/MPTokenIssuanceDestroy.h>
|
#include <xrpld/app/tx/detail/MPTokenIssuanceDestroy.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user