mirror of
https://github.com/XRPLF/rippled.git
synced 2026-09-17 12:58:37 +00:00
Compare commits
15 Commits
develop
...
mvadari/ch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a7d98621d | ||
|
|
4203d2f522 | ||
|
|
1745983b63 | ||
|
|
0442f89919 | ||
|
|
c590f1cd0e | ||
|
|
28a4d394be | ||
|
|
315775dc21 | ||
|
|
6763158124 | ||
|
|
2561b1b565 | ||
|
|
d9ad0a312c | ||
|
|
b1eda783d0 | ||
|
|
99f7b65da7 | ||
|
|
efd6275569 | ||
|
|
c64aaccf7b | ||
|
|
ce57c882ce |
66
include/xrpl/tx/helpers/PreflightHelpers.h
Normal file
66
include/xrpl/tx/helpers/PreflightHelpers.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// Checks whether value is within [min, max], inclusive.
|
||||
template <class T>
|
||||
inline bool
|
||||
checkBounds(T const& value, T const& min, T const& max)
|
||||
{
|
||||
return value >= min && value <= max;
|
||||
}
|
||||
|
||||
// Checks whether a container's size is at most max.
|
||||
template <class T>
|
||||
inline bool
|
||||
checkSize(T const& value, std::size_t const max)
|
||||
{
|
||||
return value.size() <= max;
|
||||
}
|
||||
|
||||
// Checks whether a container is non-empty and its size is at most max.
|
||||
template <class T>
|
||||
inline bool
|
||||
checkSizeAndNonEmpty(T const& value, std::size_t const max)
|
||||
{
|
||||
return !value.empty() && value.size() <= max;
|
||||
}
|
||||
|
||||
// Checks whether a hash-like identifier field (e.g. a uint256 object ID) is
|
||||
// unset/zero.
|
||||
template <class T>
|
||||
inline bool
|
||||
isZeroId(T const& id)
|
||||
{
|
||||
return id == beast::kZero;
|
||||
}
|
||||
|
||||
// Checks whether an amount is a strictly positive XRP amount.
|
||||
inline bool
|
||||
isPositiveXRPAmount(STAmount const& amount)
|
||||
{
|
||||
return isXRP(amount) && amount > beast::kZero;
|
||||
}
|
||||
|
||||
// Checks whether an amount (of any asset type) is strictly positive.
|
||||
inline bool
|
||||
isPositiveAmount(STAmount const& amount)
|
||||
{
|
||||
return amount > beast::kZero;
|
||||
}
|
||||
|
||||
// Checks whether a currency code is the reserved "bad"/XRP currency code,
|
||||
// i.e. not a valid IOU currency.
|
||||
inline bool
|
||||
isBadCurrency(Currency const& currency)
|
||||
{
|
||||
return badCurrency() == currency;
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -3,3 +3,7 @@
|
||||
See the repo-level [AGENTS.md](../../../AGENTS.md) for general build/test/style guidance.
|
||||
|
||||
Any change to transaction-processing behavior must be gated behind an amendment. New amendments (and fixes, i.e. `fix*` amendments) are added to [`include/xrpl/protocol/detail/features.macro`](../../../include/xrpl/protocol/detail/features.macro), as an `XRPL_FEATURE(...)` or `XRPL_FIX(...)` entry added to the top of the list (the list is kept in reverse chronological order). Once the pre-amendment code path for a retired amendment is removed, move its entry to `XRPL_RETIRE_FEATURE(...)`/`XRPL_RETIRE_FIX(...)` instead of deleting it.
|
||||
|
||||
## Preflight helpers
|
||||
|
||||
When writing transactor preflight logic, prefer the helpers in [`include/xrpl/tx/helpers/PreflightHelpers.h`](../../../include/xrpl/tx/helpers/PreflightHelpers.h) over ad-hoc checks. If the same check pattern shows up in more than one transactor, add a new helper there rather than inlining it.
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/SignerEntries.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
@@ -247,7 +248,7 @@ SignerListSet::validateQuorumAndSignerEntries(
|
||||
// Reject if there are too many or too few entries in the list.
|
||||
{
|
||||
std::size_t const signerCount = signers.size();
|
||||
if (signerCount < STTx::kMinMultiSigners || signerCount > STTx::kMaxMultiSigners)
|
||||
if (!checkBounds(signerCount, STTx::kMinMultiSigners, STTx::kMaxMultiSigners))
|
||||
{
|
||||
JLOG(j.trace()) << "Too many or too few signers in signer list.";
|
||||
return temMALFORMED;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
#include <xrpl/tx/SignerEntries.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
#include <xrpl/tx/paths/Flow.h>
|
||||
#include <xrpl/tx/paths/detail/Steps.h>
|
||||
|
||||
@@ -1369,8 +1370,8 @@ XChainCreateBridge::preflight(PreflightContext const& ctx)
|
||||
}
|
||||
|
||||
if (minAccountCreate &&
|
||||
((!isXRP(*minAccountCreate) || minAccountCreate->signum() <= 0) ||
|
||||
!isXRP(bridgeSpec.lockingChainIssue()) || !isXRP(bridgeSpec.issuingChainIssue())))
|
||||
(!isPositiveXRPAmount(*minAccountCreate) || !isXRP(bridgeSpec.lockingChainIssue()) ||
|
||||
!isXRP(bridgeSpec.issuingChainIssue())))
|
||||
{
|
||||
return temXCHAIN_BRIDGE_BAD_MIN_ACCOUNT_CREATE_AMOUNT;
|
||||
}
|
||||
@@ -1540,8 +1541,8 @@ BridgeModify::preflight(PreflightContext const& ctx)
|
||||
}
|
||||
|
||||
if (minAccountCreate &&
|
||||
((!isXRP(*minAccountCreate) || minAccountCreate->signum() <= 0) ||
|
||||
!isXRP(bridgeSpec.lockingChainIssue()) || !isXRP(bridgeSpec.issuingChainIssue())))
|
||||
(!isPositiveXRPAmount(*minAccountCreate) || !isXRP(bridgeSpec.lockingChainIssue()) ||
|
||||
!isXRP(bridgeSpec.issuingChainIssue())))
|
||||
{
|
||||
return temXCHAIN_BRIDGE_BAD_MIN_ACCOUNT_CREATE_AMOUNT;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <cstdint>
|
||||
namespace xrpl {
|
||||
@@ -41,7 +42,7 @@ CredentialAccept::preflight(PreflightContext const& ctx)
|
||||
}
|
||||
|
||||
auto const credType = ctx.tx[sfCredentialType];
|
||||
if (credType.empty() || (credType.size() > kMaxCredentialTypeLength))
|
||||
if (!checkSizeAndNonEmpty(credType, kMaxCredentialTypeLength))
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Malformed transaction: invalid size of CredentialType.";
|
||||
return temMALFORMED;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
@@ -62,14 +63,14 @@ CredentialCreate::preflight(PreflightContext const& ctx)
|
||||
}
|
||||
|
||||
auto const uri = tx[~sfURI];
|
||||
if (uri && (uri->empty() || (uri->size() > kMaxCredentialUriLength)))
|
||||
if (uri && !checkSizeAndNonEmpty(*uri, kMaxCredentialUriLength))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: invalid size of URI.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
auto const credType = tx[sfCredentialType];
|
||||
if (credType.empty() || (credType.size() > kMaxCredentialTypeLength))
|
||||
if (!checkSizeAndNonEmpty(credType, kMaxCredentialTypeLength))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: invalid size of CredentialType.";
|
||||
return temMALFORMED;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <cstdint>
|
||||
namespace xrpl {
|
||||
@@ -50,7 +51,7 @@ CredentialDelete::preflight(PreflightContext const& ctx)
|
||||
}
|
||||
|
||||
auto const credType = ctx.tx[sfCredentialType];
|
||||
if (credType.empty() || (credType.size() > kMaxCredentialTypeLength))
|
||||
if (!checkSizeAndNonEmpty(credType, kMaxCredentialTypeLength))
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Malformed transaction: invalid size of CredentialType.";
|
||||
return temMALFORMED;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
@@ -25,7 +26,7 @@ NotTEC
|
||||
DelegateSet::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
auto const& permissions = ctx.tx.getFieldArray(sfPermissions);
|
||||
if (permissions.size() > kPermissionMaxSize)
|
||||
if (!checkSize(permissions, kPermissionMaxSize))
|
||||
return temARRAY_TOO_LARGE;
|
||||
|
||||
// can not authorize self
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
@@ -76,7 +77,7 @@ AMMBid::preflight(PreflightContext const& ctx)
|
||||
if (ctx.tx.isFieldPresent(sfAuthAccounts))
|
||||
{
|
||||
auto const authAccounts = ctx.tx.getFieldArray(sfAuthAccounts);
|
||||
if (authAccounts.size() > kAuctionSlotMaxAuthAccounts)
|
||||
if (!checkSize(authAccounts, kAuctionSlotMaxAuthAccounts))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Bid: Invalid number of AuthAccounts.";
|
||||
return temMALFORMED;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
#include <xrpl/tx/transactors/dex/AMMWithdraw.h>
|
||||
|
||||
#include <cstdint>
|
||||
@@ -91,7 +92,7 @@ AMMClawback::preflight(PreflightContext const& ctx)
|
||||
return temBAD_AMOUNT;
|
||||
}
|
||||
|
||||
if (clawAmount && *clawAmount <= beast::kZero)
|
||||
if (clawAmount && !isPositiveAmount(*clawAmount))
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <bit>
|
||||
#include <cstdint>
|
||||
@@ -123,7 +124,7 @@ AMMDeposit::preflight(PreflightContext const& ctx)
|
||||
return temBAD_AMM_TOKENS;
|
||||
}
|
||||
|
||||
if (lpTokens && *lpTokens <= beast::kZero)
|
||||
if (lpTokens && !isPositiveAmount(*lpTokens))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Deposit: invalid LPTokens";
|
||||
return temBAD_AMM_TOKENS;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <bit>
|
||||
@@ -129,7 +130,7 @@ AMMWithdraw::preflight(PreflightContext const& ctx)
|
||||
return temBAD_AMM_TOKENS;
|
||||
}
|
||||
|
||||
if (lpTokens && *lpTokens <= beast::kZero)
|
||||
if (lpTokens && !isPositiveAmount(*lpTokens))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Withdraw: invalid tokens.";
|
||||
return temBAD_AMM_TOKENS;
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/applySteps.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
#include <xrpl/tx/paths/Flow.h>
|
||||
#include <xrpl/tx/paths/detail/Steps.h>
|
||||
|
||||
@@ -100,7 +101,7 @@ OfferCreate::preflight(PreflightContext const& ctx)
|
||||
// A zero DomainID is invalid for a PermissionedDomain ledger entry because
|
||||
// keylet::permissionedDomain(uint256) uses the DomainID as the ledger key.
|
||||
if (auto const domainID = tx[~sfDomainID];
|
||||
ctx.rules.enabled(fixCleanup3_2_0) && domainID && *domainID == beast::kZero)
|
||||
ctx.rules.enabled(fixCleanup3_2_0) && domainID && isZeroId(*domainID))
|
||||
return temMALFORMED;
|
||||
|
||||
bool const bImmediateOrCancel(tx.isFlag(tfImmediateOrCancel));
|
||||
@@ -137,7 +138,7 @@ OfferCreate::preflight(PreflightContext const& ctx)
|
||||
JLOG(j.debug()) << "Malformed offer: redundant (XRP for XRP)";
|
||||
return temBAD_OFFER;
|
||||
}
|
||||
if (saTakerPays <= beast::kZero || saTakerGets <= beast::kZero)
|
||||
if (!isPositiveAmount(saTakerPays) || !isPositiveAmount(saTakerGets))
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed offer: bad amount";
|
||||
return temBAD_OFFER;
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/applySteps.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <memory>
|
||||
#include <system_error>
|
||||
@@ -106,10 +106,10 @@ NotTEC
|
||||
escrowCreatePreflightHelper<Issue>(PreflightContext const& ctx)
|
||||
{
|
||||
STAmount const amount = ctx.tx[sfAmount];
|
||||
if (amount.native() || amount <= beast::kZero)
|
||||
if (amount.native() || !isPositiveAmount(amount))
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
if (badCurrency() == amount.get<Issue>().currency)
|
||||
if (isBadCurrency(amount.get<Issue>().currency))
|
||||
return temBAD_CURRENCY;
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -123,7 +123,7 @@ escrowCreatePreflightHelper<MPTIssue>(PreflightContext const& ctx)
|
||||
return temDISABLED;
|
||||
|
||||
auto const amount = ctx.tx[sfAmount];
|
||||
if (amount.native() || amount.mpt() > MPTAmount{kMaxMpTokenAmount} || amount <= beast::kZero)
|
||||
if (amount.native() || amount.mpt() > MPTAmount{kMaxMpTokenAmount} || !isPositiveAmount(amount))
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -146,7 +146,7 @@ EscrowCreate::preflight(PreflightContext const& ctx)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (amount <= beast::kZero)
|
||||
if (!isPositiveXRPAmount(amount))
|
||||
return temBAD_AMOUNT;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <xrpl/protocol/Units.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
@@ -48,7 +49,7 @@ LoanBrokerCoverClawback::preflight(PreflightContext const& ctx)
|
||||
if (!brokerID && !amount)
|
||||
return temINVALID;
|
||||
|
||||
if (brokerID && *brokerID == beast::kZero)
|
||||
if (brokerID && isZeroId(*brokerID))
|
||||
return temINVALID;
|
||||
|
||||
if (amount)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -27,11 +28,11 @@ LoanBrokerCoverDeposit::checkExtraFeatures(PreflightContext const& ctx)
|
||||
NotTEC
|
||||
LoanBrokerCoverDeposit::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.tx[sfLoanBrokerID] == beast::kZero)
|
||||
if (isZeroId(ctx.tx[sfLoanBrokerID]))
|
||||
return temINVALID;
|
||||
|
||||
auto const dstAmount = ctx.tx[sfAmount];
|
||||
if (dstAmount <= beast::kZero)
|
||||
if (!isPositiveAmount(dstAmount))
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
if (!isLegalNet(dstAmount))
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/Number.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
@@ -20,6 +19,7 @@
|
||||
#include <xrpl/protocol/Units.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -36,11 +36,11 @@ LoanBrokerCoverWithdraw::checkExtraFeatures(PreflightContext const& ctx)
|
||||
NotTEC
|
||||
LoanBrokerCoverWithdraw::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.tx[sfLoanBrokerID] == beast::kZero)
|
||||
if (isZeroId(ctx.tx[sfLoanBrokerID]))
|
||||
return temINVALID;
|
||||
|
||||
auto const dstAmount = ctx.tx[sfAmount];
|
||||
if (dstAmount <= beast::kZero)
|
||||
if (!isPositiveAmount(dstAmount))
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
if (!isLegalNet(dstAmount))
|
||||
@@ -48,7 +48,7 @@ LoanBrokerCoverWithdraw::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (auto const destination = ctx.tx[~sfDestination])
|
||||
{
|
||||
if (*destination == beast::kZero)
|
||||
if (isZeroId(*destination))
|
||||
{
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -28,7 +29,7 @@ LoanBrokerDelete::checkExtraFeatures(PreflightContext const& ctx)
|
||||
NotTEC
|
||||
LoanBrokerDelete::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.tx[sfLoanBrokerID] == beast::kZero)
|
||||
if (isZeroId(ctx.tx[sfLoanBrokerID]))
|
||||
return temINVALID;
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/Number.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
@@ -21,6 +20,7 @@
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@@ -59,13 +59,13 @@ LoanBrokerSet::preflight(PreflightContext const& ctx)
|
||||
tx.isFieldPresent(sfCoverRateLiquidation))
|
||||
return temINVALID;
|
||||
|
||||
if (tx[sfLoanBrokerID] == beast::kZero)
|
||||
if (isZeroId(tx[sfLoanBrokerID]))
|
||||
return temINVALID;
|
||||
}
|
||||
|
||||
if (auto const vaultID = tx.at(~sfVaultID))
|
||||
{
|
||||
if (*vaultID == beast::kZero)
|
||||
if (isZeroId(*vaultID))
|
||||
return temINVALID;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -27,7 +28,7 @@ LoanDelete::checkExtraFeatures(PreflightContext const& ctx)
|
||||
NotTEC
|
||||
LoanDelete::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.tx[sfLoanID] == beast::kZero)
|
||||
if (isZeroId(ctx.tx[sfLoanID]))
|
||||
return temINVALID;
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/Number.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
@@ -23,6 +22,7 @@
|
||||
#include <xrpl/protocol/Units.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
@@ -43,7 +43,7 @@ LoanManage::getFlagsMask(PreflightContext const& ctx)
|
||||
NotTEC
|
||||
LoanManage::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.tx[sfLoanID] == beast::kZero)
|
||||
if (isZeroId(ctx.tx[sfLoanID]))
|
||||
return temINVALID;
|
||||
|
||||
// Flags are mutually exclusive
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <xrpl/protocol/Units.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
#include <xrpl/tx/transactors/lending/LoanManage.h>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -78,10 +79,10 @@ LoanPay::getFlagsMask(PreflightContext const& ctx)
|
||||
NotTEC
|
||||
LoanPay::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.tx[sfLoanID] == beast::kZero)
|
||||
if (isZeroId(ctx.tx[sfLoanID]))
|
||||
return temINVALID;
|
||||
|
||||
if (ctx.tx[sfAmount] <= beast::kZero)
|
||||
if (!isPositiveAmount(ctx.tx[sfAmount]))
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
// The loan payment flags are all mutually exclusive. If more than one is
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <xrpl/protocol/Units.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
@@ -146,7 +147,7 @@ LoanSet::preflight(PreflightContext const& ctx)
|
||||
return *ret;
|
||||
}
|
||||
|
||||
if (auto const brokerID = ctx.tx[~sfLoanBrokerID]; brokerID && *brokerID == beast::kZero)
|
||||
if (auto const brokerID = ctx.tx[~sfLoanBrokerID]; brokerID && isZeroId(*brokerID))
|
||||
return temINVALID;
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <algorithm>
|
||||
namespace xrpl {
|
||||
@@ -24,7 +25,7 @@ NFTokenCancelOffer::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
auto const& offerIds = ctx.tx[sfNFTokenOffers];
|
||||
|
||||
if (offerIds.empty() || (offerIds.size() > kMaxTokenOfferCancelCount))
|
||||
if (!checkSizeAndNonEmpty(offerIds, kMaxTokenOfferCancelCount))
|
||||
return temMALFORMED;
|
||||
|
||||
// Zero offer IDs cannot be passed as ledger entry keys.
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
@@ -46,7 +47,7 @@ OracleSet::preflight(PreflightContext const& ctx)
|
||||
auto const& dataSeries = ctx.tx.getFieldArray(sfPriceDataSeries);
|
||||
if (dataSeries.empty())
|
||||
return temARRAY_EMPTY;
|
||||
if (dataSeries.size() > kMaxOracleDataSeries)
|
||||
if (!checkSize(dataSeries, kMaxOracleDataSeries))
|
||||
return temARRAY_TOO_LARGE;
|
||||
|
||||
auto isInvalidLength = [&](auto const& sField, std::size_t length) {
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/applySteps.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
#include <xrpl/tx/paths/RippleCalc.h>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -143,7 +144,7 @@ Payment::preflight(PreflightContext const& ctx)
|
||||
// A zero DomainID is invalid for a PermissionedDomain ledger entry because
|
||||
// keylet::permissionedDomain(uint256) uses the DomainID as the ledger key.
|
||||
if (auto const domainID = tx[~sfDomainID];
|
||||
ctx.rules.enabled(fixCleanup3_2_0) && domainID && *domainID == beast::kZero)
|
||||
ctx.rules.enabled(fixCleanup3_2_0) && domainID && isZeroId(*domainID))
|
||||
return temMALFORMED;
|
||||
|
||||
bool const partialPaymentAllowed = tx.isFlag(tfPartialPayment);
|
||||
@@ -183,13 +184,13 @@ Payment::preflight(PreflightContext const& ctx)
|
||||
<< "Payment destination account not specified.";
|
||||
return temDST_NEEDED;
|
||||
}
|
||||
if (hasMax && maxSourceAmount <= beast::kZero)
|
||||
if (hasMax && !isPositiveAmount(maxSourceAmount))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: bad max amount: "
|
||||
<< maxSourceAmount.getFullText();
|
||||
return temBAD_AMOUNT;
|
||||
}
|
||||
if (dstAmount <= beast::kZero)
|
||||
if (!isPositiveAmount(dstAmount))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: bad dst amount: " << dstAmount.getFullText();
|
||||
return temBAD_AMOUNT;
|
||||
@@ -439,8 +440,8 @@ Payment::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
STPathSet const& paths = ctx.tx.getFieldPathSet(sfPaths);
|
||||
|
||||
if (paths.size() > kMaxPathSize || std::ranges::any_of(paths, [](STPath const& path) {
|
||||
return path.size() > kMaxPathLength;
|
||||
if (!checkSize(paths, kMaxPathSize) || std::ranges::any_of(paths, [](STPath const& path) {
|
||||
return !checkSize(path, kMaxPathLength);
|
||||
}))
|
||||
{
|
||||
// Open view: the soft tel (unchanged). Inner batch txns are claimed
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
@@ -42,15 +43,15 @@ PaymentChannelClaim::getFlagsMask(PreflightContext const&)
|
||||
NotTEC
|
||||
PaymentChannelClaim::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.rules.enabled(fixCleanup3_2_0) && ctx.tx[sfChannel] == beast::kZero)
|
||||
if (ctx.rules.enabled(fixCleanup3_2_0) && isZeroId(ctx.tx[sfChannel]))
|
||||
return temMALFORMED;
|
||||
|
||||
auto const bal = ctx.tx[~sfBalance];
|
||||
if (bal && (!isXRP(*bal) || *bal <= beast::kZero))
|
||||
if (bal && !isPositiveXRPAmount(*bal))
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
auto const amt = ctx.tx[~sfAmount];
|
||||
if (amt && (!isXRP(*amt) || *amt <= beast::kZero))
|
||||
if (amt && !isPositiveXRPAmount(*amt))
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
if (bal && amt && *bal > *amt)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <xrpl/tx/transactors/payment_channel/PaymentChannelCreate.h>
|
||||
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
@@ -21,6 +20,7 @@
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/applySteps.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -57,7 +57,7 @@ PaymentChannelCreate::makeTxConsequences(PreflightContext const& ctx)
|
||||
NotTEC
|
||||
PaymentChannelCreate::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::kZero))
|
||||
if (!isPositiveXRPAmount(ctx.tx[sfAmount]))
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
if (ctx.tx[sfAccount] == ctx.tx[sfDestination])
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <xrpl/tx/transactors/payment_channel/PaymentChannelFund.h>
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
@@ -19,6 +18,7 @@
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/applySteps.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -31,10 +31,10 @@ PaymentChannelFund::makeTxConsequences(PreflightContext const& ctx)
|
||||
NotTEC
|
||||
PaymentChannelFund::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.rules.enabled(fixCleanup3_2_0) && ctx.tx[sfChannel] == beast::kZero)
|
||||
if (ctx.rules.enabled(fixCleanup3_2_0) && isZeroId(ctx.tx[sfChannel]))
|
||||
return temMALFORMED;
|
||||
|
||||
if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::kZero))
|
||||
if (!isPositiveXRPAmount(ctx.tx[sfAmount]))
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <xrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -11,6 +10,7 @@
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -18,7 +18,7 @@ NotTEC
|
||||
PermissionedDomainDelete::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
auto const domain = ctx.tx.getFieldH256(sfDomainID);
|
||||
if (domain == beast::kZero)
|
||||
if (isZeroId(domain))
|
||||
return temMALFORMED;
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.h>
|
||||
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
@@ -17,6 +16,7 @@
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
@@ -40,7 +40,7 @@ PermissionedDomainSet::preflight(PreflightContext const& ctx)
|
||||
return err;
|
||||
|
||||
auto const domain = ctx.tx.at(~sfDomainID);
|
||||
if (domain && *domain == beast::kZero)
|
||||
if (domain && isZeroId(*domain))
|
||||
return temMALFORMED;
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/applySteps.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <bit>
|
||||
@@ -236,7 +237,7 @@ Batch::preflight(PreflightContext const& ctx)
|
||||
}
|
||||
|
||||
if (ctx.tx.isFieldPresent(sfBatchSigners) &&
|
||||
ctx.tx.getFieldArray(sfBatchSigners).size() > kMaxBatchSigners)
|
||||
!checkSize(ctx.tx.getFieldArray(sfBatchSigners), kMaxBatchSigners))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "BatchTrace[" << parentBatchId << "]:"
|
||||
<< "signers array exceeds " << kMaxBatchSigners << " entries.";
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/applySteps.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
@@ -32,7 +33,7 @@ NotTEC
|
||||
TicketCreate::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (std::uint32_t const count = ctx.tx[sfTicketCount];
|
||||
count < kMinValidCount || count > kMaxValidCount)
|
||||
!checkBounds(count, kMinValidCount, kMaxValidCount))
|
||||
return temINVALID_COUNT;
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <variant>
|
||||
@@ -44,7 +45,7 @@ preflightHelper<Issue>(PreflightContext const& ctx)
|
||||
// The issuer field is used for the token holder instead
|
||||
AccountID const& holder = clawAmount.getIssuer();
|
||||
|
||||
if (issuer == holder || isXRP(clawAmount) || clawAmount <= beast::kZero)
|
||||
if (issuer == holder || isXRP(clawAmount) || !isPositiveAmount(clawAmount))
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -67,7 +68,7 @@ preflightHelper<MPTIssue>(PreflightContext const& ctx)
|
||||
if (ctx.tx[sfAccount] == *mptHolder)
|
||||
return temMALFORMED;
|
||||
|
||||
if (clawAmount.mpt() > MPTAmount{kMaxMpTokenAmount} || clawAmount <= beast::kZero)
|
||||
if (clawAmount.mpt() > MPTAmount{kMaxMpTokenAmount} || !isPositiveAmount(clawAmount))
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <xrpl/tx/transactors/token/MPTokenIssuanceCreate.h>
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
@@ -20,6 +19,7 @@
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
@@ -93,7 +93,7 @@ MPTokenIssuanceCreate::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (auto const domain = ctx.tx[~sfDomainID])
|
||||
{
|
||||
if (*domain == beast::kZero)
|
||||
if (isZeroId(*domain))
|
||||
return temMALFORMED;
|
||||
|
||||
// Domain present implies that MPTokenIssuance is not public
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_set>
|
||||
@@ -98,7 +99,7 @@ TrustSet::preflight(PreflightContext const& ctx)
|
||||
return temBAD_LIMIT;
|
||||
}
|
||||
|
||||
if (badCurrency() == saLimitAmount.get<Issue>().currency)
|
||||
if (isBadCurrency(saLimitAmount.get<Issue>().currency))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: specifies XRP as IOU";
|
||||
return temBAD_CURRENCY;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
@@ -18,13 +17,14 @@
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
NotTEC
|
||||
VaultDelete::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.tx[sfVaultID] == beast::kZero)
|
||||
if (isZeroId(ctx.tx[sfVaultID]))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "VaultDelete: zero/empty vault ID.";
|
||||
return temMALFORMED;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/helpers/PreflightHelpers.h>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -52,18 +53,18 @@ shouldWaiveWithdrawal(ReadView const& view, AccountID const& account, SLE::const
|
||||
NotTEC
|
||||
VaultWithdraw::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.tx[sfVaultID] == beast::kZero)
|
||||
if (isZeroId(ctx.tx[sfVaultID]))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "VaultWithdraw: zero/empty vault ID.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
if (ctx.tx[sfAmount] <= beast::kZero)
|
||||
if (!isPositiveAmount(ctx.tx[sfAmount]))
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
if (auto const destination = ctx.tx[~sfDestination])
|
||||
{
|
||||
if (*destination == beast::kZero)
|
||||
if (isZeroId(*destination))
|
||||
{
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user