mirror of
https://github.com/XRPLF/rippled.git
synced 2026-10-21 19:18:22 +00:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84c47bb55e | ||
|
|
5c64d9f7c0 | ||
|
|
b765e78e94 | ||
|
|
2c69d58f26 | ||
|
|
445574089f | ||
|
|
b5bd12dec0 | ||
|
|
2da94043f2 | ||
|
|
0621841912 |
No files matched your search
+153
-16
@@ -604,7 +604,7 @@ class CanCvtToNotTEC<TEScodes> : public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
using NotTEC = TERSubset<CanCvtToNotTEC>;
|
||||
using NotTECRaw = TERSubset<CanCvtToNotTEC>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -639,48 +639,188 @@ class CanCvtToTER<TECcodes> : public std::true_type
|
||||
{
|
||||
};
|
||||
template <>
|
||||
class CanCvtToTER<NotTECRaw> : public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
// TERRaw allows all of the subsets (the plain numeric code, no reason string).
|
||||
using TERRaw = TERSubset<CanCvtToTER>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// 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<RawType, Trait>: 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 <typename RawType, template <typename> 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 <typename T>
|
||||
TERBase(T c) // NOLINT(google-explicit-constructor)
|
||||
requires(Trait<std::remove_cv_t<std::remove_reference_t<T>>>::value)
|
||||
: code(c), reason(transHuman(TERRaw{code}))
|
||||
{
|
||||
}
|
||||
|
||||
// With explicit reason.
|
||||
template <typename T>
|
||||
TERBase(T c, std::string r)
|
||||
requires(Trait<std::remove_cv_t<std::remove_reference_t<T>>>::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 <typename OtherRaw, template <typename> class OtherTrait>
|
||||
TERBase(TERBase<OtherRaw, OtherTrait> const& other) // NOLINT(google-explicit-constructor)
|
||||
requires(Trait<OtherRaw>::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<bool>(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<TERRaw, CanCvtToTER>;
|
||||
|
||||
// NotTEC – result code for preflight functions (tel*, tem*, tef*, ter*, tes*;
|
||||
// excludes tec* to prevent fee charging without a valid signature).
|
||||
using NotTEC = TERBase<NotTECRaw, CanCvtToNotTEC>;
|
||||
|
||||
// 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<NotTEC> : public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
// TER allows all of the subsets.
|
||||
using TER = TERSubset<CanCvtToTER>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
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<TERUnderlyingType, std::pair<char const* const, char const* c
|
||||
transResults();
|
||||
|
||||
bool
|
||||
transResultInfo(TER code, std::string& token, std::string& text);
|
||||
transResultInfo(TERRaw code, std::string& token, std::string& text);
|
||||
|
||||
std::string
|
||||
transToken(TER code);
|
||||
|
||||
std::string
|
||||
transHuman(TER code);
|
||||
transToken(TERRaw code);
|
||||
|
||||
std::optional<TER>
|
||||
transCode(std::string const& token);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: registry(registry)
|
||||
, view(view)
|
||||
, preflightResult(preflightResult)
|
||||
, preflightResult(std::move(preflightResult))
|
||||
, flags(flags)
|
||||
, tx(tx)
|
||||
, parentBatchId(parentBatchId)
|
||||
|
||||
@@ -28,7 +28,7 @@ struct ApplyResult
|
||||
std::optional<TxMeta> metadata;
|
||||
|
||||
ApplyResult(TER t, bool a, std::optional<TxMeta> m = std::nullopt)
|
||||
: ter(t), applied(a), metadata(std::move(m))
|
||||
: ter(std::move(t)), applied(a), metadata(std::move(m))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -825,14 +825,12 @@ DirectStepI<TDerived>::check(StrandContext const& ctx) const
|
||||
// The following checks apply for both payments and offer crossing.
|
||||
if (!src_ || !dst_)
|
||||
{
|
||||
JLOG(j_.debug()) << "DirectStepI: specified bad account.";
|
||||
return temBAD_PATH;
|
||||
return {temBAD_PATH, "DirectStepI: specified bad account."};
|
||||
}
|
||||
|
||||
if (src_ == dst_)
|
||||
{
|
||||
JLOG(j_.debug()) << "DirectStepI: same src and dst.";
|
||||
return temBAD_PATH;
|
||||
return {temBAD_PATH, "DirectStepI: same src and dst."};
|
||||
}
|
||||
|
||||
auto const sleSrc = ctx.view.read(keylet::account(src_));
|
||||
|
||||
@@ -823,14 +823,12 @@ MPTEndpointStep<TDerived>::check(StrandContext const& ctx) const
|
||||
// The following checks apply for both payments and offer crossing.
|
||||
if (!src_ || !dst_)
|
||||
{
|
||||
JLOG(j_.debug()) << "MPTEndpointStep: specified bad account.";
|
||||
return temBAD_PATH;
|
||||
return {temBAD_PATH, "MPTEndpointStep: specified bad account."};
|
||||
}
|
||||
|
||||
if (src_ == dst_)
|
||||
{
|
||||
JLOG(j_.debug()) << "MPTEndpointStep: same src and dst.";
|
||||
return temBAD_PATH;
|
||||
return {temBAD_PATH, "MPTEndpointStep: same src and dst."};
|
||||
}
|
||||
|
||||
auto const sleSrc = ctx.view.read(keylet::account(src_));
|
||||
@@ -885,15 +883,13 @@ MPTEndpointStep<TDerived>::check(StrandContext const& ctx) const
|
||||
// MPT can only be an endpoint
|
||||
if (!ctx.isLast && !ctx.isFirst)
|
||||
{
|
||||
JLOG(j_.warn()) << "MPTEndpointStep: MPT can only be an endpoint";
|
||||
return temBAD_PATH;
|
||||
return {temBAD_PATH, "MPTEndpointStep: MPT can only be an endpoint"};
|
||||
}
|
||||
|
||||
auto const& issuer = mptIssue_.getIssuer();
|
||||
if ((src_ != issuer && dst_ != issuer) || (src_ == issuer && dst_ == issuer))
|
||||
{
|
||||
JLOG(j_.warn()) << "MPTEndpointStep: invalid src/dst";
|
||||
return temBAD_PATH;
|
||||
return {temBAD_PATH, "MPTEndpointStep: invalid src/dst"};
|
||||
}
|
||||
|
||||
return static_cast<TDerived const*>(this)->check(ctx, sleSrc);
|
||||
|
||||
@@ -338,8 +338,7 @@ XRPEndpointStep<TDerived>::check(StrandContext const& ctx) const
|
||||
{
|
||||
if (!acc_)
|
||||
{
|
||||
JLOG(j_.debug()) << "XRPEndpointStep: specified bad account.";
|
||||
return temBAD_PATH;
|
||||
return {temBAD_PATH, "XRPEndpointStep: specified bad account."};
|
||||
}
|
||||
|
||||
auto sleAcc = ctx.view.read(keylet::account(acc_));
|
||||
|
||||
@@ -63,15 +63,13 @@ NotTEC
|
||||
AccountSet::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
auto& tx = ctx.tx;
|
||||
auto& j = ctx.j;
|
||||
|
||||
std::uint32_t const uSetFlag = tx.getFieldU32(sfSetFlag);
|
||||
std::uint32_t const uClearFlag = tx.getFieldU32(sfClearFlag);
|
||||
|
||||
if ((uSetFlag != 0) && (uSetFlag == uClearFlag))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Set and clear same flag.";
|
||||
return temINVALID_FLAG;
|
||||
return {temINVALID_FLAG, "Malformed transaction: Set and clear same flag."};
|
||||
}
|
||||
|
||||
//
|
||||
@@ -82,8 +80,7 @@ AccountSet::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (bSetRequireAuth && bClearRequireAuth)
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Contradictory flags set.";
|
||||
return temINVALID_FLAG;
|
||||
return {temINVALID_FLAG, "Malformed transaction: Contradictory flags set."};
|
||||
}
|
||||
|
||||
//
|
||||
@@ -94,8 +91,7 @@ AccountSet::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (bSetRequireDest && bClearRequireDest)
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Contradictory flags set.";
|
||||
return temINVALID_FLAG;
|
||||
return {temINVALID_FLAG, "Malformed transaction: Contradictory flags set."};
|
||||
}
|
||||
|
||||
//
|
||||
@@ -106,8 +102,7 @@ AccountSet::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (bSetDisallowXRP && bClearDisallowXRP)
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Contradictory flags set.";
|
||||
return temINVALID_FLAG;
|
||||
return {temINVALID_FLAG, "Malformed transaction: Contradictory flags set."};
|
||||
}
|
||||
|
||||
// TransferRate
|
||||
@@ -117,14 +112,12 @@ AccountSet::preflight(PreflightContext const& ctx)
|
||||
|
||||
if ((uRate != 0u) && (uRate < QUALITY_ONE))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Transfer rate too small.";
|
||||
return temBAD_TRANSFER_RATE;
|
||||
return {temBAD_TRANSFER_RATE, "Malformed transaction: Transfer rate too small."};
|
||||
}
|
||||
|
||||
if (uRate > 2 * QUALITY_ONE)
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Transfer rate too large.";
|
||||
return temBAD_TRANSFER_RATE;
|
||||
return {temBAD_TRANSFER_RATE, "Malformed transaction: Transfer rate too large."};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,8 +128,7 @@ AccountSet::preflight(PreflightContext const& ctx)
|
||||
if ((uTickSize != 0u) &&
|
||||
((uTickSize < Quality::kMinTickSize) || (uTickSize > Quality::kMaxTickSize)))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Bad tick size.";
|
||||
return temBAD_TICK_SIZE;
|
||||
return {temBAD_TICK_SIZE, "Malformed transaction: Bad tick size."};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,15 +136,13 @@ AccountSet::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (!mk->empty() && !publicKeyType({mk->data(), mk->size()}))
|
||||
{
|
||||
JLOG(j.trace()) << "Invalid message key specified.";
|
||||
return telBAD_PUBLIC_KEY;
|
||||
return {telBAD_PUBLIC_KEY, "Invalid message key specified."};
|
||||
}
|
||||
}
|
||||
|
||||
if (auto const domain = tx[~sfDomain]; domain && domain->size() > kMaxDomainLength)
|
||||
{
|
||||
JLOG(j.trace()) << "domain too long";
|
||||
return telBAD_DOMAIN;
|
||||
return {telBAD_DOMAIN, "domain too long"};
|
||||
}
|
||||
|
||||
// Configure authorized minting account:
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/check/CheckCancel.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,9 +61,9 @@ CheckCash::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (static_cast<bool>(optAmount) == static_cast<bool>(optDeliverMin))
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Malformed transaction: "
|
||||
"does not specify exactly one of Amount and DeliverMin.";
|
||||
return temMALFORMED;
|
||||
return {
|
||||
temMALFORMED,
|
||||
"Malformed transaction: does not specify exactly one of Amount and DeliverMin."};
|
||||
}
|
||||
|
||||
// Make sure the amount is valid.
|
||||
@@ -76,8 +76,7 @@ CheckCash::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (badAsset() == value.asset())
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Malformed transaction: Bad currency.";
|
||||
return temBAD_CURRENCY;
|
||||
return {temBAD_CURRENCY, "Malformed transaction: Bad currency."};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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<TER> {
|
||||
@@ -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<TER> {
|
||||
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;
|
||||
|
||||
@@ -36,15 +36,13 @@ CredentialAccept::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (!ctx.tx[sfIssuer])
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Malformed transaction: Issuer field zeroed.";
|
||||
return temINVALID_ACCOUNT_ID;
|
||||
return {temINVALID_ACCOUNT_ID, "Malformed transaction: Issuer field zeroed."};
|
||||
}
|
||||
|
||||
auto const credType = ctx.tx[sfCredentialType];
|
||||
if (credType.empty() || (credType.size() > kMaxCredentialTypeLength))
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Malformed transaction: invalid size of CredentialType.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "Malformed transaction: invalid size of CredentialType."};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -53,26 +53,22 @@ NotTEC
|
||||
CredentialCreate::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
auto const& tx = ctx.tx;
|
||||
auto& j = ctx.j;
|
||||
|
||||
if (!tx[sfSubject])
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Invalid Subject";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "Malformed transaction: Invalid Subject"};
|
||||
}
|
||||
|
||||
auto const uri = tx[~sfURI];
|
||||
if (uri && (uri->empty() || (uri->size() > kMaxCredentialUriLength)))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: invalid size of URI.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "Malformed transaction: invalid size of URI."};
|
||||
}
|
||||
|
||||
auto const credType = tx[sfCredentialType];
|
||||
if (credType.empty() || (credType.size() > kMaxCredentialTypeLength))
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: invalid size of CredentialType.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "Malformed transaction: invalid size of CredentialType."};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -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);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/credentials/CredentialDelete.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
@@ -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_);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/delegate/DelegateSet.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -59,8 +59,7 @@ AMMClawback::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (issuer == holder)
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "AMMClawback: holder cannot be the same as issuer.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "AMMClawback: holder cannot be the same as issuer."};
|
||||
}
|
||||
|
||||
std::optional<STAmount> const clawAmount = ctx.tx[~sfAmount];
|
||||
@@ -72,23 +71,20 @@ AMMClawback::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (ctx.tx.isFlag(tfClawTwoAssets) && asset.getIssuer() != asset2.getIssuer())
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "AMMClawback: tfClawTwoAssets can only be enabled when two "
|
||||
"assets in the AMM pool are both issued by the issuer";
|
||||
return temINVALID_FLAG;
|
||||
return {
|
||||
temINVALID_FLAG,
|
||||
"AMMClawback: tfClawTwoAssets can only be enabled when two assets in the AMM pool are "
|
||||
"both issued by the issuer"};
|
||||
}
|
||||
|
||||
if (asset.getIssuer() != issuer)
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "AMMClawback: Asset's account does not "
|
||||
"match Account field.";
|
||||
return temMALFORMED;
|
||||
return {temMALFORMED, "AMMClawback: Asset's account does not match Account field."};
|
||||
}
|
||||
|
||||
if (clawAmount && clawAmount->asset() != asset)
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "AMMClawback: Amount's asset subfield "
|
||||
"does not match Asset field";
|
||||
return temBAD_AMOUNT;
|
||||
return {temBAD_AMOUNT, "AMMClawback: Amount's asset subfield does not match Asset field"};
|
||||
}
|
||||
|
||||
if (clawAmount && *clawAmount <= beast::kZero)
|
||||
@@ -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))
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/dex/AMMDelete.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/ledger/Sandbox.h>
|
||||
#include <xrpl/ledger/helpers/AMMHelpers.h>
|
||||
@@ -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];
|
||||
|
||||
@@ -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"};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -17,8 +17,7 @@ OfferCancel::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.tx[sfOfferSequence] == 0u)
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "OfferCancel::preflight: missing sequence";
|
||||
return temBAD_SEQUENCE;
|
||||
return {temBAD_SEQUENCE, "OfferCancel::preflight: missing sequence"};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -90,7 +90,6 @@ NotTEC
|
||||
OfferCreate::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
auto& tx = ctx.tx;
|
||||
auto& j = ctx.j;
|
||||
|
||||
if (tx.isFlag(tfHybrid) && !tx.isFieldPresent(sfDomainID))
|
||||
return temINVALID_FLAG;
|
||||
@@ -106,22 +105,19 @@ OfferCreate::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (bImmediateOrCancel && bFillOrKill)
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed transaction: both IoC and FoK set.";
|
||||
return temINVALID_FLAG;
|
||||
return {temINVALID_FLAG, "Malformed transaction: both IoC and FoK set."};
|
||||
}
|
||||
|
||||
bool const bHaveExpiration(tx.isFieldPresent(sfExpiration));
|
||||
|
||||
if (bHaveExpiration && (tx.getFieldU32(sfExpiration) == 0))
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed offer: bad expiration";
|
||||
return temBAD_EXPIRATION;
|
||||
return {temBAD_EXPIRATION, "Malformed offer: bad expiration"};
|
||||
}
|
||||
|
||||
if (auto const cancelSequence = tx[~sfOfferSequence]; cancelSequence && *cancelSequence == 0)
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed offer: bad cancel sequence";
|
||||
return temBAD_SEQUENCE;
|
||||
return {temBAD_SEQUENCE, "Malformed offer: bad cancel sequence"};
|
||||
}
|
||||
|
||||
STAmount const saTakerPays = tx[sfTakerPays];
|
||||
@@ -132,13 +128,11 @@ OfferCreate::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (saTakerPays.native() && saTakerGets.native())
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed offer: redundant (XRP for XRP)";
|
||||
return temBAD_OFFER;
|
||||
return {temBAD_OFFER, "Malformed offer: redundant (XRP for XRP)"};
|
||||
}
|
||||
if (saTakerPays <= beast::kZero || saTakerGets <= beast::kZero)
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed offer: bad amount";
|
||||
return temBAD_OFFER;
|
||||
return {temBAD_OFFER, "Malformed offer: bad amount"};
|
||||
}
|
||||
|
||||
auto const& uPaysIssuerID = saTakerPays.getIssuer();
|
||||
@@ -149,20 +143,17 @@ OfferCreate::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (uPaysAsset == uGetsAsset)
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed offer: redundant (IOU for IOU)";
|
||||
return temREDUNDANT;
|
||||
return {temREDUNDANT, "Malformed offer: redundant (IOU for IOU)"};
|
||||
}
|
||||
// We don't allow a non-native currency to use the currency code XRP.
|
||||
if (badAsset() == uPaysAsset || badAsset() == uGetsAsset)
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed offer: bad currency";
|
||||
return temBAD_CURRENCY;
|
||||
return {temBAD_CURRENCY, "Malformed offer: bad currency"};
|
||||
}
|
||||
|
||||
if (saTakerPays.native() != !uPaysIssuerID || saTakerGets.native() != !uGetsIssuerID)
|
||||
{
|
||||
JLOG(j.debug()) << "Malformed offer: bad issuer";
|
||||
return temBAD_ISSUER;
|
||||
return {temBAD_ISSUER, "Malformed offer: bad issuer"};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -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);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/did/DIDDelete.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/escrow/EscrowCancel.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/escrow/EscrowFinish.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/conditions/Condition.h>
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<SLE>(keylet::loanBroker(accountID_, sequence));
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/lending/LoanDelete.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/Number.h> // IWYU pragma: keep
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
@@ -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;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/Number.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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."};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <xrpl/tx/transactors/oracle/OracleDelete.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/sponsor/SponsorshipSet.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/sponsor/SponsorshipTransfer.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
@@ -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;
|
||||
|
||||
@@ -44,29 +44,25 @@ Transactor::invokePreflight<Change>(PreflightContext const& ctx)
|
||||
auto account = ctx.tx.getAccountID(sfAccount);
|
||||
if (account != beast::kZero)
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Change: Bad source id";
|
||||
return temBAD_SRC_ACCOUNT;
|
||||
return {temBAD_SRC_ACCOUNT, "Change: Bad source id"};
|
||||
}
|
||||
|
||||
// No point in going any further if the transaction fee is malformed.
|
||||
auto const fee = ctx.tx.getFieldAmount(sfFee);
|
||||
if (!fee.native() || fee != beast::kZero)
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Change: invalid fee";
|
||||
return temBAD_FEE;
|
||||
return {temBAD_FEE, "Change: invalid fee"};
|
||||
}
|
||||
|
||||
if (!ctx.tx.getSigningPubKey().empty() || !ctx.tx.getSignature().empty() ||
|
||||
ctx.tx.isFieldPresent(sfSigners))
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Change: Bad signature";
|
||||
return temBAD_SIGNATURE;
|
||||
return {temBAD_SIGNATURE, "Change: Bad signature"};
|
||||
}
|
||||
|
||||
if (ctx.tx.getFieldU32(sfSequence) != 0 || ctx.tx.isFieldPresent(sfPreviousTxnID))
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Change: Bad sequence";
|
||||
return temBAD_SEQUENCE;
|
||||
return {temBAD_SEQUENCE, "Change: Bad sequence"};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -79,8 +75,7 @@ Change::preclaim(PreclaimContext const& ctx)
|
||||
// this block can be moved to preflight.
|
||||
if (ctx.view.open())
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Change transaction against open ledger";
|
||||
return temINVALID;
|
||||
return {temINVALID, "Change transaction against open ledger"};
|
||||
}
|
||||
|
||||
switch (ctx.tx.getTxnType())
|
||||
@@ -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);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/token/ConfidentialMPTConvert.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/token/ConfidentialMPTConvertBack.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/token/ConfidentialMPTMergeInbox.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xrpl/tx/transactors/token/ConfidentialMPTSend.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -100,14 +100,12 @@ TrustSet::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (badCurrency() == saLimitAmount.get<Issue>().currency)
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: specifies XRP as IOU";
|
||||
return temBAD_CURRENCY;
|
||||
return {temBAD_CURRENCY, "Malformed transaction: specifies XRP as IOU"};
|
||||
}
|
||||
|
||||
if (saLimitAmount < beast::kZero)
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: Negative credit limit.";
|
||||
return temBAD_LIMIT;
|
||||
return {temBAD_LIMIT, "Malformed transaction: Negative credit limit."};
|
||||
}
|
||||
|
||||
// Check if destination makes sense.
|
||||
@@ -115,8 +113,7 @@ TrustSet::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (!issuer || issuer == noAccount())
|
||||
{
|
||||
JLOG(j.trace()) << "Malformed transaction: no destination account.";
|
||||
return temDST_NEEDED;
|
||||
return {temDST_NEEDED, "Malformed transaction: no destination account."};
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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."};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <xrpl/tx/transactors/vault/VaultSet.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -235,12 +236,52 @@ struct TER_test : public beast::unit_test::Suite
|
||||
testIterate<kHiIndex, kHiIndex, CheckComparable>(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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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<void(json::Value const&, json::Value const&)> 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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -251,8 +251,8 @@ public:
|
||||
, seqProxy(seqProxy)
|
||||
, txn(txn)
|
||||
, retriesRemaining(retriesRemaining)
|
||||
, preflightResult(preflightResult)
|
||||
, lastResult(lastResult)
|
||||
, preflightResult(std::move(preflightResult))
|
||||
, lastResult(std::move(lastResult))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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&)
|
||||
|
||||
@@ -264,6 +264,7 @@ simulateTxn(RPC::JsonContext& context, std::shared_ptr<Transaction> 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> 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
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in new issue
Block a user