mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-27 09:00:32 +00:00
migrate preflight errors
This commit is contained in:
@@ -64,9 +64,7 @@ preflight0(PreflightContext const& ctx, std::uint32_t flagMask)
|
||||
{
|
||||
if (isPseudoTx(ctx.tx) && ctx.tx.isFlag(tfInnerBatchTxn))
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Pseudo transactions cannot contain the "
|
||||
"tfInnerBatchTxn flag.";
|
||||
return temINVALID_FLAG;
|
||||
return {temINVALID_FLAG, "Pseudo transactions cannot contain the tfInnerBatchTxn flag."};
|
||||
}
|
||||
|
||||
if (!isPseudoTx(ctx.tx) || ctx.tx.isFieldPresent(sfNetworkID))
|
||||
@@ -97,8 +95,7 @@ preflight0(PreflightContext const& ctx, std::uint32_t flagMask)
|
||||
|
||||
if (txID == beast::kZero)
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "applyTransaction: transaction id may not be zero";
|
||||
return temINVALID;
|
||||
return {temINVALID, "applyTransaction: transaction id may not be zero"};
|
||||
}
|
||||
|
||||
if ((ctx.tx.getFlags() & flagMask) != 0u)
|
||||
@@ -124,8 +121,7 @@ preflightCheckSigningKey(STObject const& sigObject, beast::Journal j)
|
||||
if (auto const spk = sigObject.getFieldVL(sfSigningPubKey);
|
||||
!spk.empty() && !publicKeyType(makeSlice(spk)))
|
||||
{
|
||||
JLOG(j.debug()) << "preflightCheckSigningKey: invalid signing key";
|
||||
return temBAD_SIGNATURE;
|
||||
return {temBAD_SIGNATURE, "preflightCheckSigningKey: invalid signing key"};
|
||||
}
|
||||
return tesSUCCESS;
|
||||
}
|
||||
@@ -184,13 +180,11 @@ preflight1Sponsor(PreflightContext const& ctx)
|
||||
|
||||
if (hasSponsor != hasSponsorFlags)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "preflight1: sponsor and sponsor flags mismatch";
|
||||
return temINVALID_FLAG;
|
||||
return {temINVALID_FLAG, "preflight1: sponsor and sponsor flags mismatch"};
|
||||
}
|
||||
if (hasSponsorSig && (!hasSponsor || !hasSponsorFlags))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "preflight1: sponsor signature without sponsor definition";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "preflight1: sponsor signature without sponsor definition"};
|
||||
}
|
||||
|
||||
if (hasSponsorFlags)
|
||||
@@ -198,8 +192,7 @@ preflight1Sponsor(PreflightContext const& ctx)
|
||||
auto const sponsorFlags = ctx.tx.getFieldU32(sfSponsorFlags);
|
||||
if (((sponsorFlags & spfSponsorFlagMask) != 0u) || sponsorFlags == 0)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "preflight1: invalid sponsor flags";
|
||||
return temINVALID_FLAG;
|
||||
return {temINVALID_FLAG, "preflight1: invalid sponsor flags"};
|
||||
}
|
||||
|
||||
// Reserve sponsorship is only permitted for an explicit allow-list of
|
||||
@@ -208,17 +201,16 @@ preflight1Sponsor(PreflightContext const& ctx)
|
||||
{
|
||||
if (!isReserveSponsorAllowed(ctx.tx.getTxnType()))
|
||||
{
|
||||
JLOG(ctx.j.debug())
|
||||
<< "preflight1: spfSponsorReserve not allowed for this transaction type";
|
||||
return temINVALID_FLAG;
|
||||
return {
|
||||
temINVALID_FLAG,
|
||||
"preflight1: spfSponsorReserve not allowed for this transaction type"};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasSponsor && ctx.tx.getAccountID(sfSponsor) == ctx.tx.getAccountID(sfAccount))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "preflight1: Sponsor account cannot be the same as the account";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "preflight1: Sponsor account cannot be the same as the account"};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -255,16 +247,14 @@ Transactor::preflight1(PreflightContext const& ctx, std::uint32_t flagMask)
|
||||
auto const id = ctx.tx.getAccountID(sfAccount);
|
||||
if (id == beast::kZero)
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "preflight1: bad account id";
|
||||
return temBAD_SRC_ACCOUNT;
|
||||
return {temBAD_SRC_ACCOUNT, "preflight1: bad account id"};
|
||||
}
|
||||
|
||||
// No point in going any further if the transaction fee is malformed.
|
||||
auto const fee = ctx.tx.getFieldAmount(sfFee);
|
||||
if (!fee.native() || fee.negative() || !isLegalAmount(fee.xrp()))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "preflight1: invalid fee";
|
||||
return temBAD_FEE;
|
||||
return {temBAD_FEE, "preflight1: invalid fee"};
|
||||
}
|
||||
|
||||
if (auto const ret = detail::preflightCheckSigningKey(ctx.tx, ctx.j))
|
||||
@@ -525,8 +515,7 @@ Transactor::checkFee(PreclaimContext const& ctx, XRPAmount baseFee)
|
||||
if (feePaid == beast::kZero)
|
||||
return tesSUCCESS;
|
||||
|
||||
JLOG(ctx.j.trace()) << "Batch: Fee must be zero.";
|
||||
return temBAD_FEE; // LCOV_EXCL_LINE
|
||||
return {temBAD_FEE, "Batch: Fee must be zero."}; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
if (!isLegalAmount(feePaid) || feePaid < beast::kZero)
|
||||
@@ -715,9 +704,9 @@ Transactor::checkSeqProxy(ReadView const& view, STTx const& tx, beast::Journal j
|
||||
{
|
||||
if (tx.isFieldPresent(sfTicketSequence))
|
||||
{
|
||||
JLOG(j.trace()) << "applyTransaction: has both a TicketSequence "
|
||||
"and a non-zero Sequence number";
|
||||
return temSEQ_AND_TICKET;
|
||||
return {
|
||||
temSEQ_AND_TICKET,
|
||||
"applyTransaction: has both a TicketSequence and a non-zero Sequence number"};
|
||||
}
|
||||
if (tSeqProx != aSeq)
|
||||
{
|
||||
@@ -979,8 +968,9 @@ Transactor::checkSign(
|
||||
|
||||
if (!publicKeyType(makeSlice(pkSigner)))
|
||||
{
|
||||
JLOG(j.trace()) << "checkSign: signing public key type is unknown";
|
||||
return tefBAD_AUTH; // FIXME: should be better error!
|
||||
return {
|
||||
tefBAD_AUTH,
|
||||
"checkSign: signing public key type is unknown"}; // FIXME: should be better error!
|
||||
}
|
||||
|
||||
// Look up the account.
|
||||
@@ -1054,8 +1044,7 @@ Transactor::checkMultiSign(
|
||||
// If the signer list doesn't exist the account is not multi-signing.
|
||||
if (!sleAccountSigners)
|
||||
{
|
||||
JLOG(j.trace()) << "applyTransaction: Invalid: Not a multi-signing account.";
|
||||
return tefNOT_MULTI_SIGNING;
|
||||
return {tefNOT_MULTI_SIGNING, "applyTransaction: Invalid: Not a multi-signing account."};
|
||||
}
|
||||
|
||||
// We have plans to support multiple SignerLists in the future. The
|
||||
@@ -1091,15 +1080,13 @@ Transactor::checkMultiSign(
|
||||
{
|
||||
if (++iter == accountSigners->end())
|
||||
{
|
||||
JLOG(j.trace()) << "applyTransaction: Invalid SigningAccount.Account.";
|
||||
return tefBAD_SIGNATURE;
|
||||
return {tefBAD_SIGNATURE, "applyTransaction: Invalid SigningAccount.Account."};
|
||||
}
|
||||
}
|
||||
if (iter->account != txSignerAcctID)
|
||||
{
|
||||
// The SigningAccount is not in the SignerEntries.
|
||||
JLOG(j.trace()) << "applyTransaction: Invalid SigningAccount.Account.";
|
||||
return tefBAD_SIGNATURE;
|
||||
return {tefBAD_SIGNATURE, "applyTransaction: Invalid SigningAccount.Account."};
|
||||
}
|
||||
|
||||
// We found the SigningAccount in the list of valid signers. Now we
|
||||
@@ -1111,8 +1098,7 @@ Transactor::checkMultiSign(
|
||||
// STTx::checkMultiSign
|
||||
if (!spk.empty() && !publicKeyType(makeSlice(spk)))
|
||||
{
|
||||
JLOG(j.trace()) << "checkMultiSign: signing public key type is unknown";
|
||||
return tefBAD_SIGNATURE;
|
||||
return {tefBAD_SIGNATURE, "checkMultiSign: signing public key type is unknown"};
|
||||
}
|
||||
|
||||
XRPL_ASSERT(
|
||||
@@ -1159,8 +1145,8 @@ Transactor::checkMultiSign(
|
||||
|
||||
if ((signerAccountFlags & lsfDisableMaster) != 0u)
|
||||
{
|
||||
JLOG(j.trace()) << "applyTransaction: Signer:Account lsfDisableMaster.";
|
||||
return tefMASTER_DISABLED;
|
||||
return {
|
||||
tefMASTER_DISABLED, "applyTransaction: Signer:Account lsfDisableMaster."};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1170,20 +1156,17 @@ Transactor::checkMultiSign(
|
||||
// Public key must hash to the account's regular key.
|
||||
if (!sleTxSignerRoot)
|
||||
{
|
||||
JLOG(j.trace()) << "applyTransaction: Non-phantom signer "
|
||||
"lacks account root.";
|
||||
return tefBAD_SIGNATURE;
|
||||
return {
|
||||
tefBAD_SIGNATURE, "applyTransaction: Non-phantom signer lacks account root."};
|
||||
}
|
||||
|
||||
if (!sleTxSignerRoot->isFieldPresent(sfRegularKey))
|
||||
{
|
||||
JLOG(j.trace()) << "applyTransaction: Account lacks RegularKey.";
|
||||
return tefBAD_SIGNATURE;
|
||||
return {tefBAD_SIGNATURE, "applyTransaction: Account lacks RegularKey."};
|
||||
}
|
||||
if (signingAcctIDFromPubKey != sleTxSignerRoot->getAccountID(sfRegularKey))
|
||||
{
|
||||
JLOG(j.trace()) << "applyTransaction: Account doesn't match RegularKey.";
|
||||
return tefBAD_SIGNATURE;
|
||||
return {tefBAD_SIGNATURE, "applyTransaction: Account doesn't match RegularKey."};
|
||||
}
|
||||
}
|
||||
// The signer is legitimate. Add their weight toward the quorum.
|
||||
@@ -1193,8 +1176,7 @@ Transactor::checkMultiSign(
|
||||
// Cannot perform transaction if quorum is not met.
|
||||
if (weightSum < sleAccountSigners->getFieldU32(sfSignerQuorum))
|
||||
{
|
||||
JLOG(j.trace()) << "applyTransaction: Signers failed to meet quorum.";
|
||||
return tefBAD_QUORUM;
|
||||
return {tefBAD_QUORUM, "applyTransaction: Signers failed to meet quorum."};
|
||||
}
|
||||
|
||||
// Met the quorum. Continue.
|
||||
|
||||
@@ -825,14 +825,12 @@ DirectStepI<TDerived>::check(StrandContext const& ctx) const
|
||||
// The following checks apply for both payments and offer crossing.
|
||||
if (!src_ || !dst_)
|
||||
{
|
||||
JLOG(j_.debug()) << "DirectStepI: specified bad account.";
|
||||
return temBAD_PATH;
|
||||
return {temBAD_PATH, "DirectStepI: specified bad account."};
|
||||
}
|
||||
|
||||
if (src_ == dst_)
|
||||
{
|
||||
JLOG(j_.debug()) << "DirectStepI: same src and dst.";
|
||||
return temBAD_PATH;
|
||||
return {temBAD_PATH, "DirectStepI: same src and dst."};
|
||||
}
|
||||
|
||||
auto const sleSrc = ctx.view.read(keylet::account(src_));
|
||||
|
||||
@@ -823,14 +823,12 @@ MPTEndpointStep<TDerived>::check(StrandContext const& ctx) const
|
||||
// The following checks apply for both payments and offer crossing.
|
||||
if (!src_ || !dst_)
|
||||
{
|
||||
JLOG(j_.debug()) << "MPTEndpointStep: specified bad account.";
|
||||
return temBAD_PATH;
|
||||
return {temBAD_PATH, "MPTEndpointStep: specified bad account."};
|
||||
}
|
||||
|
||||
if (src_ == dst_)
|
||||
{
|
||||
JLOG(j_.debug()) << "MPTEndpointStep: same src and dst.";
|
||||
return temBAD_PATH;
|
||||
return {temBAD_PATH, "MPTEndpointStep: same src and dst."};
|
||||
}
|
||||
|
||||
auto const sleSrc = ctx.view.read(keylet::account(src_));
|
||||
@@ -885,15 +883,13 @@ MPTEndpointStep<TDerived>::check(StrandContext const& ctx) const
|
||||
// MPT can only be an endpoint
|
||||
if (!ctx.isLast && !ctx.isFirst)
|
||||
{
|
||||
JLOG(j_.warn()) << "MPTEndpointStep: MPT can only be an endpoint";
|
||||
return temBAD_PATH;
|
||||
return {temBAD_PATH, "MPTEndpointStep: MPT can only be an endpoint"};
|
||||
}
|
||||
|
||||
auto const& issuer = mptIssue_.getIssuer();
|
||||
if ((src_ != issuer && dst_ != issuer) || (src_ == issuer && dst_ == issuer))
|
||||
{
|
||||
JLOG(j_.warn()) << "MPTEndpointStep: invalid src/dst";
|
||||
return temBAD_PATH;
|
||||
return {temBAD_PATH, "MPTEndpointStep: invalid src/dst"};
|
||||
}
|
||||
|
||||
return static_cast<TDerived const*>(this)->check(ctx, sleSrc);
|
||||
|
||||
@@ -338,8 +338,7 @@ XRPEndpointStep<TDerived>::check(StrandContext const& ctx) const
|
||||
{
|
||||
if (!acc_)
|
||||
{
|
||||
JLOG(j_.debug()) << "XRPEndpointStep: specified bad account.";
|
||||
return temBAD_PATH;
|
||||
return {temBAD_PATH, "XRPEndpointStep: specified bad account."};
|
||||
}
|
||||
|
||||
auto sleAcc = ctx.view.read(keylet::account(acc_));
|
||||
|
||||
@@ -63,15 +63,13 @@ NotTEC
|
||||
AccountSet::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
auto& tx = ctx.tx;
|
||||
auto& j = ctx.j;
|
||||
|
||||
std::uint32_t const uSetFlag = tx.getFieldU32(sfSetFlag);
|
||||
std::uint32_t const uClearFlag = tx.getFieldU32(sfClearFlag);
|
||||
|
||||
if ((uSetFlag != 0) && (uSetFlag == uClearFlag))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Set and clear same flag.";
|
||||
return temINVALID_FLAG;
|
||||
return {temINVALID_FLAG, "Malformed transaction: Set and clear same flag."};
|
||||
}
|
||||
|
||||
//
|
||||
@@ -82,8 +80,7 @@ AccountSet::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (bSetRequireAuth && bClearRequireAuth)
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Contradictory flags set.";
|
||||
return temINVALID_FLAG;
|
||||
return {temINVALID_FLAG, "Malformed transaction: Contradictory flags set."};
|
||||
}
|
||||
|
||||
//
|
||||
@@ -94,8 +91,7 @@ AccountSet::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (bSetRequireDest && bClearRequireDest)
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Contradictory flags set.";
|
||||
return temINVALID_FLAG;
|
||||
return {temINVALID_FLAG, "Malformed transaction: Contradictory flags set."};
|
||||
}
|
||||
|
||||
//
|
||||
@@ -106,8 +102,7 @@ AccountSet::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (bSetDisallowXRP && bClearDisallowXRP)
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Contradictory flags set.";
|
||||
return temINVALID_FLAG;
|
||||
return {temINVALID_FLAG, "Malformed transaction: Contradictory flags set."};
|
||||
}
|
||||
|
||||
// TransferRate
|
||||
@@ -117,14 +112,12 @@ AccountSet::preflight(PreflightContext const& ctx)
|
||||
|
||||
if ((uRate != 0u) && (uRate < QUALITY_ONE))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Transfer rate too small.";
|
||||
return temBAD_TRANSFER_RATE;
|
||||
return {temBAD_TRANSFER_RATE, "Malformed transaction: Transfer rate too small."};
|
||||
}
|
||||
|
||||
if (uRate > 2 * QUALITY_ONE)
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Transfer rate too large.";
|
||||
return temBAD_TRANSFER_RATE;
|
||||
return {temBAD_TRANSFER_RATE, "Malformed transaction: Transfer rate too large."};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,8 +128,7 @@ AccountSet::preflight(PreflightContext const& ctx)
|
||||
if ((uTickSize != 0u) &&
|
||||
((uTickSize < Quality::kMinTickSize) || (uTickSize > Quality::kMaxTickSize)))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Bad tick size.";
|
||||
return temBAD_TICK_SIZE;
|
||||
return {temBAD_TICK_SIZE, "Malformed transaction: Bad tick size."};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,15 +136,13 @@ AccountSet::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (!mk->empty() && !publicKeyType({mk->data(), mk->size()}))
|
||||
{
|
||||
JLOG(j.trace()) << "Invalid message key specified.";
|
||||
return telBAD_PUBLIC_KEY;
|
||||
return {telBAD_PUBLIC_KEY, "Invalid message key specified."};
|
||||
}
|
||||
}
|
||||
|
||||
if (auto const domain = tx[~sfDomain]; domain && domain->size() > kMaxDomainLength)
|
||||
{
|
||||
JLOG(j.trace()) << "domain too long";
|
||||
return telBAD_DOMAIN;
|
||||
return {telBAD_DOMAIN, "domain too long"};
|
||||
}
|
||||
|
||||
// Configure authorized minting account:
|
||||
|
||||
@@ -89,8 +89,7 @@ SignerListSet::preflight(PreflightContext const& ctx)
|
||||
if (std::get<3>(result) == Operation::Unknown)
|
||||
{
|
||||
// Neither a set nor a destroy. Malformed.
|
||||
JLOG(ctx.j.trace()) << "Malformed transaction: Invalid signer set list format.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "Malformed transaction: Invalid signer set list format."};
|
||||
}
|
||||
|
||||
if (std::get<3>(result) == Operation::Set)
|
||||
@@ -248,8 +247,7 @@ SignerListSet::validateQuorumAndSignerEntries(
|
||||
std::size_t const signerCount = signers.size();
|
||||
if (signerCount < STTx::kMinMultiSigners || signerCount > STTx::kMaxMultiSigners)
|
||||
{
|
||||
JLOG(j.trace()) << "Too many or too few signers in signer list.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "Too many or too few signers in signer list."};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,8 +258,7 @@ SignerListSet::validateQuorumAndSignerEntries(
|
||||
"signers");
|
||||
if (std::ranges::adjacent_find(signers) != signers.end())
|
||||
{
|
||||
JLOG(j.trace()) << "Duplicate signers in signer list";
|
||||
return temBAD_SIGNER;
|
||||
return {temBAD_SIGNER, "Duplicate signers in signer list"};
|
||||
}
|
||||
|
||||
// Make sure no signers reference this account. Also make sure the
|
||||
@@ -272,24 +269,21 @@ SignerListSet::validateQuorumAndSignerEntries(
|
||||
std::uint32_t const weight = signer.weight;
|
||||
if (weight <= 0)
|
||||
{
|
||||
JLOG(j.trace()) << "Every signer must have a positive weight.";
|
||||
return temBAD_WEIGHT;
|
||||
return {temBAD_WEIGHT, "Every signer must have a positive weight."};
|
||||
}
|
||||
|
||||
allSignersWeight += signer.weight;
|
||||
|
||||
if (signer.account == account)
|
||||
{
|
||||
JLOG(j.trace()) << "A signer may not self reference account.";
|
||||
return temBAD_SIGNER;
|
||||
return {temBAD_SIGNER, "A signer may not self reference account."};
|
||||
}
|
||||
// Don't verify that the signer accounts exist. Non-existent accounts
|
||||
// may be phantom accounts (which are permitted).
|
||||
}
|
||||
if ((quorum <= 0) || (allSignersWeight < quorum))
|
||||
{
|
||||
JLOG(j.trace()) << "Quorum is unreachable";
|
||||
return temBAD_QUORUM;
|
||||
return {temBAD_QUORUM, "Quorum is unreachable"};
|
||||
}
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -61,9 +61,9 @@ CheckCash::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (static_cast<bool>(optAmount) == static_cast<bool>(optDeliverMin))
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Malformed transaction: "
|
||||
"does not specify exactly one of Amount and DeliverMin.";
|
||||
return temMALFORMED;
|
||||
return {
|
||||
temMALFORMED,
|
||||
"Malformed transaction: does not specify exactly one of Amount and DeliverMin."};
|
||||
}
|
||||
|
||||
// Make sure the amount is valid.
|
||||
@@ -76,8 +76,7 @@ CheckCash::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (badAsset() == value.asset())
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Malformed transaction: Bad currency.";
|
||||
return temBAD_CURRENCY;
|
||||
return {temBAD_CURRENCY, "Malformed transaction: Bad currency."};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -145,14 +144,12 @@ CheckCash::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
if (!equalTokens(value.asset(), sendMax.asset()))
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Check cash does not match check currency.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "Check cash does not match check currency."};
|
||||
}
|
||||
AccountID const issuerId{value.getIssuer()};
|
||||
if (issuerId != sendMax.getIssuer())
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Check cash does not match check issuer.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "Check cash does not match check issuer."};
|
||||
}
|
||||
if (value > sendMax)
|
||||
{
|
||||
|
||||
@@ -43,8 +43,7 @@ CheckCreate::preflight(PreflightContext const& ctx)
|
||||
if (ctx.tx[sfAccount] == ctx.tx[sfDestination])
|
||||
{
|
||||
// They wrote a check to themselves.
|
||||
JLOG(ctx.j.warn()) << "Malformed transaction: Check to self.";
|
||||
return temREDUNDANT;
|
||||
return {temREDUNDANT, "Malformed transaction: Check to self."};
|
||||
}
|
||||
|
||||
{
|
||||
@@ -58,8 +57,7 @@ CheckCreate::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (badAsset() == sendMax.asset())
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Malformed transaction: Bad currency.";
|
||||
return temBAD_CURRENCY;
|
||||
return {temBAD_CURRENCY, "Malformed transaction: Bad currency."};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,8 +65,7 @@ CheckCreate::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (*optExpiry == 0)
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Malformed transaction: bad expiration";
|
||||
return temBAD_EXPIRATION;
|
||||
return {temBAD_EXPIRATION, "Malformed transaction: bad expiration"};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,15 +36,13 @@ CredentialAccept::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (!ctx.tx[sfIssuer])
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Malformed transaction: Issuer field zeroed.";
|
||||
return temINVALID_ACCOUNT_ID;
|
||||
return {temINVALID_ACCOUNT_ID, "Malformed transaction: Issuer field zeroed."};
|
||||
}
|
||||
|
||||
auto const credType = ctx.tx[sfCredentialType];
|
||||
if (credType.empty() || (credType.size() > kMaxCredentialTypeLength))
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Malformed transaction: invalid size of CredentialType.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "Malformed transaction: invalid size of CredentialType."};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -53,26 +53,22 @@ NotTEC
|
||||
CredentialCreate::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
auto const& tx = ctx.tx;
|
||||
auto& j = ctx.j;
|
||||
|
||||
if (!tx[sfSubject])
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Invalid Subject";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "Malformed transaction: Invalid Subject"};
|
||||
}
|
||||
|
||||
auto const uri = tx[~sfURI];
|
||||
if (uri && (uri->empty() || (uri->size() > kMaxCredentialUriLength)))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: invalid size of URI.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "Malformed transaction: invalid size of URI."};
|
||||
}
|
||||
|
||||
auto const credType = tx[sfCredentialType];
|
||||
if (credType.empty() || (credType.size() > kMaxCredentialTypeLength))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: invalid size of CredentialType.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "Malformed transaction: invalid size of CredentialType."};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -36,24 +36,19 @@ CredentialDelete::preflight(PreflightContext const& ctx)
|
||||
if (!subject && !issuer)
|
||||
{
|
||||
// Neither field is present, the transaction is malformed.
|
||||
JLOG(ctx.j.trace()) << "Malformed transaction: "
|
||||
"No Subject or Issuer fields.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "Malformed transaction: No Subject or Issuer fields."};
|
||||
}
|
||||
|
||||
// Make sure that the passed account is valid.
|
||||
if ((subject && subject->isZero()) || (issuer && issuer->isZero()))
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Malformed transaction: Subject or Issuer "
|
||||
"field zeroed.";
|
||||
return temINVALID_ACCOUNT_ID;
|
||||
return {temINVALID_ACCOUNT_ID, "Malformed transaction: Subject or Issuer field zeroed."};
|
||||
}
|
||||
|
||||
auto const credType = ctx.tx[sfCredentialType];
|
||||
if (credType.empty() || (credType.size() > kMaxCredentialTypeLength))
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Malformed transaction: invalid size of CredentialType.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "Malformed transaction: invalid size of CredentialType."};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -78,8 +78,7 @@ AMMBid::preflight(PreflightContext const& ctx)
|
||||
auto const authAccounts = ctx.tx.getFieldArray(sfAuthAccounts);
|
||||
if (authAccounts.size() > kAuctionSlotMaxAuthAccounts)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Bid: Invalid number of AuthAccounts.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "AMM Bid: Invalid number of AuthAccounts."};
|
||||
}
|
||||
if (ctx.rules.enabled(fixAMMv1_3))
|
||||
{
|
||||
@@ -90,8 +89,7 @@ AMMBid::preflight(PreflightContext const& ctx)
|
||||
auto authAccount = obj[sfAccount];
|
||||
if (authAccount == account || unique.contains(authAccount))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Bid: Invalid auth.account.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "AMM Bid: Invalid auth.account."};
|
||||
}
|
||||
unique.insert(authAccount);
|
||||
}
|
||||
@@ -138,8 +136,7 @@ AMMBid::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
if (bidMin->asset() != lpTokens.asset())
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Bid: Invalid LPToken.";
|
||||
return temBAD_AMM_TOKENS;
|
||||
return {temBAD_AMM_TOKENS, "AMM Bid: Invalid LPToken."};
|
||||
}
|
||||
if (*bidMin > lpTokens || *bidMin >= lpTokensBalance)
|
||||
{
|
||||
@@ -152,8 +149,7 @@ AMMBid::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
if (bidMax->asset() != lpTokens.asset())
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Bid: Invalid LPToken.";
|
||||
return temBAD_AMM_TOKENS;
|
||||
return {temBAD_AMM_TOKENS, "AMM Bid: Invalid LPToken."};
|
||||
}
|
||||
if (*bidMax > lpTokens || *bidMax >= lpTokensBalance)
|
||||
{
|
||||
|
||||
@@ -59,8 +59,7 @@ AMMClawback::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (issuer == holder)
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "AMMClawback: holder cannot be the same as issuer.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "AMMClawback: holder cannot be the same as issuer."};
|
||||
}
|
||||
|
||||
std::optional<STAmount> const clawAmount = ctx.tx[~sfAmount];
|
||||
@@ -72,23 +71,20 @@ AMMClawback::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (ctx.tx.isFlag(tfClawTwoAssets) && asset.getIssuer() != asset2.getIssuer())
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "AMMClawback: tfClawTwoAssets can only be enabled when two "
|
||||
"assets in the AMM pool are both issued by the issuer";
|
||||
return temINVALID_FLAG;
|
||||
return {
|
||||
temINVALID_FLAG,
|
||||
"AMMClawback: tfClawTwoAssets can only be enabled when two assets in the AMM pool are "
|
||||
"both issued by the issuer"};
|
||||
}
|
||||
|
||||
if (asset.getIssuer() != issuer)
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "AMMClawback: Asset's account does not "
|
||||
"match Account field.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "AMMClawback: Asset's account does not match Account field."};
|
||||
}
|
||||
|
||||
if (clawAmount && clawAmount->asset() != asset)
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "AMMClawback: Amount's asset subfield "
|
||||
"does not match Asset field";
|
||||
return temBAD_AMOUNT;
|
||||
return {temBAD_AMOUNT, "AMMClawback: Amount's asset subfield does not match Asset field"};
|
||||
}
|
||||
|
||||
if (clawAmount && *clawAmount <= beast::kZero)
|
||||
|
||||
@@ -59,8 +59,7 @@ AMMCreate::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (amount.asset() == amount2.asset())
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Instance: tokens can not have the same asset.";
|
||||
return temBAD_AMM_TOKENS;
|
||||
return {temBAD_AMM_TOKENS, "AMM Instance: tokens can not have the same asset."};
|
||||
}
|
||||
|
||||
if (auto const err = invalidAMMAmount(amount))
|
||||
@@ -77,8 +76,7 @@ AMMCreate::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (ctx.tx[sfTradingFee] > kTradingFeeThreshold)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Instance: invalid trading fee.";
|
||||
return temBAD_FEE;
|
||||
return {temBAD_FEE, "AMM Instance: invalid trading fee."};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -70,8 +70,7 @@ AMMDeposit::preflight(PreflightContext const& ctx)
|
||||
// tfLimitLPToken: Amount and EPrice
|
||||
if (std::popcount(flags & tfDepositSubTx) != 1)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Deposit: invalid flags.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "AMM Deposit: invalid flags."};
|
||||
}
|
||||
if (ctx.tx.isFlag(tfLPToken))
|
||||
{
|
||||
@@ -124,8 +123,7 @@ AMMDeposit::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (lpTokens && *lpTokens <= beast::kZero)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Deposit: invalid LPTokens";
|
||||
return temBAD_AMM_TOKENS;
|
||||
return {temBAD_AMM_TOKENS, "AMM Deposit: invalid LPTokens"};
|
||||
}
|
||||
|
||||
if (amount)
|
||||
@@ -166,8 +164,7 @@ AMMDeposit::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (tradingFee > kTradingFeeThreshold)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Deposit: invalid trading fee.";
|
||||
return temBAD_FEE;
|
||||
return {temBAD_FEE, "AMM Deposit: invalid trading fee."};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -378,8 +375,7 @@ AMMDeposit::preclaim(PreclaimContext const& ctx)
|
||||
if (auto const lpTokens = ctx.tx[~sfLPTokenOut];
|
||||
lpTokens && lpTokens->asset() != lptAMMBalance.asset())
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Deposit: invalid LPTokens.";
|
||||
return temBAD_AMM_TOKENS;
|
||||
return {temBAD_AMM_TOKENS, "AMM Deposit: invalid LPTokens."};
|
||||
}
|
||||
|
||||
// Check the reserve for LPToken trustline if not LP.
|
||||
|
||||
@@ -48,8 +48,7 @@ AMMVote::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (ctx.tx[sfTradingFee] > kTradingFeeThreshold)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Vote: invalid trading fee.";
|
||||
return temBAD_FEE;
|
||||
return {temBAD_FEE, "AMM Vote: invalid trading fee."};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -78,8 +78,7 @@ AMMWithdraw::preflight(PreflightContext const& ctx)
|
||||
// Amount and EPrice
|
||||
if (std::popcount(flags & tfWithdrawSubTx) != 1)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Withdraw: invalid flags.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "AMM Withdraw: invalid flags."};
|
||||
}
|
||||
if (ctx.tx.isFlag(tfLPToken))
|
||||
{
|
||||
@@ -129,8 +128,7 @@ AMMWithdraw::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (lpTokens && *lpTokens <= beast::kZero)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Withdraw: invalid tokens.";
|
||||
return temBAD_AMM_TOKENS;
|
||||
return {temBAD_AMM_TOKENS, "AMM Withdraw: invalid tokens."};
|
||||
}
|
||||
|
||||
if (amount)
|
||||
@@ -283,8 +281,7 @@ AMMWithdraw::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
if (lpTokensWithdraw && lpTokensWithdraw->asset() != lpTokens.asset())
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Withdraw: invalid LPTokens.";
|
||||
return temBAD_AMM_TOKENS;
|
||||
return {temBAD_AMM_TOKENS, "AMM Withdraw: invalid LPTokens."};
|
||||
}
|
||||
|
||||
if (lpTokensWithdraw && *lpTokensWithdraw > lpTokens)
|
||||
@@ -294,8 +291,7 @@ AMMWithdraw::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
if (auto const ePrice = ctx.tx[~sfEPrice]; ePrice && ePrice->asset() != lpTokens.asset())
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Withdraw: invalid EPrice.";
|
||||
return temBAD_AMM_TOKENS;
|
||||
return {temBAD_AMM_TOKENS, "AMM Withdraw: invalid EPrice."};
|
||||
}
|
||||
|
||||
if ((ctx.tx.getFlags() & (tfLPToken | tfWithdrawAll)) != 0u)
|
||||
|
||||
@@ -17,8 +17,7 @@ OfferCancel::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.tx[sfOfferSequence] == 0u)
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "OfferCancel::preflight: missing sequence";
|
||||
return temBAD_SEQUENCE;
|
||||
return {temBAD_SEQUENCE, "OfferCancel::preflight: missing sequence"};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -90,7 +90,6 @@ NotTEC
|
||||
OfferCreate::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
auto& tx = ctx.tx;
|
||||
auto& j = ctx.j;
|
||||
|
||||
if (tx.isFlag(tfHybrid) && !tx.isFieldPresent(sfDomainID))
|
||||
return temINVALID_FLAG;
|
||||
@@ -106,22 +105,19 @@ OfferCreate::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (bImmediateOrCancel && bFillOrKill)
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed transaction: both IoC and FoK set.";
|
||||
return temINVALID_FLAG;
|
||||
return {temINVALID_FLAG, "Malformed transaction: both IoC and FoK set."};
|
||||
}
|
||||
|
||||
bool const bHaveExpiration(tx.isFieldPresent(sfExpiration));
|
||||
|
||||
if (bHaveExpiration && (tx.getFieldU32(sfExpiration) == 0))
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed offer: bad expiration";
|
||||
return temBAD_EXPIRATION;
|
||||
return {temBAD_EXPIRATION, "Malformed offer: bad expiration"};
|
||||
}
|
||||
|
||||
if (auto const cancelSequence = tx[~sfOfferSequence]; cancelSequence && *cancelSequence == 0)
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed offer: bad cancel sequence";
|
||||
return temBAD_SEQUENCE;
|
||||
return {temBAD_SEQUENCE, "Malformed offer: bad cancel sequence"};
|
||||
}
|
||||
|
||||
STAmount const saTakerPays = tx[sfTakerPays];
|
||||
@@ -132,13 +128,11 @@ OfferCreate::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (saTakerPays.native() && saTakerGets.native())
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed offer: redundant (XRP for XRP)";
|
||||
return temBAD_OFFER;
|
||||
return {temBAD_OFFER, "Malformed offer: redundant (XRP for XRP)"};
|
||||
}
|
||||
if (saTakerPays <= beast::kZero || saTakerGets <= beast::kZero)
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed offer: bad amount";
|
||||
return temBAD_OFFER;
|
||||
return {temBAD_OFFER, "Malformed offer: bad amount"};
|
||||
}
|
||||
|
||||
auto const& uPaysIssuerID = saTakerPays.getIssuer();
|
||||
@@ -149,20 +143,17 @@ OfferCreate::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (uPaysAsset == uGetsAsset)
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed offer: redundant (IOU for IOU)";
|
||||
return temREDUNDANT;
|
||||
return {temREDUNDANT, "Malformed offer: redundant (IOU for IOU)"};
|
||||
}
|
||||
// We don't allow a non-native currency to use the currency code XRP.
|
||||
if (badAsset() == uPaysAsset || badAsset() == uGetsAsset)
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed offer: bad currency";
|
||||
return temBAD_CURRENCY;
|
||||
return {temBAD_CURRENCY, "Malformed offer: bad currency"};
|
||||
}
|
||||
|
||||
if (saTakerPays.native() != !uPaysIssuerID || saTakerGets.native() != !uGetsIssuerID)
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed offer: bad issuer";
|
||||
return temBAD_ISSUER;
|
||||
return {temBAD_ISSUER, "Malformed offer: bad issuer"};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -52,9 +52,10 @@ LoanManage::preflight(PreflightContext const& ctx)
|
||||
auto const flags = *flagField & tfUniversalMask;
|
||||
if ((flags & (flags - 1)) != 0)
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "LoanManage: Only one of tfLoanDefault, tfLoanImpair, or "
|
||||
"tfLoanUnimpair can be set.";
|
||||
return temINVALID_FLAG;
|
||||
return {
|
||||
temINVALID_FLAG,
|
||||
"LoanManage: Only one of tfLoanDefault, tfLoanImpair, or tfLoanUnimpair can be "
|
||||
"set."};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,8 +59,7 @@ LoanSet::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (tx.isFieldPresent(sfSponsorFlags) && isReserveSponsored(tx))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "LoanSet: reserve sponsorship is not allowed.";
|
||||
return temINVALID_FLAG;
|
||||
return {temINVALID_FLAG, "LoanSet: reserve sponsorship is not allowed."};
|
||||
}
|
||||
|
||||
// Special case for Batch inner transactions
|
||||
@@ -81,8 +80,7 @@ LoanSet::preflight(PreflightContext const& ctx)
|
||||
}();
|
||||
if (!tx.isFlag(tfInnerBatchTxn) && !counterPartySig)
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "LoanSet transaction must have a CounterpartySignature.";
|
||||
return temBAD_SIGNER;
|
||||
return {temBAD_SIGNER, "LoanSet transaction must have a CounterpartySignature."};
|
||||
}
|
||||
|
||||
if (counterPartySig)
|
||||
|
||||
@@ -55,9 +55,9 @@ DepositPreauth::preflight(PreflightContext const& ctx)
|
||||
if (authPresent + authCredPresent != 1)
|
||||
{
|
||||
// There can only be 1 field out of 4 or the transaction is malformed.
|
||||
JLOG(ctx.j.trace()) << "Malformed transaction: "
|
||||
"Invalid Authorize and Unauthorize field combination.";
|
||||
return temMALFORMED;
|
||||
return {
|
||||
temMALFORMED,
|
||||
"Malformed transaction: Invalid Authorize and Unauthorize field combination."};
|
||||
}
|
||||
|
||||
if (authPresent != 0)
|
||||
@@ -67,16 +67,17 @@ DepositPreauth::preflight(PreflightContext const& ctx)
|
||||
AccountID const& target(optAuth ? *optAuth : *optUnauth);
|
||||
if (!target)
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Malformed transaction: Authorized or Unauthorized "
|
||||
"field zeroed.";
|
||||
return temINVALID_ACCOUNT_ID;
|
||||
return {
|
||||
temINVALID_ACCOUNT_ID,
|
||||
"Malformed transaction: Authorized or Unauthorized field zeroed."};
|
||||
}
|
||||
|
||||
// An account may not preauthorize itself.
|
||||
if (optAuth && (target == ctx.tx[sfAccount]))
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Malformed transaction: Attempting to DepositPreauth self.";
|
||||
return temCANNOT_PREAUTH_SELF;
|
||||
return {
|
||||
temCANNOT_PREAUTH_SELF,
|
||||
"Malformed transaction: Attempting to DepositPreauth self."};
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -179,9 +179,7 @@ Payment::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (!dstAccountID)
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: "
|
||||
<< "Payment destination account not specified.";
|
||||
return temDST_NEEDED;
|
||||
return {temDST_NEEDED, "Malformed transaction: Payment destination account not specified."};
|
||||
}
|
||||
if (hasMax && maxSourceAmount <= beast::kZero)
|
||||
{
|
||||
@@ -201,8 +199,7 @@ Payment::preflight(PreflightContext const& ctx)
|
||||
};
|
||||
if (bad(srcAsset) || bad(dstAsset))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Bad currency.";
|
||||
return temBAD_CURRENCY;
|
||||
return {temBAD_CURRENCY, "Malformed transaction: Bad currency."};
|
||||
}
|
||||
if (account == dstAccountID && equalTokens(srcAsset, dstAsset) && !hasPaths)
|
||||
{
|
||||
@@ -216,37 +213,35 @@ Payment::preflight(PreflightContext const& ctx)
|
||||
if (xrpDirect && hasMax)
|
||||
{
|
||||
// Consistent but redundant transaction.
|
||||
JLOG(j.trace()) << "Malformed transaction: "
|
||||
<< "SendMax specified for XRP to XRP.";
|
||||
return temBAD_SEND_XRP_MAX;
|
||||
return {temBAD_SEND_XRP_MAX, "Malformed transaction: SendMax specified for XRP to XRP."};
|
||||
}
|
||||
if ((xrpDirect || (!mpTokensV2 && isDstMPT)) && hasPaths)
|
||||
{
|
||||
// XRP is sent without paths.
|
||||
JLOG(j.trace()) << "Malformed transaction: "
|
||||
<< "Paths specified for XRP to XRP or MPT to MPT.";
|
||||
return temBAD_SEND_XRP_PATHS;
|
||||
return {
|
||||
temBAD_SEND_XRP_PATHS,
|
||||
"Malformed transaction: Paths specified for XRP to XRP or MPT to MPT."};
|
||||
}
|
||||
if (xrpDirect && partialPaymentAllowed)
|
||||
{
|
||||
// Consistent but redundant transaction.
|
||||
JLOG(j.trace()) << "Malformed transaction: "
|
||||
<< "Partial payment specified for XRP to XRP.";
|
||||
return temBAD_SEND_XRP_PARTIAL;
|
||||
return {
|
||||
temBAD_SEND_XRP_PARTIAL,
|
||||
"Malformed transaction: Partial payment specified for XRP to XRP."};
|
||||
}
|
||||
if ((xrpDirect || (!mpTokensV2 && isDstMPT)) && limitQuality)
|
||||
{
|
||||
// Consistent but redundant transaction.
|
||||
JLOG(j.trace()) << "Malformed transaction: "
|
||||
<< "Limit quality specified for XRP to XRP or MPT to MPT.";
|
||||
return temBAD_SEND_XRP_LIMIT;
|
||||
return {
|
||||
temBAD_SEND_XRP_LIMIT,
|
||||
"Malformed transaction: Limit quality specified for XRP to XRP or MPT to MPT."};
|
||||
}
|
||||
if ((xrpDirect || (!mpTokensV2 && isDstMPT)) && !defaultPathsAllowed)
|
||||
{
|
||||
// Consistent but redundant transaction.
|
||||
JLOG(j.trace()) << "Malformed transaction: "
|
||||
<< "No ripple direct specified for XRP to XRP or MPT to MPT.";
|
||||
return temBAD_SEND_XRP_NO_DIRECT;
|
||||
return {
|
||||
temBAD_SEND_XRP_NO_DIRECT,
|
||||
"Malformed transaction: No ripple direct specified for XRP to XRP or MPT to MPT."};
|
||||
}
|
||||
|
||||
if (deliverMin)
|
||||
@@ -387,9 +382,9 @@ Payment::preclaim(PreclaimContext const& ctx)
|
||||
if (ctx.view.open())
|
||||
{
|
||||
// Make retry work smaller, by rejecting this.
|
||||
JLOG(ctx.j.trace()) << "Delay transaction: Partial payment not "
|
||||
"allowed to create account.";
|
||||
return telNO_DST_PARTIAL;
|
||||
return {
|
||||
telNO_DST_PARTIAL,
|
||||
"Delay transaction: Partial payment not allowed to create account."};
|
||||
}
|
||||
// Inner batch txns are claimed on a closed view, where a tel is
|
||||
// invalid, so use the tef.
|
||||
|
||||
@@ -102,8 +102,7 @@ SponsorshipTransfer::preflight(PreflightContext const& ctx)
|
||||
tfSponsorshipCreate | tfSponsorshipReassign | tfSponsorshipEnd;
|
||||
if (std::popcount(ctx.tx.getFlags() & transferFlags) != 1)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "preflight: Only one SponsorshipTransfer flag can be set per tx.";
|
||||
return temINVALID_FLAG;
|
||||
return {temINVALID_FLAG, "preflight: Only one SponsorshipTransfer flag can be set per tx."};
|
||||
}
|
||||
|
||||
if (ctx.tx.isFlag(tfSponsorshipCreate))
|
||||
@@ -112,22 +111,20 @@ SponsorshipTransfer::preflight(PreflightContext const& ctx)
|
||||
// to a reserve sponsor identified by sfSponsor + spfSponsorReserve.
|
||||
if (!ctx.tx.isFieldPresent(sfSponsor))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "preflight: sfSponsor must be present when creating sponsorship";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "preflight: sfSponsor must be present when creating sponsorship"};
|
||||
}
|
||||
|
||||
if (!isReserveSponsored(ctx.tx))
|
||||
{
|
||||
JLOG(ctx.j.debug())
|
||||
<< "preflight: spfSponsorReserve must be set when creating sponsorship";
|
||||
return temINVALID_FLAG;
|
||||
return {
|
||||
temINVALID_FLAG,
|
||||
"preflight: spfSponsorReserve must be set when creating sponsorship"};
|
||||
}
|
||||
|
||||
if (ctx.tx.isFieldPresent(sfSponsee))
|
||||
{
|
||||
JLOG(ctx.j.debug())
|
||||
<< "preflight: sfSponsee must not be present when creating sponsorship";
|
||||
return temMALFORMED;
|
||||
return {
|
||||
temMALFORMED, "preflight: sfSponsee must not be present when creating sponsorship"};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,22 +135,21 @@ SponsorshipTransfer::preflight(PreflightContext const& ctx)
|
||||
// spfSponsorReserve.
|
||||
if (!ctx.tx.isFieldPresent(sfSponsor))
|
||||
{
|
||||
JLOG(ctx.j.debug())
|
||||
<< "preflight: sfSponsor must be present when reassigning sponsorship";
|
||||
return temMALFORMED;
|
||||
return {
|
||||
temMALFORMED, "preflight: sfSponsor must be present when reassigning sponsorship"};
|
||||
}
|
||||
|
||||
if (!isReserveSponsored(ctx.tx))
|
||||
{
|
||||
JLOG(ctx.j.debug())
|
||||
<< "preflight: spfSponsorReserve must be set when reassigning sponsorship";
|
||||
return temINVALID_FLAG;
|
||||
return {
|
||||
temINVALID_FLAG,
|
||||
"preflight: spfSponsorReserve must be set when reassigning sponsorship"};
|
||||
}
|
||||
if (ctx.tx.isFieldPresent(sfSponsee))
|
||||
{
|
||||
JLOG(ctx.j.debug())
|
||||
<< "preflight: sfSponsee must not be present when reassigning sponsorship";
|
||||
return temMALFORMED;
|
||||
return {
|
||||
temMALFORMED,
|
||||
"preflight: sfSponsee must not be present when reassigning sponsorship"};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,9 +159,8 @@ SponsorshipTransfer::preflight(PreflightContext const& ctx)
|
||||
// The target is sfSponsee when provided; otherwise it is sfAccount.
|
||||
if (ctx.tx.isFieldPresent(sfSponsor))
|
||||
{
|
||||
JLOG(ctx.j.debug())
|
||||
<< "preflight: sfSponsor must not be present when ending sponsorship";
|
||||
return temMALFORMED;
|
||||
return {
|
||||
temMALFORMED, "preflight: sfSponsor must not be present when ending sponsorship"};
|
||||
}
|
||||
|
||||
// sfSponsorFlags should not be present if it is ending sponsorship.
|
||||
@@ -185,8 +180,7 @@ SponsorshipTransfer::preflight(PreflightContext const& ctx)
|
||||
if (ctx.tx.isFieldPresent(sfSponsee) &&
|
||||
ctx.tx.getAccountID(sfSponsee) == ctx.tx.getAccountID(sfAccount))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "preflight: sfSponsee should not be the same as the account";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "preflight: sfSponsee should not be the same as the account"};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,8 +195,7 @@ SponsorshipTransfer::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (isAccountReserveSponsorship && !ctx.tx.isFieldPresent(sfSponsorSignature))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "preflight: account sponsorship requires sfSponsorSignature";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "preflight: account sponsorship requires sfSponsorSignature"};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -44,29 +44,25 @@ Transactor::invokePreflight<Change>(PreflightContext const& ctx)
|
||||
auto account = ctx.tx.getAccountID(sfAccount);
|
||||
if (account != beast::kZero)
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Change: Bad source id";
|
||||
return temBAD_SRC_ACCOUNT;
|
||||
return {temBAD_SRC_ACCOUNT, "Change: Bad source id"};
|
||||
}
|
||||
|
||||
// No point in going any further if the transaction fee is malformed.
|
||||
auto const fee = ctx.tx.getFieldAmount(sfFee);
|
||||
if (!fee.native() || fee != beast::kZero)
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Change: invalid fee";
|
||||
return temBAD_FEE;
|
||||
return {temBAD_FEE, "Change: invalid fee"};
|
||||
}
|
||||
|
||||
if (!ctx.tx.getSigningPubKey().empty() || !ctx.tx.getSignature().empty() ||
|
||||
ctx.tx.isFieldPresent(sfSigners))
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Change: Bad signature";
|
||||
return temBAD_SIGNATURE;
|
||||
return {temBAD_SIGNATURE, "Change: Bad signature"};
|
||||
}
|
||||
|
||||
if (ctx.tx.getFieldU32(sfSequence) != 0 || ctx.tx.isFieldPresent(sfPreviousTxnID))
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Change: Bad sequence";
|
||||
return temBAD_SEQUENCE;
|
||||
return {temBAD_SEQUENCE, "Change: Bad sequence"};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -79,8 +75,7 @@ Change::preclaim(PreclaimContext const& ctx)
|
||||
// this block can be moved to preflight.
|
||||
if (ctx.view.open())
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Change transaction against open ledger";
|
||||
return temINVALID;
|
||||
return {temINVALID, "Change transaction against open ledger"};
|
||||
}
|
||||
|
||||
switch (ctx.tx.getTxnType())
|
||||
|
||||
@@ -100,14 +100,12 @@ TrustSet::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (badCurrency() == saLimitAmount.get<Issue>().currency)
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: specifies XRP as IOU";
|
||||
return temBAD_CURRENCY;
|
||||
return {temBAD_CURRENCY, "Malformed transaction: specifies XRP as IOU"};
|
||||
}
|
||||
|
||||
if (saLimitAmount < beast::kZero)
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Negative credit limit.";
|
||||
return temBAD_LIMIT;
|
||||
return {temBAD_LIMIT, "Malformed transaction: Negative credit limit."};
|
||||
}
|
||||
|
||||
// Check if destination makes sense.
|
||||
@@ -115,8 +113,7 @@ TrustSet::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (!issuer || issuer == noAccount())
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: no destination account.";
|
||||
return temDST_NEEDED;
|
||||
return {temDST_NEEDED, "Malformed transaction: no destination account."};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -36,8 +36,7 @@ VaultClawback::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.tx[sfVaultID] == beast::kZero)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "VaultClawback: zero/empty vault ID.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "VaultClawback: zero/empty vault ID."};
|
||||
}
|
||||
|
||||
auto const amount = ctx.tx[~sfAmount];
|
||||
@@ -50,8 +49,7 @@ VaultClawback::preflight(PreflightContext const& ctx)
|
||||
}
|
||||
if (isXRP(amount->asset()))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "VaultClawback: cannot clawback XRP.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "VaultClawback: cannot clawback XRP."};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,7 @@ VaultDelete::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.tx[sfVaultID] == beast::kZero)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "VaultDelete: zero/empty vault ID.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "VaultDelete: zero/empty vault ID."};
|
||||
}
|
||||
|
||||
if (ctx.tx.isFieldPresent(sfMemoData) && !ctx.rules.enabled(featureLendingProtocolV1_1))
|
||||
|
||||
@@ -51,8 +51,7 @@ VaultDeposit::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.tx[sfVaultID] == beast::kZero)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "VaultDeposit: zero/empty vault ID.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "VaultDeposit: zero/empty vault ID."};
|
||||
}
|
||||
|
||||
if (ctx.tx[sfAmount] <= beast::kZero)
|
||||
|
||||
@@ -28,16 +28,14 @@ VaultSet::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.tx[sfVaultID] == beast::kZero)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "VaultSet: zero/empty vault ID.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "VaultSet: zero/empty vault ID."};
|
||||
}
|
||||
|
||||
if (auto const data = ctx.tx[~sfData])
|
||||
{
|
||||
if (data->empty() || data->length() > kMaxDataPayloadLength)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "VaultSet: invalid data payload size.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "VaultSet: invalid data payload size."};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,16 +43,14 @@ VaultSet::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (*assetMax < beast::kZero)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "VaultSet: invalid max assets.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "VaultSet: invalid max assets."};
|
||||
}
|
||||
}
|
||||
|
||||
if (!ctx.tx.isFieldPresent(sfDomainID) && !ctx.tx.isFieldPresent(sfAssetsMaximum) &&
|
||||
!ctx.tx.isFieldPresent(sfData))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "VaultSet: nothing is being updated.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "VaultSet: nothing is being updated."};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -44,8 +44,7 @@ VaultWithdraw::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.tx[sfVaultID] == beast::kZero)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "VaultWithdraw: zero/empty vault ID.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "VaultWithdraw: zero/empty vault ID."};
|
||||
}
|
||||
|
||||
if (ctx.tx[sfAmount] <= beast::kZero)
|
||||
|
||||
Reference in New Issue
Block a user