diff --git a/include/xrpl/protocol/TER.h b/include/xrpl/protocol/TER.h index 730d0212545..9513a0b9073 100644 --- a/include/xrpl/protocol/TER.h +++ b/include/xrpl/protocol/TER.h @@ -604,7 +604,7 @@ class CanCvtToNotTEC : public std::true_type { }; -using NotTEC = TERSubset; +using NotTECRaw = TERSubset; //------------------------------------------------------------------------------ @@ -639,48 +639,188 @@ class CanCvtToTER : public std::true_type { }; template <> -class CanCvtToTER : public std::true_type +class CanCvtToTER : public std::true_type { }; -// TER allows all of the subsets. -using TER = TERSubset; +// TERRaw allows all of the subsets (the plain numeric code, no reason string). +using TERRaw = TERSubset; + +//------------------------------------------------------------------------------ +// Forward declaration required by TER constructors below (TER.cpp provides the +// definition). The full public declaration is repeated after the struct. +std::string +transHuman(TERRaw code); + +//------------------------------------------------------------------------------ +// TERBase: shared implementation for TER and NotTEC. +// +// RawType – the underlying plain-integer subset (TERRaw or NotTECRaw). +// Trait – the trait class restricting which TE*codes values are accepted. +// +// When no reason is supplied the standard description from transHuman() is used +// automatically, so existing bare return statements compile unchanged: +// return tesSUCCESS; // in a TER-returning function +// return temMALFORMED; // in a NotTEC-returning preflight +// +// To attach a more specific reason at a particular return site write: +// return {tecNO_DST, "destination account has been deleted"}; +// return {temMALFORMED, "SignerEntries must be present for a non-zero quorum"}; +// +template class Trait> +struct TERBase +{ + RawType code; + std::string reason; + + // Default-construct to tesSUCCESS. + TERBase() : code(tesSUCCESS), reason(transHuman(TERRaw{code})) + { + } + + TERBase(TERBase const&) = default; + TERBase(TERBase&&) = default; + TERBase& + operator=(TERBase const&) = default; + TERBase& + operator=(TERBase&&) = default; + + // --- construction from RawType --- + + // Without explicit reason: populate from transHuman. + TERBase(RawType c) // NOLINT(google-explicit-constructor) + : code(c), reason(transHuman(TERRaw{code})) + { + } + + // With explicit reason. + TERBase(RawType c, std::string r) : code(c), reason(std::move(r)) + { + } + + // --- construction from any TE*codes enum satisfying Trait --- + + // Without explicit reason: populate from transHuman. + template + TERBase(T c) // NOLINT(google-explicit-constructor) + requires(Trait>>::value) + : code(c), reason(transHuman(TERRaw{code})) + { + } + + // With explicit reason. + template + TERBase(T c, std::string r) + requires(Trait>>::value) + : code(c), reason(std::move(r)) + { + } + + // --- cross-construction from a compatible TERBase specialization --- + // Carries the reason string across (e.g. NotTEC → TER preserves a + // custom reason set during preflight). + template class OtherTrait> + TERBase(TERBase const& other) // NOLINT(google-explicit-constructor) + requires(Trait::value) + : code(other.code), reason(other.reason) + { + } + + // Build from a raw integer (used by transCode). + static TERBase + fromInt(int from) + { + return TERBase(RawType::fromInt(from)); + } + + // Implicit conversion to RawType for backward compatibility. + operator RawType() const // NOLINT(google-explicit-constructor) + { + return code; + } + + // True when the code is anything other than tesSUCCESS. + explicit + operator bool() const + { + return static_cast(code); + } + + // Allow assignment to json::Objects without casting. + operator json::Value() const // NOLINT(google-explicit-constructor) + { + return json::Value{TERtoInt(code)}; + } + + friend std::ostream& + operator<<(std::ostream& os, TERBase const& rhs) + { + return os << TERtoInt(rhs.code); + } +}; + +// TER – full result code for apply-phase transactors (all TE*codes). +using TER = TERBase; + +// NotTEC – result code for preflight functions (tel*, tem*, tef*, ter*, tes*; +// excludes tec* to prevent fee charging without a valid signature). +using NotTEC = TERBase; + +// Expose underlying integers for the comparison operator templates. +inline TERUnderlyingType +TERtoInt(TER const& v) +{ + return TERtoInt(v.code); +} + +inline TERUnderlyingType +TERtoInt(NotTEC const& v) +{ + return TERtoInt(v.code); +} + +// Allow TERRaw (and therefore transHuman/transToken/transResultInfo) to accept +// a NotTEC directly, enabling one-step implicit conversion via TERtoInt(NotTEC). +template <> +class CanCvtToTER : public std::true_type +{ +}; //------------------------------------------------------------------------------ inline bool -isTelLocal(TER x) noexcept +isTelLocal(TER const& x) noexcept { return (x >= telLOCAL_ERROR && x < temMALFORMED); } inline bool -isTemMalformed(TER x) noexcept +isTemMalformed(TER const& x) noexcept { return (x >= temMALFORMED && x < tefFAILURE); } inline bool -isTefFailure(TER x) noexcept +isTefFailure(TER const& x) noexcept { return (x >= tefFAILURE && x < terRETRY); } inline bool -isTerRetry(TER x) noexcept +isTerRetry(TER const& x) noexcept { return (x >= terRETRY && x < tesSUCCESS); } inline bool -isTesSuccess(TER x) noexcept +isTesSuccess(TER const& x) noexcept { - // Makes use of TERSubset::operator bool() + // Makes use of TER::operator bool() return !x; } inline bool -isTecClaim(TER x) noexcept +isTecClaim(TER const& x) noexcept { return (x >= tecCLAIM); } @@ -689,13 +829,10 @@ std::unordered_map transCode(std::string const& token); diff --git a/include/xrpl/protocol/jss.h b/include/xrpl/protocol/jss.h index 63e877ca311..95864f0b41a 100644 --- a/include/xrpl/protocol/jss.h +++ b/include/xrpl/protocol/jss.h @@ -239,6 +239,7 @@ JSS(enabled); // out: AmendmentTable JSS(engine_result); // out: NetworkOPs, TransactionSign, Submit JSS(engine_result_code); // out: NetworkOPs, TransactionSign, Submit JSS(engine_result_message); // out: NetworkOPs, TransactionSign, Submit +JSS(engine_result_reason); // out: NetworkOPs, TransactionSign, Submit JSS(entire_set); // out: get_aggregate_price JSS(ephemeral_key); // out: ValidatorInfo // in/out: Manifest diff --git a/include/xrpl/tx/Transactor.h b/include/xrpl/tx/Transactor.h index a71285f70e0..2de1f08af08 100644 --- a/include/xrpl/tx/Transactor.h +++ b/include/xrpl/tx/Transactor.h @@ -100,7 +100,7 @@ struct PreclaimContext beast::Journal j = beast::Journal{beast::Journal::getNullSink()}) : registry(registry) , view(view) - , preflightResult(preflightResult) + , preflightResult(std::move(preflightResult)) , flags(flags) , tx(tx) , parentBatchId(parentBatchId) diff --git a/include/xrpl/tx/applySteps.h b/include/xrpl/tx/applySteps.h index bd495481f21..3be6c2b0bce 100644 --- a/include/xrpl/tx/applySteps.h +++ b/include/xrpl/tx/applySteps.h @@ -28,7 +28,7 @@ struct ApplyResult std::optional metadata; ApplyResult(TER t, bool a, std::optional m = std::nullopt) - : ter(t), applied(a), metadata(std::move(m)) + : ter(std::move(t)), applied(a), metadata(std::move(m)) { } }; diff --git a/include/xrpl/tx/paths/detail/Steps.h b/include/xrpl/tx/paths/detail/Steps.h index 8ee37c026cb..b3269fa3d64 100644 --- a/include/xrpl/tx/paths/detail/Steps.h +++ b/include/xrpl/tx/paths/detail/Steps.h @@ -505,7 +505,7 @@ class FlowException : public std::runtime_error public: TER ter; - FlowException(TER t, std::string const& msg) : std::runtime_error(msg), ter(t) + FlowException(TER t, std::string const& msg) : std::runtime_error(msg), ter(std::move(t)) { } diff --git a/src/libxrpl/protocol/TER.cpp b/src/libxrpl/protocol/TER.cpp index c2167d58ce3..611ae17cc0c 100644 --- a/src/libxrpl/protocol/TER.cpp +++ b/src/libxrpl/protocol/TER.cpp @@ -233,7 +233,7 @@ transResults() } bool -transResultInfo(TER code, std::string& token, std::string& text) +transResultInfo(TERRaw code, std::string& token, std::string& text) { auto& results = transResults(); @@ -248,7 +248,7 @@ transResultInfo(TER code, std::string& token, std::string& text) } std::string -transToken(TER code) +transToken(TERRaw code) { std::string token; std::string text; @@ -257,7 +257,7 @@ transToken(TER code) } std::string -transHuman(TER code) +transHuman(TERRaw code) { std::string token; std::string text; diff --git a/src/libxrpl/tx/Transactor.cpp b/src/libxrpl/tx/Transactor.cpp index 4b562692d75..f4f7d96a9a4 100644 --- a/src/libxrpl/tx/Transactor.cpp +++ b/src/libxrpl/tx/Transactor.cpp @@ -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) { @@ -817,8 +806,7 @@ Transactor::ticketDelete( if (!sleTicket) { // LCOV_EXCL_START - JLOG(j.fatal()) << "Ticket disappeared from ledger."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Ticket disappeared from ledger."}; // LCOV_EXCL_STOP } @@ -826,8 +814,7 @@ Transactor::ticketDelete( if (!view.dirRemove(keylet::ownerDir(account), page, ticketIndex, true)) { // LCOV_EXCL_START - JLOG(j.fatal()) << "Unable to delete Ticket from owner."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete Ticket from owner."}; // LCOV_EXCL_STOP } @@ -837,8 +824,7 @@ Transactor::ticketDelete( if (!sleAccount) { // LCOV_EXCL_START - JLOG(j.fatal()) << "Could not find Ticket owner account root."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Could not find Ticket owner account root."}; // LCOV_EXCL_STOP } @@ -856,8 +842,7 @@ Transactor::ticketDelete( else { // LCOV_EXCL_START - JLOG(j.fatal()) << "TicketCount field missing from account root."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "TicketCount field missing from account root."}; // LCOV_EXCL_STOP } @@ -983,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. @@ -1058,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 @@ -1095,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 @@ -1115,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( @@ -1163,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."}; } } } @@ -1174,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. @@ -1197,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. diff --git a/src/libxrpl/tx/paths/DirectStep.cpp b/src/libxrpl/tx/paths/DirectStep.cpp index f8f12bd421a..e1abbbf1f8d 100644 --- a/src/libxrpl/tx/paths/DirectStep.cpp +++ b/src/libxrpl/tx/paths/DirectStep.cpp @@ -825,14 +825,12 @@ DirectStepI::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_)); diff --git a/src/libxrpl/tx/paths/MPTEndpointStep.cpp b/src/libxrpl/tx/paths/MPTEndpointStep.cpp index 0a0f6a9f27d..f732d907a12 100644 --- a/src/libxrpl/tx/paths/MPTEndpointStep.cpp +++ b/src/libxrpl/tx/paths/MPTEndpointStep.cpp @@ -823,14 +823,12 @@ MPTEndpointStep::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::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(this)->check(ctx, sleSrc); diff --git a/src/libxrpl/tx/paths/XRPEndpointStep.cpp b/src/libxrpl/tx/paths/XRPEndpointStep.cpp index 05d893a50d6..93fc86bb69f 100644 --- a/src/libxrpl/tx/paths/XRPEndpointStep.cpp +++ b/src/libxrpl/tx/paths/XRPEndpointStep.cpp @@ -338,8 +338,7 @@ XRPEndpointStep::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_)); diff --git a/src/libxrpl/tx/transactors/account/AccountSet.cpp b/src/libxrpl/tx/transactors/account/AccountSet.cpp index f0ad5b113a5..fe786beba75 100644 --- a/src/libxrpl/tx/transactors/account/AccountSet.cpp +++ b/src/libxrpl/tx/transactors/account/AccountSet.cpp @@ -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: @@ -198,14 +188,12 @@ AccountSet::preclaim(PreclaimContext const& ctx) { if (sle->isFlag(lsfNoFreeze)) { - JLOG(ctx.j.trace()) << "Can't set Clawback if NoFreeze is set"; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Can't set Clawback if NoFreeze is set"}; } if (!dirIsEmpty(ctx.view, keylet::ownerDir(id))) { - JLOG(ctx.j.trace()) << "Owner directory not empty."; - return tecOWNERS; + return {tecOWNERS, "Owner directory not empty."}; } } else if (uSetFlag == asfNoFreeze) @@ -213,8 +201,7 @@ AccountSet::preclaim(PreclaimContext const& ctx) // Cannot set NoFreeze if clawback is enabled if (sle->isFlag(lsfAllowTrustLineClawback)) { - JLOG(ctx.j.trace()) << "Can't set NoFreeze if clawback is enabled"; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Can't set NoFreeze if clawback is enabled"}; } } @@ -308,8 +295,7 @@ AccountSet::doApply() { if (!sigWithMaster) { - JLOG(j_.trace()) << "Must use master key to disable master key."; - return tecNEED_MASTER_KEY; + return {tecNEED_MASTER_KEY, "Must use master key to disable master key."}; } if ((!sle->isFieldPresent(sfRegularKey)) && (!view().peek(keylet::signerList(accountID_)))) @@ -349,8 +335,7 @@ AccountSet::doApply() { if (!sigWithMaster && !sle->isFlag(lsfDisableMaster)) { - JLOG(j_.trace()) << "Must use master key to set NoFreeze."; - return tecNEED_MASTER_KEY; + return {tecNEED_MASTER_KEY, "Must use master key to set NoFreeze."}; } JLOG(j_.trace()) << "Set NoFreeze flag"; diff --git a/src/libxrpl/tx/transactors/account/SignerListSet.cpp b/src/libxrpl/tx/transactors/account/SignerListSet.cpp index 799c292bfcf..74aedc17c88 100644 --- a/src/libxrpl/tx/transactors/account/SignerListSet.cpp +++ b/src/libxrpl/tx/transactors/account/SignerListSet.cpp @@ -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) @@ -208,8 +207,7 @@ removeSignersFromLedger( if (!view.dirRemove(ownerDirKeylet, hint, signerListKeylet.key, false)) { // LCOV_EXCL_START - JLOG(j.fatal()) << "Unable to delete SignerList from owner."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete SignerList from owner."}; // LCOV_EXCL_STOP } @@ -249,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."}; } } @@ -261,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 @@ -273,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; } diff --git a/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp b/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp index e03cb56fd52..27fb5faef21 100644 --- a/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp +++ b/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp @@ -133,9 +133,9 @@ checkAttestationPublicKey( // master key if (sleAttestationSigningAccount->isFlag(lsfDisableMaster)) { - JLOG(j.trace()) << "Attempt to add an attestation with " - "disabled master key."; - return tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR; + return { + tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR, + "Attempt to add an attestation with disabled master key."}; } } else @@ -165,9 +165,10 @@ checkAttestationPublicKey( // account does not exist. if (calcAccountID(pk) != attestationSignerAccount) { - JLOG(j.trace()) << "Attempt to add an attestation with non-existant account " - "and mismatched pk/account pair."; - return tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR; + return { + tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR, + "Attempt to add an attestation with non-existant account and mismatched pk/account " + "pair."}; } } @@ -465,8 +466,7 @@ transferHelper( } if (amt < psb.fees().reserve) { - JLOG(j.trace()) << "Insufficient payment to create account."; - return tecNO_DST_INSUF_XRP; + return {tecNO_DST_INSUF_XRP, "Insufficient payment to create account."}; } // Create the account. diff --git a/src/libxrpl/tx/transactors/check/CheckCancel.cpp b/src/libxrpl/tx/transactors/check/CheckCancel.cpp index f4602f98c65..ca0b5cafac9 100644 --- a/src/libxrpl/tx/transactors/check/CheckCancel.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCancel.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -33,8 +32,7 @@ CheckCancel::preclaim(PreclaimContext const& ctx) auto const sleCheck = ctx.view.read(keylet::check(ctx.tx[sfCheckID])); if (!sleCheck) { - JLOG(ctx.j.warn()) << "Check does not exist."; - return tecNO_ENTRY; + return {tecNO_ENTRY, "Check does not exist."}; } // Expiration is defined in terms of the close time of the parent @@ -48,9 +46,9 @@ CheckCancel::preclaim(PreclaimContext const& ctx) AccountID const acctId{ctx.tx[sfAccount]}; if (acctId != (*sleCheck)[sfAccount] && acctId != (*sleCheck)[sfDestination]) { - JLOG(ctx.j.warn()) << "Check is not expired and canceler is " - "neither check source nor destination."; - return tecNO_PERMISSION; + return { + tecNO_PERMISSION, + "Check is not expired and canceler is neither check source nor destination."}; } } return tesSUCCESS; @@ -63,8 +61,7 @@ CheckCancel::doApply() if (!sleCheck) { // Error should have been caught in preclaim. - JLOG(j_.warn()) << "Check does not exist."; - return tecNO_ENTRY; + return {tecNO_ENTRY, "Check does not exist."}; } AccountID const srcId{sleCheck->getAccountID(sfAccount)}; @@ -79,8 +76,7 @@ CheckCancel::doApply() if (!view().dirRemove(keylet::ownerDir(dstId), page, sleCheck->key(), true)) { // LCOV_EXCL_START - JLOG(j_.fatal()) << "Unable to delete check from destination."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete check from destination."}; // LCOV_EXCL_STOP } } @@ -89,8 +85,7 @@ CheckCancel::doApply() if (!view().dirRemove(keylet::ownerDir(srcId), page, sleCheck->key(), true)) { // LCOV_EXCL_START - JLOG(j_.fatal()) << "Unable to delete check from owner."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete check from owner."}; // LCOV_EXCL_STOP } } diff --git a/src/libxrpl/tx/transactors/check/CheckCash.cpp b/src/libxrpl/tx/transactors/check/CheckCash.cpp index a8c989f4df8..90ebe7ddb47 100644 --- a/src/libxrpl/tx/transactors/check/CheckCash.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCash.cpp @@ -61,9 +61,9 @@ CheckCash::preflight(PreflightContext const& ctx) if (static_cast(optAmount) == static_cast(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; @@ -89,16 +88,14 @@ CheckCash::preclaim(PreclaimContext const& ctx) auto const sleCheck = ctx.view.read(keylet::check(ctx.tx[sfCheckID])); if (!sleCheck) { - JLOG(ctx.j.warn()) << "Check does not exist."; - return tecNO_ENTRY; + return {tecNO_ENTRY, "Check does not exist."}; } // Only cash a check with this account as the destination. AccountID const dstId = sleCheck->at(sfDestination); if (ctx.tx[sfAccount] != dstId) { - JLOG(ctx.j.warn()) << "Cashing a check with wrong Destination."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Cashing a check with wrong Destination."}; } AccountID const srcId = sleCheck->at(sfAccount); if (srcId == dstId) @@ -106,8 +103,7 @@ CheckCash::preclaim(PreclaimContext const& ctx) // They wrote a check to themselves. This should be caught when // the check is created, but better late than never. // LCOV_EXCL_START - JLOG(ctx.j.error()) << "Malformed transaction: Cashing check to self."; - return tecINTERNAL; + return {tecINTERNAL, "Malformed transaction: Cashing check to self."}; // LCOV_EXCL_STOP } { @@ -116,23 +112,20 @@ CheckCash::preclaim(PreclaimContext const& ctx) if (!sleSrc || !sleDst) { // If the check exists this should never occur. - JLOG(ctx.j.warn()) << "Malformed transaction: source or destination not in ledger"; - return tecNO_ENTRY; + return {tecNO_ENTRY, "Malformed transaction: source or destination not in ledger"}; } if (sleDst->isFlag(lsfRequireDestTag) && !sleCheck->isFieldPresent(sfDestinationTag)) { // The tag is basically account-specific information we don't // understand, but we can require someone to fill it in. - JLOG(ctx.j.warn()) << "Malformed transaction: DestinationTag required in check."; - return tecDST_TAG_NEEDED; + return {tecDST_TAG_NEEDED, "Malformed transaction: DestinationTag required in check."}; } } if (hasExpired(ctx.view, sleCheck->at(~sfExpiration))) { - JLOG(ctx.j.warn()) << "Cashing a check that has already expired."; - return tecEXPIRED; + return {tecEXPIRED, "Cashing a check that has already expired."}; } { @@ -151,19 +144,16 @@ 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) { - JLOG(ctx.j.warn()) << "Check cashed for more than check sendMax."; - return tecPATH_PARTIAL; + return {tecPATH_PARTIAL, "Check cashed for more than check sendMax."}; } // Make sure the check owner holds at least value. If they have @@ -186,8 +176,7 @@ CheckCash::preclaim(PreclaimContext const& ctx) if (value > availableFunds) { - JLOG(ctx.j.warn()) << "Check cashed for more than owner's balance."; - return tecPATH_PARTIAL; + return {tecPATH_PARTIAL, "Check cashed for more than owner's balance."}; } } @@ -230,9 +219,7 @@ CheckCash::preclaim(PreclaimContext const& ctx) if (!isAuthorized) { - JLOG(ctx.j.warn()) << "Can't receive IOUs from " - "issuer without auth."; - return tecNO_AUTH; + return {tecNO_AUTH, "Can't receive IOUs from issuer without auth."}; } } @@ -245,8 +232,7 @@ CheckCash::preclaim(PreclaimContext const& ctx) // not be frozen. if (isFrozen(ctx.view, dstId, currency, issuerId)) { - JLOG(ctx.j.warn()) << "Cashing a check to a frozen trustline."; - return tecFROZEN; + return {tecFROZEN, "Cashing a check to a frozen trustline."}; } return tesSUCCESS; @@ -270,8 +256,7 @@ CheckCash::preclaim(PreclaimContext const& ctx) if (isFrozen(ctx.view, dstId, issue)) { - JLOG(ctx.j.warn()) << "Cashing a check to a frozen MPT."; - return tecLOCKED; + return {tecLOCKED, "Cashing a check to a frozen MPT."}; } if (auto const err = canTransfer(ctx.view, issue, srcId, dstId); @@ -299,8 +284,7 @@ CheckCash::doApply() if (!sleCheck) { // LCOV_EXCL_START - JLOG(j_.fatal()) << "Precheck did not verify check's existence."; - return tecFAILED_PROCESSING; + return {tecFAILED_PROCESSING, "Precheck did not verify check's existence."}; // LCOV_EXCL_STOP } @@ -308,8 +292,7 @@ CheckCash::doApply() if (!psb.exists(keylet::account(srcId)) || !psb.exists(keylet::account(accountID_))) { // LCOV_EXCL_START - JLOG(ctx_.journal.fatal()) << "Precheck did not verify source or destination's existence."; - return tecFAILED_PROCESSING; + return {tecFAILED_PROCESSING, "Precheck did not verify source or destination's existence."}; // LCOV_EXCL_STOP } @@ -566,8 +549,7 @@ CheckCash::doApply() { if (result.actualAmountOut < *optDeliverMin) { - JLOG(ctx_.journal.warn()) << "flow did not produce DeliverMin."; - return tecPATH_PARTIAL; + return {tecPATH_PARTIAL, "flow did not produce DeliverMin."}; } ctx_.deliver(result.actualAmountOut); } @@ -587,8 +569,7 @@ CheckCash::doApply() keylet::ownerDir(accountID_), sleCheck->at(sfDestinationNode), sleCheck->key(), true)) { // LCOV_EXCL_START - JLOG(j_.fatal()) << "Unable to delete check from destination."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete check from destination."}; // LCOV_EXCL_STOP } @@ -596,8 +577,7 @@ CheckCash::doApply() if (!psb.dirRemove(keylet::ownerDir(srcId), sleCheck->at(sfOwnerNode), sleCheck->key(), true)) { // LCOV_EXCL_START - JLOG(j_.fatal()) << "Unable to delete check from owner."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete check from owner."}; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/tx/transactors/check/CheckCreate.cpp b/src/libxrpl/tx/transactors/check/CheckCreate.cpp index cb1d81ba4a4..7fb634ac35e 100644 --- a/src/libxrpl/tx/transactors/check/CheckCreate.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCreate.cpp @@ -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"}; } } @@ -83,8 +80,7 @@ CheckCreate::preclaim(PreclaimContext const& ctx) auto const sleDst = ctx.view.read(keylet::account(dstId)); if (!sleDst) { - JLOG(ctx.j.warn()) << "Destination account does not exist."; - return tecNO_DST; + return {tecNO_DST, "Destination account does not exist."}; } // Check if the destination has disallowed incoming checks @@ -102,8 +98,7 @@ CheckCreate::preclaim(PreclaimContext const& ctx) { // The tag is basically account-specific information we don't // understand, but we can require someone to fill it in. - JLOG(ctx.j.warn()) << "Malformed transaction: DestinationTag required."; - return tecDST_TAG_NEEDED; + return {tecDST_TAG_NEEDED, "Malformed transaction: DestinationTag required."}; } { @@ -114,8 +109,7 @@ CheckCreate::preclaim(PreclaimContext const& ctx) AccountID const& issuerId{sendMax.getIssuer()}; if (auto const ter = checkGlobalFrozen(ctx.view, sendMax.asset()); !isTesSuccess(ter)) { - JLOG(ctx.j.warn()) << "Creating a check for frozen or locked asset"; - return ter; + return {ter, "Creating a check for frozen or locked asset"}; } auto const err = sendMax.asset().visit( [&](Issue const& issue) -> std::optional { @@ -132,8 +126,7 @@ CheckCreate::preclaim(PreclaimContext const& ctx) if (sleTrust && sleTrust->isFlag((issuerId > srcId) ? lsfHighFreeze : lsfLowFreeze)) { - JLOG(ctx.j.warn()) << "Creating a check for frozen trustline."; - return tecFROZEN; + return TER{tecFROZEN, "Creating a check for frozen trustline."}; } } if (issuerId != dstId) @@ -144,9 +137,8 @@ CheckCreate::preclaim(PreclaimContext const& ctx) if (sleTrust && sleTrust->isFlag((dstId > issuerId) ? lsfHighFreeze : lsfLowFreeze)) { - JLOG(ctx.j.warn()) << "Creating a check for " - "destination frozen trustline."; - return tecFROZEN; + return TER{ + tecFROZEN, "Creating a check for destination frozen trustline."}; } } @@ -155,19 +147,16 @@ CheckCreate::preclaim(PreclaimContext const& ctx) [&](MPTIssue const& issue) -> std::optional { if (srcId != issuerId && isFrozen(ctx.view, srcId, issue)) { - JLOG(ctx.j.warn()) << "Creating a check for locked MPT."; - return tecLOCKED; + return TER{tecLOCKED, "Creating a check for locked MPT."}; } if (dstId != issuerId && isFrozen(ctx.view, dstId, issue)) { - JLOG(ctx.j.warn()) << "Creating a check for locked MPT."; - return tecLOCKED; + return TER{tecLOCKED, "Creating a check for locked MPT."}; } if (auto const ter = canTransfer(ctx.view, issue, srcId, dstId); !isTesSuccess(ter)) { - JLOG(ctx.j.warn()) << "MPT transfer is disabled."; - return ter; + return TER{ter, "MPT transfer is disabled."}; } return std::nullopt; @@ -178,8 +167,7 @@ CheckCreate::preclaim(PreclaimContext const& ctx) } if (hasExpired(ctx.view, ctx.tx[~sfExpiration])) { - JLOG(ctx.j.warn()) << "Creating a check that has already expired."; - return tecEXPIRED; + return {tecEXPIRED, "Creating a check that has already expired."}; } return tesSUCCESS; diff --git a/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp b/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp index c0ef7ea9e8a..cc6588950c5 100644 --- a/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp +++ b/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp @@ -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; diff --git a/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp b/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp index e902ee73a6c..9f5e7614dab 100644 --- a/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp +++ b/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp @@ -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; @@ -86,14 +82,12 @@ CredentialCreate::preclaim(PreclaimContext const& ctx) if (!ctx.view.exists(keylet::account(subject))) { - JLOG(ctx.j.trace()) << "Subject doesn't exist."; - return tecNO_TARGET; + return {tecNO_TARGET, "Subject doesn't exist."}; } if (ctx.view.exists(keylet::credential(subject, ctx.tx[sfAccount], credType))) { - JLOG(ctx.j.trace()) << "Credential already exists."; - return tecDUPLICATE; + return {tecDUPLICATE, "Credential already exists."}; } return tesSUCCESS; @@ -118,9 +112,7 @@ CredentialCreate::doApply() if (closeTime > *optExp) { - JLOG(j_.trace()) << "Malformed transaction: " - "Expiration time is in the past."; - return tecEXPIRED; + return {tecEXPIRED, "Malformed transaction: Expiration time is in the past."}; } sleCred->setFieldU32(sfExpiration, *optExp); diff --git a/src/libxrpl/tx/transactors/credentials/CredentialDelete.cpp b/src/libxrpl/tx/transactors/credentials/CredentialDelete.cpp index 6bd4ad54c5c..c6e23737847 100644 --- a/src/libxrpl/tx/transactors/credentials/CredentialDelete.cpp +++ b/src/libxrpl/tx/transactors/credentials/CredentialDelete.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -36,24 +35,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; @@ -87,8 +81,7 @@ CredentialDelete::doApply() if ((subject != accountID_) && (issuer != accountID_) && !checkExpired(*sleCred, ctx_.view().header().parentCloseTime)) { - JLOG(j_.trace()) << "Can't delete non-expired credential."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Can't delete non-expired credential."}; } return deleteSLE(view(), sleCred, j_); diff --git a/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp b/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp index 96e6c9e4431..a718634f17d 100644 --- a/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp +++ b/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -152,8 +151,7 @@ DelegateSet::deleteDelegate(ApplyView& view, SLE::ref sle, beast::Journal j) if (!view.dirRemove(keylet::ownerDir(delegator), (*sle)[sfOwnerNode], sle->key(), false)) { // LCOV_EXCL_START - JLOG(j.fatal()) << "Unable to delete Delegate from owner."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete Delegate from owner."}; // LCOV_EXCL_STOP } @@ -163,8 +161,7 @@ DelegateSet::deleteDelegate(ApplyView& view, SLE::ref sle, beast::Journal j) if (!view.dirRemove(keylet::ownerDir(delegatee), *optPage, sle->key(), false)) { // LCOV_EXCL_START - JLOG(j.fatal()) << "Unable to delete Delegate from authorized account."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete Delegate from authorized account."}; // LCOV_EXCL_STOP } } diff --git a/src/libxrpl/tx/transactors/dex/AMMBid.cpp b/src/libxrpl/tx/transactors/dex/AMMBid.cpp index 3454559e821..5f512a54e83 100644 --- a/src/libxrpl/tx/transactors/dex/AMMBid.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMBid.cpp @@ -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); } @@ -107,8 +105,7 @@ AMMBid::preclaim(PreclaimContext const& ctx) auto const ammSle = ctx.view.read(keylet::amm(ctx.tx[sfAsset], ctx.tx[sfAsset2])); if (!ammSle) { - JLOG(ctx.j.debug()) << "AMM Bid: Invalid asset pair."; - return terNO_AMM; + return {terNO_AMM, "AMM Bid: Invalid asset pair."}; } auto const lpTokensBalance = (*ammSle)[sfLPTokenBalance]; @@ -121,8 +118,7 @@ AMMBid::preclaim(PreclaimContext const& ctx) { if (!ctx.view.read(keylet::account(account[sfAccount]))) { - JLOG(ctx.j.debug()) << "AMM Bid: Invalid Account."; - return terNO_ACCOUNT; + return {terNO_ACCOUNT, "AMM Bid: Invalid Account."}; } } } @@ -131,8 +127,7 @@ AMMBid::preclaim(PreclaimContext const& ctx) // Not LP if (lpTokens == beast::kZero) { - JLOG(ctx.j.debug()) << "AMM Bid: account is not LP."; - return tecAMM_INVALID_TOKENS; + return {tecAMM_INVALID_TOKENS, "AMM Bid: account is not LP."}; } auto const bidMin = ctx.tx[~sfBidMin]; @@ -141,13 +136,11 @@ 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) { - JLOG(ctx.j.debug()) << "AMM Bid: Invalid Tokens."; - return tecAMM_INVALID_TOKENS; + return {tecAMM_INVALID_TOKENS, "AMM Bid: Invalid Tokens."}; } } @@ -156,20 +149,17 @@ 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) { - JLOG(ctx.j.debug()) << "AMM Bid: Invalid Tokens."; - return tecAMM_INVALID_TOKENS; + return {tecAMM_INVALID_TOKENS, "AMM Bid: Invalid Tokens."}; } } if (bidMin && bidMax && bidMin > bidMax) { - JLOG(ctx.j.debug()) << "AMM Bid: Invalid Max/MinSlotPrice."; - return tecAMM_INVALID_TOKENS; + return {tecAMM_INVALID_TOKENS, "AMM Bid: Invalid Max/MinSlotPrice."}; } return tesSUCCESS; diff --git a/src/libxrpl/tx/transactors/dex/AMMClawback.cpp b/src/libxrpl/tx/transactors/dex/AMMClawback.cpp index c1ef9f875ee..aefc30f7ebf 100644 --- a/src/libxrpl/tx/transactors/dex/AMMClawback.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMClawback.cpp @@ -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 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) @@ -112,8 +108,7 @@ AMMClawback::preclaim(PreclaimContext const& ctx) auto const ammSle = ctx.view.read(keylet::amm(asset, asset2)); if (!ammSle) { - JLOG(ctx.j.debug()) << "AMM Clawback: Invalid asset pair."; - return terNO_AMM; + return {terNO_AMM, "AMM Clawback: Invalid asset pair."}; } if (!ctx.view.rules().enabled(featureMPTokensV2)) diff --git a/src/libxrpl/tx/transactors/dex/AMMCreate.cpp b/src/libxrpl/tx/transactors/dex/AMMCreate.cpp index 7c7d35497a9..bc4ebf04d06 100644 --- a/src/libxrpl/tx/transactors/dex/AMMCreate.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMCreate.cpp @@ -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; @@ -102,8 +100,7 @@ AMMCreate::preclaim(PreclaimContext const& ctx) if (auto const ammKeylet = keylet::amm(amount.asset(), amount2.asset()); ctx.view.read(ammKeylet)) { - JLOG(ctx.j.debug()) << "AMM Instance: ltAMM already exists."; - return tecDUPLICATE; + return {tecDUPLICATE, "AMM Instance: ltAMM already exists."}; } if (auto const ter = requireAuth(ctx.view, amount.asset(), accountID); !isTesSuccess(ter)) @@ -122,13 +119,11 @@ AMMCreate::preclaim(PreclaimContext const& ctx) if (auto const ter = checkFrozen(ctx.view, accountID, amount.asset()); !isTesSuccess(ter)) { - JLOG(ctx.j.debug()) << "AMM Instance: involves frozen or locked asset."; - return ter; + return {ter, "AMM Instance: involves frozen or locked asset."}; } if (auto const ter = checkFrozen(ctx.view, accountID, amount2.asset()); !isTesSuccess(ter)) { - JLOG(ctx.j.debug()) << "AMM Instance: involves frozen or locked asset."; - return ter; + return {ter, "AMM Instance: involves frozen or locked asset."}; } auto noDefaultRipple = [](ReadView const& view, Asset const& asset) { @@ -143,8 +138,7 @@ AMMCreate::preclaim(PreclaimContext const& ctx) if (noDefaultRipple(ctx.view, amount.asset()) || noDefaultRipple(ctx.view, amount2.asset())) { - JLOG(ctx.j.debug()) << "AMM Instance: DefaultRipple not set"; - return terNO_RIPPLE; + return {terNO_RIPPLE, "AMM Instance: DefaultRipple not set"}; } // Check the reserve for LPToken trustline @@ -152,8 +146,7 @@ AMMCreate::preclaim(PreclaimContext const& ctx) // Insufficient reserve if (xrpBalance <= beast::kZero) { - JLOG(ctx.j.debug()) << "AMM Instance: insufficient reserves"; - return tecINSUF_RESERVE_LINE; + return {tecINSUF_RESERVE_LINE, "AMM Instance: insufficient reserves"}; } auto insufficientBalance = [&](STAmount const& amount) { diff --git a/src/libxrpl/tx/transactors/dex/AMMDelete.cpp b/src/libxrpl/tx/transactors/dex/AMMDelete.cpp index e2ecec82429..82c3d93ea64 100644 --- a/src/libxrpl/tx/transactors/dex/AMMDelete.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMDelete.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -39,8 +38,7 @@ AMMDelete::preclaim(PreclaimContext const& ctx) auto const ammSle = ctx.view.read(keylet::amm(ctx.tx[sfAsset], ctx.tx[sfAsset2])); if (!ammSle) { - JLOG(ctx.j.debug()) << "AMM Delete: Invalid asset pair."; - return terNO_AMM; + return {terNO_AMM, "AMM Delete: Invalid asset pair."}; } auto const lpTokensBalance = (*ammSle)[sfLPTokenBalance]; diff --git a/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp b/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp index 0d1798babc0..2104dff11a8 100644 --- a/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp @@ -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; @@ -181,8 +178,7 @@ AMMDeposit::preclaim(PreclaimContext const& ctx) auto const ammSle = ctx.view.read(keylet::amm(ctx.tx[sfAsset], ctx.tx[sfAsset2])); if (!ammSle) { - JLOG(ctx.j.debug()) << "AMM Deposit: Invalid asset pair."; - return terNO_AMM; + return {terNO_AMM, "AMM Deposit: Invalid asset pair."}; } auto const expected = ammHolds( @@ -203,8 +199,7 @@ AMMDeposit::preclaim(PreclaimContext const& ctx) if (amountBalance != beast::kZero || amount2Balance != beast::kZero) { // LCOV_EXCL_START - JLOG(ctx.j.debug()) << "AMM Deposit: tokens balance is not zero."; - return tecINTERNAL; + return {tecINTERNAL, "AMM Deposit: tokens balance is not zero."}; // LCOV_EXCL_STOP } } @@ -216,8 +211,7 @@ AMMDeposit::preclaim(PreclaimContext const& ctx) lptAMMBalance < beast::kZero) { // LCOV_EXCL_START - JLOG(ctx.j.debug()) << "AMM Deposit: reserves or tokens balance is zero."; - return tecINTERNAL; + return {tecINTERNAL, "AMM Deposit: reserves or tokens balance is zero."}; // LCOV_EXCL_STOP } } @@ -381,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. @@ -393,8 +386,7 @@ AMMDeposit::preclaim(PreclaimContext const& ctx) // Insufficient reserve if (xrpBalance <= beast::kZero) { - JLOG(ctx.j.debug()) << "AMM Instance: insufficient reserves"; - return tecINSUF_RESERVE_LINE; + return {tecINSUF_RESERVE_LINE, "AMM Instance: insufficient reserves"}; } } diff --git a/src/libxrpl/tx/transactors/dex/AMMVote.cpp b/src/libxrpl/tx/transactors/dex/AMMVote.cpp index 0f2b721ac43..07bf9a4ac2d 100644 --- a/src/libxrpl/tx/transactors/dex/AMMVote.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMVote.cpp @@ -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; @@ -61,8 +60,7 @@ AMMVote::preclaim(PreclaimContext const& ctx) auto const ammSle = ctx.view.read(keylet::amm(ctx.tx[sfAsset], ctx.tx[sfAsset2])); if (!ammSle) { - JLOG(ctx.j.debug()) << "AMM Vote: Invalid asset pair."; - return terNO_AMM; + return {terNO_AMM, "AMM Vote: Invalid asset pair."}; } if (ammSle->getFieldAmount(sfLPTokenBalance) == beast::kZero) { @@ -71,8 +69,7 @@ AMMVote::preclaim(PreclaimContext const& ctx) if (auto const lpTokensNew = ammLPHolds(ctx.view, *ammSle, ctx.tx[sfAccount], ctx.j); lpTokensNew == beast::kZero) { - JLOG(ctx.j.debug()) << "AMM Vote: account is not LP."; - return tecAMM_INVALID_TOKENS; + return {tecAMM_INVALID_TOKENS, "AMM Vote: account is not LP."}; } return tesSUCCESS; diff --git a/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp b/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp index 2baa7edfb4b..23e138fda4b 100644 --- a/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp @@ -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) @@ -186,8 +184,7 @@ AMMWithdraw::preclaim(PreclaimContext const& ctx) auto const ammSle = ctx.view.read(keylet::amm(ctx.tx[sfAsset], ctx.tx[sfAsset2])); if (!ammSle) { - JLOG(ctx.j.debug()) << "AMM Withdraw: Invalid asset pair."; - return terNO_AMM; + return {terNO_AMM, "AMM Withdraw: Invalid asset pair."}; } auto const amount = ctx.tx[~sfAmount]; @@ -210,8 +207,7 @@ AMMWithdraw::preclaim(PreclaimContext const& ctx) lptAMMBalance < beast::kZero) { // LCOV_EXCL_START - JLOG(ctx.j.debug()) << "AMM Withdraw: reserves or tokens balance is zero."; - return tecINTERNAL; + return {tecINTERNAL, "AMM Withdraw: reserves or tokens balance is zero."}; // LCOV_EXCL_STOP } @@ -280,26 +276,22 @@ AMMWithdraw::preclaim(PreclaimContext const& ctx) if (lpTokens <= beast::kZero) { - JLOG(ctx.j.debug()) << "AMM Withdraw: tokens balance is zero."; - return tecAMM_BALANCE; + return {tecAMM_BALANCE, "AMM Withdraw: tokens balance is zero."}; } 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) { - JLOG(ctx.j.debug()) << "AMM Withdraw: invalid tokens."; - return tecAMM_INVALID_TOKENS; + return {tecAMM_INVALID_TOKENS, "AMM Withdraw: invalid tokens."}; } 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) diff --git a/src/libxrpl/tx/transactors/dex/OfferCancel.cpp b/src/libxrpl/tx/transactors/dex/OfferCancel.cpp index 0dea5fa9673..d93d7faa6c7 100644 --- a/src/libxrpl/tx/transactors/dex/OfferCancel.cpp +++ b/src/libxrpl/tx/transactors/dex/OfferCancel.cpp @@ -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; diff --git a/src/libxrpl/tx/transactors/dex/OfferCreate.cpp b/src/libxrpl/tx/transactors/dex/OfferCreate.cpp index fb47cf0f971..596d79937a8 100644 --- a/src/libxrpl/tx/transactors/dex/OfferCreate.cpp +++ b/src/libxrpl/tx/transactors/dex/OfferCreate.cpp @@ -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; @@ -190,13 +181,11 @@ OfferCreate::preclaim(PreclaimContext const& ctx) if (auto const ter = checkGlobalFrozen(ctx.view, saTakerPays.asset()); !isTesSuccess(ter)) { - JLOG(ctx.j.debug()) << "Offer involves frozen or locked asset"; - return ter; + return {ter, "Offer involves frozen or locked asset"}; } if (auto const ter = checkGlobalFrozen(ctx.view, saTakerGets.asset()); !isTesSuccess(ter)) { - JLOG(ctx.j.debug()) << "Offer involves frozen or locked asset"; - return ter; + return {ter, "Offer involves frozen or locked asset"}; } // Allow unfunded MPT for issuer (OutstandingAmount >= MaximumAmount) @@ -209,8 +198,7 @@ OfferCreate::preclaim(PreclaimContext const& ctx) AuthHandling::ZeroIfUnauthorized, viewJ) <= beast::kZero) { - JLOG(ctx.j.debug()) << "delay: Offers must be at least partially funded."; - return tecUNFUNDED_OFFER; + return {tecUNFUNDED_OFFER, "delay: Offers must be at least partially funded."}; } // This can probably be simplified to make sure that you cancel sequences @@ -587,8 +575,9 @@ OfferCreate::applyHybrid( if (!bookNode) { - JLOG(j_.debug()) << "final result: failed to add hybrid offer to open book"; - return tecDIR_FULL; // LCOV_EXCL_LINE + return { + tecDIR_FULL, + "final result: failed to add hybrid offer to open book"}; // LCOV_EXCL_LINE } STArray bookArr(sfAdditionalBooks, 1); diff --git a/src/libxrpl/tx/transactors/did/DIDDelete.cpp b/src/libxrpl/tx/transactors/did/DIDDelete.cpp index a2af4c1100e..d93ef928cb8 100644 --- a/src/libxrpl/tx/transactors/did/DIDDelete.cpp +++ b/src/libxrpl/tx/transactors/did/DIDDelete.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -41,8 +40,7 @@ DIDDelete::deleteSLE(ApplyView& view, SLE::pointer sle, AccountID const owner, b if (!view.dirRemove(keylet::ownerDir(owner), (*sle)[sfOwnerNode], sle->key(), true)) { // LCOV_EXCL_START - JLOG(j.fatal()) << "Unable to delete DID from owner."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete DID from owner."}; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp b/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp index feed43d410f..9fbbb10ecbf 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -145,8 +144,7 @@ EscrowCancel::doApply() if (!ctx_.view().dirRemove(keylet::ownerDir(account), page, k.key, true)) { // LCOV_EXCL_START - JLOG(j_.fatal()) << "Unable to delete Escrow from owner."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete Escrow from owner."}; // LCOV_EXCL_STOP } } @@ -157,8 +155,7 @@ EscrowCancel::doApply() if (!ctx_.view().dirRemove(keylet::ownerDir((*slep)[sfDestination]), *optPage, k.key, true)) { // LCOV_EXCL_START - JLOG(j_.fatal()) << "Unable to delete Escrow from recipient."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete Escrow from recipient."}; // LCOV_EXCL_STOP } } @@ -202,8 +199,7 @@ EscrowCancel::doApply() if (!ctx_.view().dirRemove(keylet::ownerDir(issuer), *optPage, k.key, true)) { // LCOV_EXCL_START - JLOG(j_.fatal()) << "Unable to delete Escrow from recipient."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete Escrow from recipient."}; // LCOV_EXCL_STOP } } diff --git a/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp b/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp index 8bc98c7aa8e..378c323ac92 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -322,8 +321,7 @@ EscrowFinish::doApply() if (!ctx_.view().dirRemove(keylet::ownerDir(account), page, k.key, true)) { // LCOV_EXCL_START - JLOG(j_.fatal()) << "Unable to delete Escrow from owner."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete Escrow from owner."}; // LCOV_EXCL_STOP } } @@ -334,8 +332,7 @@ EscrowFinish::doApply() if (!ctx_.view().dirRemove(keylet::ownerDir(destID), *optPage, k.key, true)) { // LCOV_EXCL_START - JLOG(j_.fatal()) << "Unable to delete Escrow from recipient."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete Escrow from recipient."}; // LCOV_EXCL_STOP } } @@ -390,8 +387,7 @@ EscrowFinish::doApply() if (!ctx_.view().dirRemove(keylet::ownerDir(issuer), *optPage, k.key, true)) { // LCOV_EXCL_START - JLOG(j_.fatal()) << "Unable to delete Escrow from recipient."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete Escrow from recipient."}; // LCOV_EXCL_STOP } } diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverClawback.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverClawback.cpp index b914f3cf249..0b6b42388bc 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverClawback.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverClawback.cpp @@ -248,8 +248,7 @@ LoanBrokerCoverClawback::preclaim(PreclaimContext const& ctx) auto const sleBroker = ctx.view.read(keylet::loanBroker(brokerID)); if (!sleBroker) { - JLOG(ctx.j.warn()) << "LoanBroker does not exist."; - return tecNO_ENTRY; + return {tecNO_ENTRY, "LoanBroker does not exist."}; } auto const brokerPseudoAccountID = sleBroker->at(sfAccount); @@ -267,16 +266,14 @@ LoanBrokerCoverClawback::preclaim(PreclaimContext const& ctx) if (vaultAsset.native()) { - JLOG(ctx.j.warn()) << "Cannot clawback native asset."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Cannot clawback native asset."}; } // Only the issuer of the vault asset can claw it back from the broker's // cover funds. if (vaultAsset.getIssuer() != account) { - JLOG(ctx.j.warn()) << "Account is not the issuer of the vault asset."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Account is not the issuer of the vault asset."}; } if (amount) @@ -287,9 +284,10 @@ LoanBrokerCoverClawback::preclaim(PreclaimContext const& ctx) auto const txAsset = *findAsset; if (txAsset != vaultAsset) { - JLOG(ctx.j.warn()) << "Account is the correct issuer, but trying " - "to clawback the wrong asset from LoanBroker"; - return tecWRONG_ASSET; + return { + tecWRONG_ASSET, + "Account is the correct issuer, but trying to clawback the wrong asset from " + "LoanBroker"}; } } @@ -323,8 +321,7 @@ LoanBrokerCoverClawback::preclaim(PreclaimContext const& ctx) if (!sleIssuer) { // LCOV_EXCL_START - JLOG(ctx.j.fatal()) << "Issuer account does not exist."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Issuer account does not exist."}; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverDeposit.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverDeposit.cpp index 09ab03347a1..a5210d5f54f 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverDeposit.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverDeposit.cpp @@ -54,13 +54,11 @@ LoanBrokerCoverDeposit::preclaim(PreclaimContext const& ctx) auto const sleBroker = ctx.view.read(keylet::loanBroker(brokerID)); if (!sleBroker) { - JLOG(ctx.j.warn()) << "LoanBroker does not exist."; - return tecNO_ENTRY; + return {tecNO_ENTRY, "LoanBroker does not exist."}; } if (account != sleBroker->at(sfOwner)) { - JLOG(ctx.j.warn()) << "Account is not the owner of the LoanBroker."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Account is not the owner of the LoanBroker."}; } auto const vault = ctx.view.read(keylet::vault(sleBroker->at(sfVaultID))); if (!vault) diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp index 498f3c99eb3..dccb2a771d4 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp @@ -67,19 +67,16 @@ LoanBrokerCoverWithdraw::preclaim(PreclaimContext const& ctx) if (isPseudoAccount(ctx.view, dstAcct)) { - JLOG(ctx.j.warn()) << "Trying to withdraw into a pseudo-account."; - return tecPSEUDO_ACCOUNT; + return {tecPSEUDO_ACCOUNT, "Trying to withdraw into a pseudo-account."}; } auto const sleBroker = ctx.view.read(keylet::loanBroker(brokerID)); if (!sleBroker) { - JLOG(ctx.j.warn()) << "LoanBroker does not exist."; - return tecNO_ENTRY; + return {tecNO_ENTRY, "LoanBroker does not exist."}; } if (account != sleBroker->at(sfOwner)) { - JLOG(ctx.j.warn()) << "Account is not the owner of the LoanBroker."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Account is not the owner of the LoanBroker."}; } auto const vault = ctx.view.read(keylet::vault(sleBroker->at(sfVaultID))); if (!vault) diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp index b36977d2256..b301bbbdd80 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp @@ -46,16 +46,14 @@ LoanBrokerDelete::preclaim(PreclaimContext const& ctx) auto const sleBroker = ctx.view.read(keylet::loanBroker(brokerID)); if (!sleBroker) { - JLOG(ctx.j.warn()) << "LoanBroker does not exist."; - return tecNO_ENTRY; + return {tecNO_ENTRY, "LoanBroker does not exist."}; } auto const brokerOwner = sleBroker->at(sfOwner); if (account != brokerOwner) { - JLOG(ctx.j.warn()) << "Account is not the owner of the LoanBroker."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Account is not the owner of the LoanBroker."}; } if (auto const ownerCount = sleBroker->at(sfOwnerCount); ownerCount != 0) { @@ -170,18 +168,21 @@ LoanBrokerDelete::doApply() // obligations associated with the broker or broker pseudo-account. if (*brokerPseudoSLE->at(sfBalance)) { - JLOG(j_.warn()) << "LoanBrokerDelete: Pseudo-account has a balance"; - return tecHAS_OBLIGATIONS; // LCOV_EXCL_LINE + return { + tecHAS_OBLIGATIONS, + "LoanBrokerDelete: Pseudo-account has a balance"}; // LCOV_EXCL_LINE } if (brokerPseudoSLE->at(sfOwnerCount) != 0) { - JLOG(j_.warn()) << "LoanBrokerDelete: Pseudo-account still owns objects"; - return tecHAS_OBLIGATIONS; // LCOV_EXCL_LINE + return { + tecHAS_OBLIGATIONS, + "LoanBrokerDelete: Pseudo-account still owns objects"}; // LCOV_EXCL_LINE } if (auto const directory = keylet::ownerDir(brokerPseudoID); view().read(directory)) { - JLOG(j_.warn()) << "LoanBrokerDelete: Pseudo-account has a directory"; - return tecHAS_OBLIGATIONS; // LCOV_EXCL_LINE + return { + tecHAS_OBLIGATIONS, + "LoanBrokerDelete: Pseudo-account has a directory"}; // LCOV_EXCL_LINE } view().erase(brokerPseudoSLE); diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp index e9c153404ca..7d64dfbf3c2 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp @@ -99,15 +99,13 @@ LoanBrokerSet::preclaim(PreclaimContext const& ctx) auto const sleVault = ctx.view.read(keylet::vault(vaultID)); if (!sleVault) { - JLOG(ctx.j.warn()) << "Vault does not exist."; - return tecNO_ENTRY; + return {tecNO_ENTRY, "Vault does not exist."}; } Asset const asset = sleVault->at(sfAsset); if (account != sleVault->at(sfOwner)) { - JLOG(ctx.j.warn()) << "Account is not the owner of the Vault."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Account is not the owner of the Vault."}; } if (auto const brokerID = tx[~sfLoanBrokerID]) @@ -117,18 +115,15 @@ LoanBrokerSet::preclaim(PreclaimContext const& ctx) auto const sleBroker = ctx.view.read(keylet::loanBroker(*brokerID)); if (!sleBroker) { - JLOG(ctx.j.warn()) << "LoanBroker does not exist."; - return tecNO_ENTRY; + return {tecNO_ENTRY, "LoanBroker does not exist."}; } if (vaultID != sleBroker->at(sfVaultID)) { - JLOG(ctx.j.warn()) << "Can not change VaultID on an existing LoanBroker."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Can not change VaultID on an existing LoanBroker."}; } if (account != sleBroker->at(sfOwner)) { - JLOG(ctx.j.warn()) << "Account is not the owner of the LoanBroker."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Account is not the owner of the LoanBroker."}; } if (auto const debtMax = tx[~sfDebtMaximum]) @@ -137,8 +132,7 @@ LoanBrokerSet::preclaim(PreclaimContext const& ctx) auto const currentDebtTotal = sleBroker->at(sfDebtTotal); if (*debtMax != 0 && *debtMax < currentDebtTotal) { - JLOG(ctx.j.warn()) << "Cannot reduce DebtMaximum below current DebtTotal."; - return tecLIMIT_EXCEEDED; + return {tecLIMIT_EXCEEDED, "Cannot reduce DebtMaximum below current DebtTotal."}; } } } @@ -149,8 +143,7 @@ LoanBrokerSet::preclaim(PreclaimContext const& ctx) if (auto const ter = checkFrozen(ctx.view, sleVault->at(sfAccount), sleVault->at(sfAsset))) { - JLOG(ctx.j.warn()) << "Vault pseudo-account is frozen."; - return ter; + return {ter, "Vault pseudo-account is frozen."}; } } @@ -183,8 +176,7 @@ LoanBrokerSet::doApply() { // This should be impossible // LCOV_EXCL_START - JLOG(j_.fatal()) << "LoanBroker does not exist."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "LoanBroker does not exist."}; // LCOV_EXCL_STOP } @@ -212,8 +204,7 @@ LoanBrokerSet::doApply() { // This should be impossible // LCOV_EXCL_START - JLOG(j_.fatal()) << "Vault does not exist."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Vault does not exist."}; // LCOV_EXCL_STOP } auto const vaultPseudoID = sleVault->at(sfAccount); @@ -225,8 +216,7 @@ LoanBrokerSet::doApply() { // This should be impossible // LCOV_EXCL_START - JLOG(j_.fatal()) << "Account does not exist."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Account does not exist."}; // LCOV_EXCL_STOP } auto broker = std::make_shared(keylet::loanBroker(accountID_, sequence)); diff --git a/src/libxrpl/tx/transactors/lending/LoanDelete.cpp b/src/libxrpl/tx/transactors/lending/LoanDelete.cpp index 1a77489b4bc..e060bfa1368 100644 --- a/src/libxrpl/tx/transactors/lending/LoanDelete.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanDelete.cpp @@ -1,6 +1,5 @@ #include -#include #include // IWYU pragma: keep #include #include @@ -44,13 +43,11 @@ LoanDelete::preclaim(PreclaimContext const& ctx) auto const loanSle = ctx.view.read(keylet::loan(loanID)); if (!loanSle) { - JLOG(ctx.j.warn()) << "Loan does not exist."; - return tecNO_ENTRY; + return {tecNO_ENTRY, "Loan does not exist."}; } if (loanSle->at(sfPaymentRemaining) > 0) { - JLOG(ctx.j.warn()) << "Active loan can not be deleted."; - return tecHAS_OBLIGATIONS; + return {tecHAS_OBLIGATIONS, "Active loan can not be deleted."}; } auto const loanBrokerID = loanSle->at(sfLoanBrokerID); @@ -62,8 +59,7 @@ LoanDelete::preclaim(PreclaimContext const& ctx) } if (loanBrokerSle->at(sfOwner) != account && loanSle->at(sfBorrower) != account) { - JLOG(ctx.j.warn()) << "Account is not Loan Broker Owner or Loan Borrower."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Account is not Loan Broker Owner or Loan Borrower."}; } return tesSUCCESS; diff --git a/src/libxrpl/tx/transactors/lending/LoanManage.cpp b/src/libxrpl/tx/transactors/lending/LoanManage.cpp index a0aa948876b..6004b1c8644 100644 --- a/src/libxrpl/tx/transactors/lending/LoanManage.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanManage.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -52,9 +53,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."}; } } @@ -72,8 +74,7 @@ LoanManage::preclaim(PreclaimContext const& ctx) auto const loanSle = ctx.view.read(keylet::loan(loanID)); if (!loanSle) { - JLOG(ctx.j.warn()) << "Loan does not exist."; - return tecNO_ENTRY; + return {tecNO_ENTRY, "Loan does not exist."}; } // Impairment only allows certain transitions. // 1. Once it's in default, it can't be changed. @@ -83,31 +84,27 @@ LoanManage::preclaim(PreclaimContext const& ctx) // 4. If it's in a state, it can't be put in that state again. if (loanSle->isFlag(lsfLoanDefault)) { - JLOG(ctx.j.warn()) << "Loan is in default. A defaulted loan can not be modified."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Loan is in default. A defaulted loan can not be modified."}; } if (loanSle->isFlag(lsfLoanImpaired) && tx.isFlag(tfLoanImpair)) { - JLOG(ctx.j.warn()) << "Loan is impaired. A loan can not be impaired twice."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Loan is impaired. A loan can not be impaired twice."}; } if (!(loanSle->isFlag(lsfLoanImpaired) || loanSle->isFlag(lsfLoanDefault)) && (tx.isFlag(tfLoanUnimpair))) { - JLOG(ctx.j.warn()) << "Loan is unimpaired. Can not be unimpaired again."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Loan is unimpaired. Can not be unimpaired again."}; } if (loanSle->at(sfPaymentRemaining) == 0) { - JLOG(ctx.j.warn()) << "Loan is fully paid. A loan can not be modified " - "after it is fully paid."; - return tecNO_PERMISSION; + return { + tecNO_PERMISSION, + "Loan is fully paid. A loan can not be modified after it is fully paid."}; } if (tx.isFlag(tfLoanDefault) && !hasExpired(ctx.view, loanSle->at(sfNextPaymentDueDate) + loanSle->at(sfGracePeriod))) { - JLOG(ctx.j.warn()) << "A loan can not be defaulted before the next payment due date."; - return tecTOO_SOON; + return {tecTOO_SOON, "A loan can not be defaulted before the next payment due date."}; } auto const loanBrokerID = loanSle->at(sfLoanBrokerID); @@ -119,9 +116,10 @@ LoanManage::preclaim(PreclaimContext const& ctx) } if (loanBrokerSle->at(sfOwner) != account) { - JLOG(ctx.j.warn()) << "LoanBroker for Loan does not belong to the account. LoanManage " - "can only be submitted by the Loan Broker."; - return tecNO_PERMISSION; + return { + tecNO_PERMISSION, + "LoanBroker for Loan does not belong to the account. LoanManage can only be submitted " + "by the Loan Broker."}; } return tesSUCCESS; @@ -199,8 +197,7 @@ LoanManage::defaultLoan( if (vaultTotalProxy < vaultDefaultAmount) { // LCOV_EXCL_START - JLOG(j.warn()) << "Vault total assets is less than the vault default amount"; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Vault total assets is less than the vault default amount"}; // LCOV_EXCL_STOP } @@ -244,8 +241,7 @@ LoanManage::defaultLoan( if (vaultLossUnrealizedProxy < totalDefaultAmount) { // LCOV_EXCL_START - JLOG(j.warn()) << "Vault unrealized loss is less than the default amount"; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Vault unrealized loss is less than the default amount"}; // LCOV_EXCL_STOP } adjustImpreciseNumber( @@ -264,8 +260,7 @@ LoanManage::defaultLoan( if (coverAvailableProxy < defaultCovered) { // LCOV_EXCL_START - JLOG(j.warn()) << "LoanBroker cover available is less than amount covered"; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "LoanBroker cover available is less than amount covered"}; // LCOV_EXCL_STOP } coverAvailableProxy -= defaultCovered; @@ -318,9 +313,8 @@ LoanManage::impairLoan( { // Having a loss greater than the vault's unavailable assets // will leave the vault in an invalid / inconsistent state. - JLOG(j.warn()) << "Vault unrealized loss is too large, and will " - "corrupt the vault."; - return tecLIMIT_EXCEEDED; + return { + tecLIMIT_EXCEEDED, "Vault unrealized loss is too large, and will corrupt the vault."}; } view.update(vaultSle); @@ -357,8 +351,7 @@ LoanManage::unimpairLoan( if (vaultLossUnrealizedProxy < lossReversed) { // LCOV_EXCL_START - JLOG(j.warn()) << "Vault unrealized loss is less than the amount to be cleared"; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Vault unrealized loss is less than the amount to be cleared"}; // LCOV_EXCL_STOP } // Reverse the "paper loss" diff --git a/src/libxrpl/tx/transactors/lending/LoanPay.cpp b/src/libxrpl/tx/transactors/lending/LoanPay.cpp index 54ee85b186b..c34925fdf0a 100644 --- a/src/libxrpl/tx/transactors/lending/LoanPay.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanPay.cpp @@ -187,14 +187,12 @@ LoanPay::preclaim(PreclaimContext const& ctx) auto const loanSle = ctx.view.read(keylet::loan(loanID)); if (!loanSle) { - JLOG(ctx.j.warn()) << "Loan does not exist."; - return tecNO_ENTRY; + return {tecNO_ENTRY, "Loan does not exist."}; } if (loanSle->at(sfBorrower) != account) { - JLOG(ctx.j.warn()) << "Loan does not belong to the account."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "Loan does not belong to the account."}; } if (tx.isFlag(tfLoanOverpayment) && !loanSle->isFlag(lsfLoanOverpayment)) @@ -208,8 +206,7 @@ LoanPay::preclaim(PreclaimContext const& ctx) if (paymentRemaining == 0 || principalOutstanding == 0) { - JLOG(ctx.j.warn()) << "Loan is already paid off."; - return tecKILLED; + return {tecKILLED, "Loan is already paid off."}; } auto const loanBrokerID = loanSle->at(sfLoanBrokerID); @@ -218,8 +215,7 @@ LoanPay::preclaim(PreclaimContext const& ctx) { // This should be impossible // LCOV_EXCL_START - JLOG(ctx.j.fatal()) << "LoanBroker does not exist."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "LoanBroker does not exist."}; // LCOV_EXCL_STOP } auto const vaultID = loanBrokerSle->at(sfVaultID); @@ -228,8 +224,7 @@ LoanPay::preclaim(PreclaimContext const& ctx) { // This should be impossible // LCOV_EXCL_START - JLOG(ctx.j.fatal()) << "Vault does not exist."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Vault does not exist."}; // LCOV_EXCL_STOP } auto const asset = vaultSle->at(sfAsset); @@ -237,8 +232,7 @@ LoanPay::preclaim(PreclaimContext const& ctx) if (amount.asset() != asset) { - JLOG(ctx.j.warn()) << "Loan amount does not match the Vault asset."; - return tecWRONG_ASSET; + return {tecWRONG_ASSET, "Loan amount does not match the Vault asset."}; } if (auto const ret = checkFrozen(ctx.view, account, asset)) @@ -415,8 +409,7 @@ LoanPay::doApply() paymentParts->feePaid < 0) { // LCOV_EXCL_START - JLOG(j_.fatal()) << "Loan payment computation returned invalid values."; - return tecLIMIT_EXCEEDED; + return {tecLIMIT_EXCEEDED, "Loan payment computation returned invalid values."}; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/tx/transactors/lending/LoanSet.cpp b/src/libxrpl/tx/transactors/lending/LoanSet.cpp index 694d01c69fd..afea1e85ead 100644 --- a/src/libxrpl/tx/transactors/lending/LoanSet.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanSet.cpp @@ -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) @@ -246,29 +244,27 @@ LoanSet::preclaim(PreclaimContext const& ctx) // mostly so that unit tests can test that specific case. if (grace > timeAvailable) { - JLOG(ctx.j.warn()) << "Grace period exceeds protocol time limit."; - return tecKILLED; + return {tecKILLED, "Grace period exceeds protocol time limit."}; } if (interval > timeAvailable) { - JLOG(ctx.j.warn()) << "Payment interval exceeds protocol time limit."; - return tecKILLED; + return {tecKILLED, "Payment interval exceeds protocol time limit."}; } if (total > timeAvailable) { - JLOG(ctx.j.warn()) << "Payment total exceeds protocol time limit."; - return tecKILLED; + return {tecKILLED, "Payment total exceeds protocol time limit."}; } auto const timeLastPayment = timeAvailable - grace; if (timeLastPayment / interval < total) { - JLOG(ctx.j.warn()) << "Last payment due date, or grace period for " - "last payment exceeds protocol time limit."; - return tecKILLED; + return { + tecKILLED, + "Last payment due date, or grace period for last payment exceeds protocol time " + "limit."}; } } @@ -280,16 +276,14 @@ LoanSet::preclaim(PreclaimContext const& ctx) { // This can only be hit if there's a counterparty specified, otherwise // it'll fail in the signature check - JLOG(ctx.j.warn()) << "LoanBroker does not exist."; - return tecNO_ENTRY; + return {tecNO_ENTRY, "LoanBroker does not exist."}; } auto const brokerOwner = brokerSle->at(sfOwner); auto const counterparty = tx[~sfCounterparty].value_or(brokerOwner); if (account != brokerOwner && counterparty != brokerOwner) { - JLOG(ctx.j.warn()) << "Neither Account nor Counterparty are the owner " - "of the LoanBroker."; - return tecNO_PERMISSION; + return { + tecNO_PERMISSION, "Neither Account nor Counterparty are the owner of the LoanBroker."}; } auto const brokerPseudo = brokerSle->at(sfAccount); @@ -298,8 +292,7 @@ LoanSet::preclaim(PreclaimContext const& ctx) { // It may not be possible to hit this case, because it'll fail the // signature check with terNO_ACCOUNT. - JLOG(ctx.j.warn()) << "Borrower does not exist."; - return terNO_ACCOUNT; + return {terNO_ACCOUNT, "Borrower does not exist."}; } auto const vault = ctx.view.read(keylet::vault(brokerSle->at(sfVaultID))); @@ -311,8 +304,7 @@ LoanSet::preclaim(PreclaimContext const& ctx) if (vault->at(sfAssetsMaximum) != 0 && vault->at(sfAssetsTotal) >= vault->at(sfAssetsMaximum)) { - JLOG(ctx.j.warn()) << "Vault at maximum assets limit. Can't add another loan."; - return tecLIMIT_EXCEEDED; + return {tecLIMIT_EXCEEDED, "Vault at maximum assets limit. Can't add another loan."}; } Asset const asset = vault->at(sfAsset); @@ -415,8 +407,8 @@ LoanSet::doApply() auto const vaultScale = getAssetsTotalScale(vaultSle); if (vaultAvailableProxy < principalRequested) { - JLOG(j_.warn()) << "Insufficient assets available in the Vault to fund the loan."; - return tecINSUFFICIENT_FUNDS; + return { + tecINSUFFICIENT_FUNDS, "Insufficient assets available in the Vault to fund the loan."}; } TenthBips32 const interestRate{tx[~sfInterestRate].value_or(0)}; @@ -446,8 +438,7 @@ LoanSet::doApply() "Vault is below maximum limit"); if (vaultMaximum != 0 && state.interestDue > vaultMaximum - vaultTotalProxy) { - JLOG(j_.warn()) << "Loan would exceed the maximum assets of the vault"; - return tecLIMIT_EXCEEDED; + return {tecLIMIT_EXCEEDED, "Loan would exceed the maximum assets of the vault"}; } // Check that relevant values won't lose precision. This is mostly only // relevant for IOU assets. @@ -495,8 +486,7 @@ LoanSet::doApply() if (auto const debtMaximum = brokerSle->at(sfDebtMaximum); debtMaximum != 0 && debtMaximum < newDebtTotal) { - JLOG(j_.warn()) << "Loan would exceed the maximum debt limit of the LoanBroker."; - return tecLIMIT_EXCEEDED; + return {tecLIMIT_EXCEEDED, "Loan would exceed the maximum debt limit of the LoanBroker."}; } TenthBips32 const coverRateMinimum{brokerSle->at(sfCoverRateMinimum)}; { @@ -514,8 +504,7 @@ LoanSet::doApply() }(); if (brokerSle->at(sfCoverAvailable) < minCover) { - JLOG(j_.warn()) << "Insufficient first-loss capital to cover the loan."; - return tecINSUFFICIENT_FUNDS; + return {tecINSUFFICIENT_FUNDS, "Insufficient first-loss capital to cover the loan."}; } } diff --git a/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp b/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp index b4c12b9514b..270ea231734 100644 --- a/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp +++ b/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include #include @@ -34,16 +34,14 @@ OracleDelete::preclaim(PreclaimContext const& ctx) ctx.view.read(keylet::oracle(ctx.tx.getAccountID(sfAccount), ctx.tx[sfOracleDocumentID])); if (!sle) { - JLOG(ctx.j.debug()) << "Oracle Delete: Oracle does not exist."; - return tecNO_ENTRY; + return {tecNO_ENTRY, "Oracle Delete: Oracle does not exist."}; } if (ctx.tx.getAccountID(sfAccount) != sle->getAccountID(sfOwner)) { // this can't happen because of the above check // LCOV_EXCL_START - JLOG(ctx.j.debug()) << "Oracle Delete: invalid account."; - return tecINTERNAL; + return {tecINTERNAL, "Oracle Delete: invalid account."}; // LCOV_EXCL_STOP } return tesSUCCESS; @@ -62,8 +60,7 @@ OracleDelete::deleteOracle( if (!view.dirRemove(keylet::ownerDir(account), (*sle)[sfOwnerNode], sle->key(), true)) { // LCOV_EXCL_START - JLOG(j.fatal()) << "Unable to delete Oracle from owner."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete Oracle from owner."}; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp b/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp index d3e2af86eff..478fa7fccc9 100644 --- a/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp +++ b/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp @@ -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 @@ -267,8 +268,7 @@ DepositPreauth::removeFromLedger(ApplyView& view, uint256 const& preauthIndex, b auto const slePreauth{view.peek(keylet::depositPreauth(preauthIndex))}; if (!slePreauth) { - JLOG(j.warn()) << "Selected DepositPreauth does not exist."; - return tecNO_ENTRY; + return {tecNO_ENTRY, "Selected DepositPreauth does not exist."}; } AccountID const account{(*slePreauth)[sfAccount]}; @@ -276,8 +276,7 @@ DepositPreauth::removeFromLedger(ApplyView& view, uint256 const& preauthIndex, b if (!view.dirRemove(keylet::ownerDir(account), page, preauthIndex, false)) { // LCOV_EXCL_START - JLOG(j.fatal()) << "Unable to delete DepositPreauth from owner."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete DepositPreauth from owner."}; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/tx/transactors/payment/Payment.cpp b/src/libxrpl/tx/transactors/payment/Payment.cpp index 17c96a1919f..cc652cc06ba 100644 --- a/src/libxrpl/tx/transactors/payment/Payment.cpp +++ b/src/libxrpl/tx/transactors/payment/Payment.cpp @@ -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. @@ -429,9 +424,7 @@ Payment::preclaim(PreclaimContext const& ctx) // We didn't make this test for a newly-formed account because there's // no way for this field to be set. - JLOG(ctx.j.trace()) << "Malformed transaction: DestinationTag required."; - - return tecDST_TAG_NEEDED; + return {tecDST_TAG_NEEDED, "Malformed transaction: DestinationTag required."}; } // Payment with at least one intermediate step and uses transitive balances. diff --git a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp index dc1b3234822..81c3f5c5fcf 100644 --- a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp +++ b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -58,8 +57,7 @@ PermissionedDomainDelete::doApply() if (!view().dirRemove(keylet::ownerDir(accountID_), page, slePd->key(), true)) { // LCOV_EXCL_START - JLOG(j_.fatal()) << "Unable to delete permissioned domain directory entry."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete permissioned domain directory entry."}; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/tx/transactors/sponsor/SponsorshipSet.cpp b/src/libxrpl/tx/transactors/sponsor/SponsorshipSet.cpp index 2b6ab8cf150..fb1bc417e73 100644 --- a/src/libxrpl/tx/transactors/sponsor/SponsorshipSet.cpp +++ b/src/libxrpl/tx/transactors/sponsor/SponsorshipSet.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -182,15 +181,13 @@ deleteSponsorship(ApplyView& view, SLE::ref sle, beast::Journal j) if (!view.dirRemove(keylet::ownerDir(sponsorID), (*sle)[sfOwnerNode], sle->key(), false)) { // LCOV_EXCL_START - JLOG(j.fatal()) << "Unable to delete Sponsorship from sponsor."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete Sponsorship from sponsor."}; // LCOV_EXCL_STOP } if (!view.dirRemove(keylet::ownerDir(sponseeID), (*sle)[sfSponseeNode], sle->key(), false)) { // LCOV_EXCL_START - JLOG(j.fatal()) << "Unable to delete Sponsorship from sponsee."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "Unable to delete Sponsorship from sponsee."}; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/tx/transactors/sponsor/SponsorshipTransfer.cpp b/src/libxrpl/tx/transactors/sponsor/SponsorshipTransfer.cpp index 0e036649fd6..a6b5adc4e72 100644 --- a/src/libxrpl/tx/transactors/sponsor/SponsorshipTransfer.cpp +++ b/src/libxrpl/tx/transactors/sponsor/SponsorshipTransfer.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -102,8 +101,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 +110,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 +134,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 +158,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 +179,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 +194,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; diff --git a/src/libxrpl/tx/transactors/system/Change.cpp b/src/libxrpl/tx/transactors/system/Change.cpp index f27855a5c82..bf8b7e8e057 100644 --- a/src/libxrpl/tx/transactors/system/Change.cpp +++ b/src/libxrpl/tx/transactors/system/Change.cpp @@ -44,29 +44,25 @@ Transactor::invokePreflight(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()) @@ -287,8 +282,7 @@ Change::applyFee() view().update(feeObject); - JLOG(j_.warn()) << "Fees have been changed"; - return tesSUCCESS; + return {tesSUCCESS, "Fees have been changed"}; } TER @@ -304,8 +298,7 @@ Change::applyUNLModify() ctx_.tx.getFieldU8(sfUNLModifyDisabling) > 1 || !ctx_.tx.isFieldPresent(sfLedgerSequence) || !ctx_.tx.isFieldPresent(sfUNLModifyValidator)) { - JLOG(j_.warn()) << "N-UNL: applyUNLModify, wrong Tx format."; - return tefFAILURE; + return {tefFAILURE, "N-UNL: applyUNLModify, wrong Tx format."}; } bool const disabling = ctx_.tx.getFieldU8(sfUNLModifyDisabling) != 0u; @@ -319,8 +312,7 @@ Change::applyUNLModify() Blob const validator = ctx_.tx.getFieldVL(sfUNLModifyValidator); if (!publicKeyType(makeSlice(validator))) { - JLOG(j_.warn()) << "N-UNL: applyUNLModify, bad validator key"; - return tefFAILURE; + return {tefFAILURE, "N-UNL: applyUNLModify, bad validator key"}; } JLOG(j_.info()) << "N-UNL: applyUNLModify, " << (disabling ? "ToDisable" : "ToReEnable") @@ -352,8 +344,7 @@ Change::applyUNLModify() // cannot have more than one toDisable if (negUnlObject->isFieldPresent(sfValidatorToDisable)) { - JLOG(j_.warn()) << "N-UNL: applyUNLModify, already has ToDisable"; - return tefFAILURE; + return {tefFAILURE, "N-UNL: applyUNLModify, already has ToDisable"}; } // cannot be the same as toReEnable @@ -361,16 +352,14 @@ Change::applyUNLModify() { if (negUnlObject->getFieldVL(sfValidatorToReEnable) == validator) { - JLOG(j_.warn()) << "N-UNL: applyUNLModify, ToDisable is same as ToReEnable"; - return tefFAILURE; + return {tefFAILURE, "N-UNL: applyUNLModify, ToDisable is same as ToReEnable"}; } } // cannot be in negative UNL already if (found) { - JLOG(j_.warn()) << "N-UNL: applyUNLModify, ToDisable already in negative UNL"; - return tefFAILURE; + return {tefFAILURE, "N-UNL: applyUNLModify, ToDisable already in negative UNL"}; } negUnlObject->setFieldVL(sfValidatorToDisable, validator); @@ -380,8 +369,7 @@ Change::applyUNLModify() // cannot have more than one toReEnable if (negUnlObject->isFieldPresent(sfValidatorToReEnable)) { - JLOG(j_.warn()) << "N-UNL: applyUNLModify, already has ToReEnable"; - return tefFAILURE; + return {tefFAILURE, "N-UNL: applyUNLModify, already has ToReEnable"}; } // cannot be the same as toDisable @@ -389,16 +377,14 @@ Change::applyUNLModify() { if (negUnlObject->getFieldVL(sfValidatorToDisable) == validator) { - JLOG(j_.warn()) << "N-UNL: applyUNLModify, ToReEnable is same as ToDisable"; - return tefFAILURE; + return {tefFAILURE, "N-UNL: applyUNLModify, ToReEnable is same as ToDisable"}; } } // must be in negative UNL if (!found) { - JLOG(j_.warn()) << "N-UNL: applyUNLModify, ToReEnable is not in negative UNL"; - return tefFAILURE; + return {tefFAILURE, "N-UNL: applyUNLModify, ToReEnable is not in negative UNL"}; } negUnlObject->setFieldVL(sfValidatorToReEnable, validator); diff --git a/src/libxrpl/tx/transactors/token/ConfidentialMPTConvert.cpp b/src/libxrpl/tx/transactors/token/ConfidentialMPTConvert.cpp index 454eb39ead1..3e0c30d1831 100644 --- a/src/libxrpl/tx/transactors/token/ConfidentialMPTConvert.cpp +++ b/src/libxrpl/tx/transactors/token/ConfidentialMPTConvert.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -245,9 +244,8 @@ ConfidentialMPTConvert::doApply() if (!sum) { // LCOV_EXCL_START - JLOG(ctx_.journal.error()) - << "ConfidentialMPTConvert failed homomorphic add for holder inbox."; - return tecINTERNAL; + return { + tecINTERNAL, "ConfidentialMPTConvert failed homomorphic add for holder inbox."}; // LCOV_EXCL_STOP } @@ -260,9 +258,9 @@ ConfidentialMPTConvert::doApply() if (!sum) { // LCOV_EXCL_START - JLOG(ctx_.journal.error()) - << "ConfidentialMPTConvert failed homomorphic add for issuer balance."; - return tecINTERNAL; + return { + tecINTERNAL, + "ConfidentialMPTConvert failed homomorphic add for issuer balance."}; // LCOV_EXCL_STOP } @@ -279,9 +277,9 @@ ConfidentialMPTConvert::doApply() if (!sum) { // LCOV_EXCL_START - JLOG(ctx_.journal.error()) - << "ConfidentialMPTConvert failed homomorphic add for auditor balance."; - return tecINTERNAL; + return { + tecINTERNAL, + "ConfidentialMPTConvert failed homomorphic add for auditor balance."}; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/tx/transactors/token/ConfidentialMPTConvertBack.cpp b/src/libxrpl/tx/transactors/token/ConfidentialMPTConvertBack.cpp index 87f9e476d63..a470250981d 100644 --- a/src/libxrpl/tx/transactors/token/ConfidentialMPTConvertBack.cpp +++ b/src/libxrpl/tx/transactors/token/ConfidentialMPTConvertBack.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -244,10 +243,10 @@ ConfidentialMPTConvertBack::doApply() if (!res) { // LCOV_EXCL_START - JLOG(ctx_.journal.error()) - << "ConfidentialMPTConvertBack failed homomorphic subtract for holder spending " - "balance."; - return tecINTERNAL; + return { + tecINTERNAL, + "ConfidentialMPTConvertBack failed homomorphic subtract for holder spending " + "balance."}; // LCOV_EXCL_STOP } @@ -261,9 +260,9 @@ ConfidentialMPTConvertBack::doApply() if (!res) { // LCOV_EXCL_START - JLOG(ctx_.journal.error()) - << "ConfidentialMPTConvertBack failed homomorphic subtract for issuer balance."; - return tecINTERNAL; + return { + tecINTERNAL, + "ConfidentialMPTConvertBack failed homomorphic subtract for issuer balance."}; // LCOV_EXCL_STOP } @@ -277,9 +276,9 @@ ConfidentialMPTConvertBack::doApply() if (!res) { // LCOV_EXCL_START - JLOG(ctx_.journal.error()) - << "ConfidentialMPTConvertBack failed homomorphic subtract for auditor balance."; - return tecINTERNAL; + return { + tecINTERNAL, + "ConfidentialMPTConvertBack failed homomorphic subtract for auditor balance."}; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/tx/transactors/token/ConfidentialMPTMergeInbox.cpp b/src/libxrpl/tx/transactors/token/ConfidentialMPTMergeInbox.cpp index 0b98382a61c..7a94c3e9b7b 100644 --- a/src/libxrpl/tx/transactors/token/ConfidentialMPTMergeInbox.cpp +++ b/src/libxrpl/tx/transactors/token/ConfidentialMPTMergeInbox.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -100,9 +99,7 @@ ConfidentialMPTMergeInbox::doApply() if (!sum) { // LCOV_EXCL_START - JLOG(ctx_.journal.error()) - << "ConfidentialMPTMergeInbox failed homomorphic add for inbox merge."; - return tecINTERNAL; + return {tecINTERNAL, "ConfidentialMPTMergeInbox failed homomorphic add for inbox merge."}; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/tx/transactors/token/ConfidentialMPTSend.cpp b/src/libxrpl/tx/transactors/token/ConfidentialMPTSend.cpp index d121ec26341..db904c1c60e 100644 --- a/src/libxrpl/tx/transactors/token/ConfidentialMPTSend.cpp +++ b/src/libxrpl/tx/transactors/token/ConfidentialMPTSend.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -306,9 +305,9 @@ ConfidentialMPTSend::doApply() if (!newSpending) { // LCOV_EXCL_START - JLOG(ctx_.journal.error()) - << "ConfidentialMPTSend failed homomorphic subtract for sender spending balance."; - return tecINTERNAL; + return { + tecINTERNAL, + "ConfidentialMPTSend failed homomorphic subtract for sender spending balance."}; // LCOV_EXCL_STOP } @@ -322,9 +321,9 @@ ConfidentialMPTSend::doApply() if (!newIssuerEnc) { // LCOV_EXCL_START - JLOG(ctx_.journal.error()) - << "ConfidentialMPTSend failed homomorphic subtract for sender issuer balance."; - return tecINTERNAL; + return { + tecINTERNAL, + "ConfidentialMPTSend failed homomorphic subtract for sender issuer balance."}; // LCOV_EXCL_STOP } @@ -339,9 +338,9 @@ ConfidentialMPTSend::doApply() if (!newAuditorEnc) { // LCOV_EXCL_START - JLOG(ctx_.journal.error()) - << "ConfidentialMPTSend failed homomorphic subtract for sender auditor balance."; - return tecINTERNAL; + return { + tecINTERNAL, + "ConfidentialMPTSend failed homomorphic subtract for sender auditor balance."}; // LCOV_EXCL_STOP } @@ -360,9 +359,8 @@ ConfidentialMPTSend::doApply() if (!newInbox) { // LCOV_EXCL_START - JLOG(ctx_.journal.error()) - << "ConfidentialMPTSend failed homomorphic add for destination inbox."; - return tecINTERNAL; + return { + tecINTERNAL, "ConfidentialMPTSend failed homomorphic add for destination inbox."}; // LCOV_EXCL_STOP } @@ -381,9 +379,9 @@ ConfidentialMPTSend::doApply() if (!newIssuerEnc) { // LCOV_EXCL_START - JLOG(ctx_.journal.error()) - << "ConfidentialMPTSend failed homomorphic add for destination issuer balance."; - return tecINTERNAL; + return { + tecINTERNAL, + "ConfidentialMPTSend failed homomorphic add for destination issuer balance."}; // LCOV_EXCL_STOP } @@ -403,9 +401,9 @@ ConfidentialMPTSend::doApply() if (!newAuditorEnc) { // LCOV_EXCL_START - JLOG(ctx_.journal.error()) - << "ConfidentialMPTSend failed homomorphic add for destination auditor balance."; - return tecINTERNAL; + return { + tecINTERNAL, + "ConfidentialMPTSend failed homomorphic add for destination auditor balance."}; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/tx/transactors/token/TrustSet.cpp b/src/libxrpl/tx/transactors/token/TrustSet.cpp index 3d078ce825d..e9c77d73d91 100644 --- a/src/libxrpl/tx/transactors/token/TrustSet.cpp +++ b/src/libxrpl/tx/transactors/token/TrustSet.cpp @@ -100,14 +100,12 @@ TrustSet::preflight(PreflightContext const& ctx) if (badCurrency() == saLimitAmount.get().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; @@ -165,8 +162,7 @@ TrustSet::preclaim(PreclaimContext const& ctx) if (bSetAuth && !sle->isFlag(lsfRequireAuth)) { - JLOG(ctx.j.trace()) << "Retry: Auth not required."; - return tefNO_AUTH_REQUIRED; + return {tefNO_AUTH_REQUIRED, "Retry: Auth not required."}; } auto const saLimitAmount = ctx.tx[sfLimitAmount]; @@ -354,8 +350,7 @@ TrustSet::doApply() if (!sleDst) { - JLOG(j_.trace()) << "Delay transaction: Destination account does not exist."; - return tecNO_DST; + return {tecNO_DST, "Delay transaction: Destination account does not exist."}; } STAmount saLimitAllow = saLimitAmount; @@ -683,8 +678,7 @@ TrustSet::doApply() // setting default quality out. (!bSetAuth)) { - JLOG(j_.trace()) << "Redundant: Setting non-existent ripple line to defaults."; - return tecNO_LINE_REDUNDANT; + return {tecNO_LINE_REDUNDANT, "Redundant: Setting non-existent ripple line to defaults."}; } // reserve is not scaled by load else if (!view().rules().enabled(featureSponsor) && preFeeBalance_ < reserveCreate) diff --git a/src/libxrpl/tx/transactors/vault/VaultClawback.cpp b/src/libxrpl/tx/transactors/vault/VaultClawback.cpp index d77286b667b..20717642e7a 100644 --- a/src/libxrpl/tx/transactors/vault/VaultClawback.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultClawback.cpp @@ -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."}; } } @@ -90,8 +88,7 @@ VaultClawback::preclaim(PreclaimContext const& ctx) if (!sleShareIssuance) { // LCOV_EXCL_START - JLOG(ctx.j.error()) << "VaultClawback: missing issuance of vault shares."; - return tefINTERNAL; + return {tefINTERNAL, "VaultClawback: missing issuance of vault shares."}; // LCOV_EXCL_STOP } @@ -100,8 +97,7 @@ VaultClawback::preclaim(PreclaimContext const& ctx) // Ambiguous case: If Issuer is Owner they must specify the asset if (!maybeAmount && !vaultAsset.native() && vaultAsset.getIssuer() == vault->at(sfOwner)) { - JLOG(ctx.j.debug()) << "VaultClawback: must specify amount when issuer is owner."; - return tecWRONG_ASSET; + return {tecWRONG_ASSET, "VaultClawback: must specify amount when issuer is owner."}; } auto const amount = clawbackAmount(vault, maybeAmount, account); @@ -115,8 +111,7 @@ VaultClawback::preclaim(PreclaimContext const& ctx) // Only the Vault Owner may clawback shares if (account != vault->at(sfOwner)) { - JLOG(ctx.j.debug()) << "VaultClawback: only vault owner can clawback shares."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "VaultClawback: only vault owner can clawback shares."}; } auto const assetsTotal = vault->at(sfAssetsTotal); @@ -126,9 +121,9 @@ VaultClawback::preclaim(PreclaimContext const& ctx) // Owner can clawback funds when the vault has shares but no assets if (sharesTotal == 0 || (assetsTotal != 0 || assetsAvailable != 0)) { - JLOG(ctx.j.debug()) << "VaultClawback: vault owner can clawback shares only" - " when vault has no assets."; - return tecNO_PERMISSION; + return { + tecNO_PERMISSION, + "VaultClawback: vault owner can clawback shares only when vault has no assets."}; } // If amount is non-zero, the VaultOwner must burn all shares @@ -145,9 +140,7 @@ VaultClawback::preclaim(PreclaimContext const& ctx) // The VaultOwner must burn all shares if (amount != sharesHeld) { - JLOG(ctx.j.debug()) << "VaultClawback: vault owner must clawback all " - "shares."; - return tecLIMIT_EXCEEDED; + return {tecLIMIT_EXCEEDED, "VaultClawback: vault owner must clawback all shares."}; } } @@ -160,22 +153,19 @@ VaultClawback::preclaim(PreclaimContext const& ctx) // XRP cannot be clawed back if (vaultAsset.native()) { - JLOG(ctx.j.debug()) << "VaultClawback: cannot clawback XRP."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "VaultClawback: cannot clawback XRP."}; } // Only the Asset Issuer may clawback the asset if (account != vaultAsset.getIssuer()) { - JLOG(ctx.j.debug()) << "VaultClawback: only asset issuer can clawback asset."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "VaultClawback: only asset issuer can clawback asset."}; } // The issuer cannot clawback from itself if (account == holder) { - JLOG(ctx.j.debug()) << "VaultClawback: issuer cannot be the holder."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "VaultClawback: issuer cannot be the holder."}; } return vaultAsset.visit( @@ -186,9 +176,7 @@ VaultClawback::preclaim(PreclaimContext const& ctx) if (!mptIssue->isFlag(lsfMPTCanClawback)) { - JLOG(ctx.j.debug()) << "VaultClawback: cannot clawback " - "MPT vault asset."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "VaultClawback: cannot clawback MPT vault asset."}; } return tesSUCCESS; @@ -198,16 +186,13 @@ VaultClawback::preclaim(PreclaimContext const& ctx) if (!issuerSle) { // LCOV_EXCL_START - JLOG(ctx.j.error()) << "VaultClawback: missing submitter account."; - return tefINTERNAL; + return {tefINTERNAL, "VaultClawback: missing submitter account."}; // LCOV_EXCL_STOP } if (!issuerSle->isFlag(lsfAllowTrustLineClawback) || issuerSle->isFlag(lsfNoFreeze)) { - JLOG(ctx.j.debug()) << "VaultClawback: cannot clawback " - "IOU vault asset."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "VaultClawback: cannot clawback IOU vault asset."}; } return tesSUCCESS; @@ -341,8 +326,7 @@ VaultClawback::doApply() if (!sleIssuance) { // LCOV_EXCL_START - JLOG(j_.error()) << "VaultClawback: missing issuance of vault shares."; - return tefINTERNAL; + return {tefINTERNAL, "VaultClawback: missing issuance of vault shares."}; // LCOV_EXCL_STOP } MPTIssue const share{mptIssuanceID}; @@ -440,8 +424,7 @@ VaultClawback::doApply() j_) < beast::kZero) { // LCOV_EXCL_START - JLOG(j_.error()) << "VaultClawback: negative balance of vault assets."; - return tefINTERNAL; + return {tefINTERNAL, "VaultClawback: negative balance of vault assets."}; // LCOV_EXCL_STOP } } diff --git a/src/libxrpl/tx/transactors/vault/VaultDelete.cpp b/src/libxrpl/tx/transactors/vault/VaultDelete.cpp index 497a2f24654..27e101f930a 100644 --- a/src/libxrpl/tx/transactors/vault/VaultDelete.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultDelete.cpp @@ -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)) @@ -48,20 +47,17 @@ VaultDelete::preclaim(PreclaimContext const& ctx) if (vault->at(sfOwner) != ctx.tx[sfAccount]) { - JLOG(ctx.j.debug()) << "VaultDelete: account is not an owner."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "VaultDelete: account is not an owner."}; } if (vault->at(sfAssetsAvailable) != 0) { - JLOG(ctx.j.debug()) << "VaultDelete: nonzero assets available."; - return tecHAS_OBLIGATIONS; + return {tecHAS_OBLIGATIONS, "VaultDelete: nonzero assets available."}; } if (vault->at(sfAssetsTotal) != 0) { - JLOG(ctx.j.debug()) << "VaultDelete: nonzero assets total."; - return tecHAS_OBLIGATIONS; + return {tecHAS_OBLIGATIONS, "VaultDelete: nonzero assets total."}; } // Verify we can destroy MPTokenIssuance @@ -70,23 +66,20 @@ VaultDelete::preclaim(PreclaimContext const& ctx) if (!sleMPT) { // LCOV_EXCL_START - JLOG(ctx.j.error()) << "VaultDelete: missing issuance of vault shares."; - return tecOBJECT_NOT_FOUND; + return {tecOBJECT_NOT_FOUND, "VaultDelete: missing issuance of vault shares."}; // LCOV_EXCL_STOP } if (sleMPT->at(sfIssuer) != vault->getAccountID(sfAccount)) { // LCOV_EXCL_START - JLOG(ctx.j.error()) << "VaultDelete: invalid owner of vault shares."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "VaultDelete: invalid owner of vault shares."}; // LCOV_EXCL_STOP } if (sleMPT->at(sfOutstandingAmount) != 0) { - JLOG(ctx.j.debug()) << "VaultDelete: nonzero outstanding shares."; - return tecHAS_OBLIGATIONS; + return {tecHAS_OBLIGATIONS, "VaultDelete: nonzero outstanding shares."}; } return tesSUCCESS; @@ -112,8 +105,7 @@ VaultDelete::doApply() if (!pseudoAcct) { // LCOV_EXCL_START - JLOG(j_.error()) << "VaultDelete: missing vault pseudo-account."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "VaultDelete: missing vault pseudo-account."}; // LCOV_EXCL_STOP } @@ -124,8 +116,7 @@ VaultDelete::doApply() if (!mpt) { // LCOV_EXCL_START - JLOG(j_.error()) << "VaultDelete: missing issuance of vault shares."; - return tefINTERNAL; + return {tefINTERNAL, "VaultDelete: missing issuance of vault shares."}; // LCOV_EXCL_STOP } @@ -150,8 +141,7 @@ VaultDelete::doApply() if (!view().dirRemove(keylet::ownerDir(pseudoID), (*mpt)[sfOwnerNode], mpt->key(), false)) { // LCOV_EXCL_START - JLOG(j_.error()) << "VaultDelete: failed to delete issuance object."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "VaultDelete: failed to delete issuance object."}; // LCOV_EXCL_STOP } decreaseOwnerCountForObject(view(), pseudoAcct, mpt, 1, j_); @@ -172,22 +162,19 @@ VaultDelete::doApply() if (*vaultPseudoSLE->at(sfBalance)) { // LCOV_EXCL_START - JLOG(j_.error()) << "VaultDelete: pseudo-account has a balance"; - return tecHAS_OBLIGATIONS; + return {tecHAS_OBLIGATIONS, "VaultDelete: pseudo-account has a balance"}; // LCOV_EXCL_STOP } if (vaultPseudoSLE->at(sfOwnerCount) != 0) { // LCOV_EXCL_START - JLOG(j_.error()) << "VaultDelete: pseudo-account still owns objects"; - return tecHAS_OBLIGATIONS; + return {tecHAS_OBLIGATIONS, "VaultDelete: pseudo-account still owns objects"}; // LCOV_EXCL_STOP } if (view().exists(keylet::ownerDir(pseudoID))) { // LCOV_EXCL_START - JLOG(j_.error()) << "VaultDelete: pseudo-account has a directory"; - return tecHAS_OBLIGATIONS; + return {tecHAS_OBLIGATIONS, "VaultDelete: pseudo-account has a directory"}; // LCOV_EXCL_STOP } @@ -198,8 +185,7 @@ VaultDelete::doApply() if (!view().dirRemove(keylet::ownerDir(ownerID), vault->at(sfOwnerNode), vault->key(), false)) { // LCOV_EXCL_START - JLOG(j_.error()) << "VaultDelete: failed to delete vault object."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "VaultDelete: failed to delete vault object."}; // LCOV_EXCL_STOP } @@ -207,8 +193,7 @@ VaultDelete::doApply() if (!owner) { // LCOV_EXCL_START - JLOG(j_.error()) << "VaultDelete: missing vault owner account."; - return tefBAD_LEDGER; + return {tefBAD_LEDGER, "VaultDelete: missing vault owner account."}; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp b/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp index aa9cfc8537b..c6d0b785a5b 100644 --- a/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp @@ -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) @@ -80,8 +79,7 @@ VaultDeposit::preclaim(PreclaimContext const& ctx) auto const& vaultAccount = vault->at(sfAccount); if (auto ter = canTransfer(ctx.view, vaultAsset, account, vaultAccount); !isTesSuccess(ter)) { - JLOG(ctx.j.debug()) << "VaultDeposit: vault assets are non-transferable."; - return ter; + return {ter, "VaultDeposit: vault assets are non-transferable."}; } auto const mptIssuanceID = vault->at(sfShareMPTID); @@ -89,8 +87,7 @@ VaultDeposit::preclaim(PreclaimContext const& ctx) if (vaultShare == amount.asset()) { // LCOV_EXCL_START - JLOG(ctx.j.error()) << "VaultDeposit: vault shares and assets cannot be same."; - return tefINTERNAL; + return {tefINTERNAL, "VaultDeposit: vault shares and assets cannot be same."}; // LCOV_EXCL_STOP } @@ -98,16 +95,14 @@ VaultDeposit::preclaim(PreclaimContext const& ctx) if (!sleIssuance) { // LCOV_EXCL_START - JLOG(ctx.j.error()) << "VaultDeposit: missing issuance of vault shares."; - return tefINTERNAL; + return {tefINTERNAL, "VaultDeposit: missing issuance of vault shares."}; // LCOV_EXCL_STOP } if (sleIssuance->isFlag(lsfMPTLocked)) { // LCOV_EXCL_START - JLOG(ctx.j.error()) << "VaultDeposit: issuance of vault shares is locked."; - return tefINTERNAL; + return {tefINTERNAL, "VaultDeposit: issuance of vault shares is locked."}; // LCOV_EXCL_STOP } @@ -222,8 +217,7 @@ VaultDeposit::doApply() if (!sleIssuance) { // LCOV_EXCL_START - JLOG(j_.error()) << "VaultDeposit: missing issuance of vault shares."; - return tefINTERNAL; + return {tefINTERNAL, "VaultDeposit: missing issuance of vault shares."}; // LCOV_EXCL_STOP } @@ -292,8 +286,7 @@ VaultDeposit::doApply() if (*maybeAssets > amount) { // LCOV_EXCL_START - JLOG(j_.error()) << "VaultDeposit: would take more than offered."; - return tecINTERNAL; + return {tecINTERNAL, "VaultDeposit: would take more than offered."}; // LCOV_EXCL_STOP } assetsDeposited = *maybeAssets; @@ -346,8 +339,7 @@ VaultDeposit::doApply() AuthHandling::IgnoreAuth, j_) < beast::kZero) { - JLOG(j_.error()) << "VaultDeposit: negative balance of account assets."; - return tefINTERNAL; + return {tefINTERNAL, "VaultDeposit: negative balance of account assets."}; } } diff --git a/src/libxrpl/tx/transactors/vault/VaultSet.cpp b/src/libxrpl/tx/transactors/vault/VaultSet.cpp index c71e84858a4..1df6f2d1d4f 100644 --- a/src/libxrpl/tx/transactors/vault/VaultSet.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultSet.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include #include @@ -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; @@ -70,8 +66,7 @@ VaultSet::preclaim(PreclaimContext const& ctx) // Assert that submitter is the Owner. if (ctx.tx[sfAccount] != vault->at(sfOwner)) { - JLOG(ctx.j.debug()) << "VaultSet: account is not an owner."; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "VaultSet: account is not an owner."}; } auto const mptIssuanceID = (*vault)[sfShareMPTID]; @@ -79,8 +74,7 @@ VaultSet::preclaim(PreclaimContext const& ctx) if (!sleIssuance) { // LCOV_EXCL_START - JLOG(ctx.j.error()) << "VaultSet: missing issuance of vault shares."; - return tefINTERNAL; + return {tefINTERNAL, "VaultSet: missing issuance of vault shares."}; // LCOV_EXCL_STOP } @@ -89,8 +83,7 @@ VaultSet::preclaim(PreclaimContext const& ctx) // We can only set domain if private flag was originally set if (!vault->isFlag(lsfVaultPrivate)) { - JLOG(ctx.j.debug()) << "VaultSet: vault is not private"; - return tecNO_PERMISSION; + return {tecNO_PERMISSION, "VaultSet: vault is not private"}; } if (*domain != beast::kZero) @@ -104,8 +97,7 @@ VaultSet::preclaim(PreclaimContext const& ctx) if (!sleIssuance->isFlag(lsfMPTRequireAuth)) { // LCOV_EXCL_START - JLOG(ctx.j.error()) << "VaultSet: issuance of vault shares is not private."; - return tefINTERNAL; + return {tefINTERNAL, "VaultSet: issuance of vault shares is not private."}; // LCOV_EXCL_STOP } } @@ -134,8 +126,7 @@ VaultSet::doApply() if (!sleIssuance) { // LCOV_EXCL_START - JLOG(j_.error()) << "VaultSet: missing issuance of vault shares."; - return tefINTERNAL; + return {tefINTERNAL, "VaultSet: missing issuance of vault shares."}; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp b/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp index 353b72c30d1..ff8fb942f45 100644 --- a/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp @@ -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) @@ -90,16 +89,14 @@ VaultWithdraw::preclaim(PreclaimContext const& ctx) if (auto ter = canTransfer(ctx.view, vaultAsset, vaultAccount, dstAcct, waive); !isTesSuccess(ter)) { - JLOG(ctx.j.debug()) << "VaultWithdraw: vault assets are non-transferable."; - return ter; + return {ter, "VaultWithdraw: vault assets are non-transferable."}; } // Enforce valid withdrawal policy if (vault->at(sfWithdrawalPolicy) != kVaultStrategyFirstComeFirstServe) { // LCOV_EXCL_START - JLOG(ctx.j.error()) << "VaultWithdraw: invalid withdrawal policy."; - return tefINTERNAL; + return {tefINTERNAL, "VaultWithdraw: invalid withdrawal policy."}; // LCOV_EXCL_STOP } @@ -113,8 +110,7 @@ VaultWithdraw::preclaim(PreclaimContext const& ctx) if (!sleIssuance) { // LCOV_EXCL_START - JLOG(ctx.j.error()) << "VaultWithdraw: missing issuance of vault shares."; - return tefINTERNAL; + return {tefINTERNAL, "VaultWithdraw: missing issuance of vault shares."}; // LCOV_EXCL_STOP } @@ -203,8 +199,7 @@ VaultWithdraw::doApply() if (!sleIssuance) { // LCOV_EXCL_START - JLOG(j_.error()) << "VaultWithdraw: missing issuance of vault shares."; - return tefINTERNAL; + return {tefINTERNAL, "VaultWithdraw: missing issuance of vault shares."}; // LCOV_EXCL_STOP } @@ -283,8 +278,7 @@ VaultWithdraw::doApply() if (accountHolds(view(), accountID_, share, freezeHandling, AuthHandling::IgnoreAuth, j_) < sharesRedeemed) { - JLOG(j_.debug()) << "VaultWithdraw: account doesn't hold enough shares"; - return tecINSUFFICIENT_FUNDS; + return {tecINSUFFICIENT_FUNDS, "VaultWithdraw: account doesn't hold enough shares"}; } auto assetsAvailable = vault->at(sfAssetsAvailable); @@ -297,8 +291,7 @@ VaultWithdraw::doApply() // The vault must have enough assets on hand. if (*assetsAvailable < assetsWithdrawn) { - JLOG(j_.debug()) << "VaultWithdraw: vault doesn't hold enough assets"; - return tecINSUFFICIENT_FUNDS; + return {tecINSUFFICIENT_FUNDS, "VaultWithdraw: vault doesn't hold enough assets"}; } // Post-fixCleanup3_2_0 "final withdrawal" rule: diff --git a/src/test/protocol/TER_test.cpp b/src/test/protocol/TER_test.cpp index 77f12ff2b70..c956ac94c35 100644 --- a/src/test/protocol/TER_test.cpp +++ b/src/test/protocol/TER_test.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace xrpl { @@ -235,12 +236,52 @@ struct TER_test : public beast::unit_test::Suite testIterate(kTers, *this); } + void + testReason() + { + testcase("Reason"); + + // 1. Implicit conversion from enum uses transHuman + { + TER const t = tecNO_DST; + BEAST_EXPECT(t.code == tecNO_DST); + BEAST_EXPECT(t.reason == transHuman(TERRaw{tecNO_DST})); + } + + // 2. Explicit reason + { + TER const t = {tecNO_DST, "custom reason"}; + BEAST_EXPECT(t.code == tecNO_DST); + BEAST_EXPECT(t.reason == "custom reason"); + } + + // 3. Default constructor uses tesSUCCESS description + { + TER const t; + BEAST_EXPECT(t.code == tesSUCCESS); + BEAST_EXPECT(t.reason == transHuman(TERRaw{tesSUCCESS})); + } + + // 4. Copy and move + { + TER t1 = {tecPATH_DRY, "reason 1"}; + TER const t2 = t1; + BEAST_EXPECT(t2.code == tecPATH_DRY); + BEAST_EXPECT(t2.reason == "reason 1"); + + TER const t3 = std::move(t1); + BEAST_EXPECT(t3.code == tecPATH_DRY); + BEAST_EXPECT(t3.reason == "reason 1"); + } + } + void run() override { testTransResultInfo(); testConversion(); testComparison(); + testReason(); } }; diff --git a/src/test/rpc/Simulate_test.cpp b/src/test/rpc/Simulate_test.cpp index 16df733a666..e821b9af014 100644 --- a/src/test/rpc/Simulate_test.cpp +++ b/src/test/rpc/Simulate_test.cpp @@ -56,6 +56,7 @@ class Simulate_test : public beast::unit_test::Suite BEAST_EXPECT(result.isMember(jss::engine_result)); BEAST_EXPECT(result.isMember(jss::engine_result_code)); BEAST_EXPECT(result.isMember(jss::engine_result_message)); + BEAST_EXPECT(result.isMember(jss::engine_result_reason)); BEAST_EXPECT(result.isMember(jss::tx_json) || result.isMember(jss::tx_blob)); json::Value txJson; @@ -681,6 +682,8 @@ class Simulate_test : public beast::unit_test::Suite BEAST_EXPECT(result[jss::engine_result] == "temBAD_AMOUNT"); BEAST_EXPECT(result[jss::engine_result_code] == -298); BEAST_EXPECT(result[jss::engine_result_message] == "Malformed: Bad amount."); + // No custom reason was set; reason falls back to the default transHuman string. + BEAST_EXPECT(result[jss::engine_result_reason] == "Malformed: Bad amount."); BEAST_EXPECT(!result.isMember(jss::meta) && !result.isMember(jss::meta_blob)); }; @@ -727,6 +730,10 @@ class Simulate_test : public beast::unit_test::Suite "Destination does not exist. Too little XRP sent to " "create " "it."); + // No custom reason was set; reason falls back to the default transHuman string. + BEAST_EXPECT( + result[jss::engine_result_reason] == + "Destination does not exist. Too little XRP sent to create it."); if (BEAST_EXPECT(result.isMember(jss::meta) || result.isMember(jss::meta_blob))) { @@ -772,6 +779,39 @@ class Simulate_test : public beast::unit_test::Suite // test without autofill testTx(env, tx, testSimulation); } + + // tecDST_TAG_NEEDED: custom reason set by transactor differs from + // the static transHuman message ("A destination tag is required."). + { + env.fund(XRP(10000), alice); + env(fset(alice, asfRequireDest)); + env.close(); + + std::function const& testSimulation = + [&](json::Value const& resp, json::Value const& tx) { + auto result = resp[jss::result]; + checkBasicReturnValidity( + result, tx, env.seq(env.master), env.current()->fees().base); + + BEAST_EXPECT(result[jss::engine_result] == "tecDST_TAG_NEEDED"); + BEAST_EXPECT(result[jss::engine_result_code] == 143); + // engine_result_message is the static transHuman string. + BEAST_EXPECT( + result[jss::engine_result_message] == "A destination tag is required."); + // engine_result_reason carries the custom string from the transactor. + BEAST_EXPECT( + result[jss::engine_result_reason] == + "Malformed transaction: DestinationTag required."); + }; + + json::Value tx; + tx[jss::Account] = env.master.human(); + tx[jss::TransactionType] = jss::Payment; + tx[sfDestination] = alice.human(); + tx[sfAmount] = "100000000"; // 100 XRP in drops + + testTx(env, tx, testSimulation); + } } void diff --git a/src/xrpld/app/misc/NetworkOPs.cpp b/src/xrpld/app/misc/NetworkOPs.cpp index 4b0091dff6f..b0f55e2d9f3 100644 --- a/src/xrpld/app/misc/NetworkOPs.cpp +++ b/src/xrpld/app/misc/NetworkOPs.cpp @@ -3321,6 +3321,7 @@ NetworkOPsImp::transJson( jvObj[jss::engine_result] = sToken; jvObj[jss::engine_result_code] = result; jvObj[jss::engine_result_message] = sHuman; + jvObj[jss::engine_result_reason] = result.reason; if (transaction->getTxnType() == ttOFFER_CREATE) { diff --git a/src/xrpld/app/misc/TxQ.h b/src/xrpld/app/misc/TxQ.h index 65b4e9778c4..71a653df924 100644 --- a/src/xrpld/app/misc/TxQ.h +++ b/src/xrpld/app/misc/TxQ.h @@ -251,8 +251,8 @@ class TxQ , seqProxy(seqProxy) , txn(txn) , retriesRemaining(retriesRemaining) - , preflightResult(preflightResult) - , lastResult(lastResult) + , preflightResult(std::move(preflightResult)) + , lastResult(std::move(lastResult)) { } diff --git a/src/xrpld/rpc/detail/TransactionSign.cpp b/src/xrpld/rpc/detail/TransactionSign.cpp index e1c5180b5c8..ceaad9ab235 100644 --- a/src/xrpld/rpc/detail/TransactionSign.cpp +++ b/src/xrpld/rpc/detail/TransactionSign.cpp @@ -804,6 +804,7 @@ transactionFormatResultImpl(Transaction::pointer tpTrans, unsigned apiVersion) jvResult[jss::engine_result] = sToken; jvResult[jss::engine_result_code] = tpTrans->getResult(); jvResult[jss::engine_result_message] = sHuman; + jvResult[jss::engine_result_reason] = tpTrans->getResult().reason; } } catch (std::exception&) diff --git a/src/xrpld/rpc/handlers/transaction/Simulate.cpp b/src/xrpld/rpc/handlers/transaction/Simulate.cpp index 0f163c7356e..f52720b3767 100644 --- a/src/xrpld/rpc/handlers/transaction/Simulate.cpp +++ b/src/xrpld/rpc/handlers/transaction/Simulate.cpp @@ -264,6 +264,7 @@ simulateTxn(RPC::JsonContext& context, std::shared_ptr transaction) jvResult[jss::engine_result] = token; jvResult[jss::engine_result_code] = result.ter; jvResult[jss::engine_result_message] = message; + jvResult[jss::engine_result_reason] = result.ter.reason; } else { @@ -272,6 +273,7 @@ simulateTxn(RPC::JsonContext& context, std::shared_ptr transaction) jvResult[jss::engine_result] = "unknown"; jvResult[jss::engine_result_code] = result.ter; jvResult[jss::engine_result_message] = "unknown"; + jvResult[jss::engine_result_reason] = "unknown"; // LCOV_EXCL_STOP } diff --git a/src/xrpld/rpc/handlers/transaction/Submit.cpp b/src/xrpld/rpc/handlers/transaction/Submit.cpp index 79f36806844..769c75799cd 100644 --- a/src/xrpld/rpc/handlers/transaction/Submit.cpp +++ b/src/xrpld/rpc/handlers/transaction/Submit.cpp @@ -154,6 +154,7 @@ doSubmit(RPC::JsonContext& context) jvResult[jss::engine_result] = sToken; jvResult[jss::engine_result_code] = transaction->getResult(); jvResult[jss::engine_result_message] = sHuman; + jvResult[jss::engine_result_reason] = transaction->getResult().reason; auto const submitResult = transaction->getSubmitResult();