diff --git a/src/xrpld/app/misc/CredentialHelpers.cpp b/src/xrpld/app/misc/CredentialHelpers.cpp index 81355f17920..6d1f9f78c56 100644 --- a/src/xrpld/app/misc/CredentialHelpers.cpp +++ b/src/xrpld/app/misc/CredentialHelpers.cpp @@ -120,15 +120,15 @@ deleteSLE( } NotTEC -checkFields(PreflightContext const& ctx) +checkFields(STTx const& tx, beast::Journal j) { - if (!ctx.tx.isFieldPresent(sfCredentialIDs)) + if (!tx.isFieldPresent(sfCredentialIDs)) return tesSUCCESS; - auto const& credentials = ctx.tx.getFieldV256(sfCredentialIDs); + auto const& credentials = tx.getFieldV256(sfCredentialIDs); if (credentials.empty() || (credentials.size() > maxCredentialsArraySize)) { - JLOG(ctx.j.trace()) + JLOG(j.trace()) << "Malformed transaction: Credentials array size is invalid: " << credentials.size(); return temMALFORMED; @@ -140,7 +140,7 @@ checkFields(PreflightContext const& ctx) auto [it, ins] = duplicates.insert(cred); if (!ins) { - JLOG(ctx.j.trace()) + JLOG(j.trace()) << "Malformed transaction: duplicates in credentials."; return temMALFORMED; } @@ -150,24 +150,28 @@ checkFields(PreflightContext const& ctx) } TER -valid(PreclaimContext const& ctx, AccountID const& src) +valid( + STTx const& tx, + ReadView const& view, + AccountID const& src, + beast::Journal j) { - if (!ctx.tx.isFieldPresent(sfCredentialIDs)) + if (!tx.isFieldPresent(sfCredentialIDs)) return tesSUCCESS; - auto const& credIDs(ctx.tx.getFieldV256(sfCredentialIDs)); + auto const& credIDs(tx.getFieldV256(sfCredentialIDs)); for (auto const& h : credIDs) { - auto const sleCred = ctx.view.read(keylet::credential(h)); + auto const sleCred = view.read(keylet::credential(h)); if (!sleCred) { - JLOG(ctx.j.trace()) << "Credential doesn't exist. Cred: " << h; + JLOG(j.trace()) << "Credential doesn't exist. Cred: " << h; return tecBAD_CREDENTIALS; } if (sleCred->getAccountID(sfSubject) != src) { - JLOG(ctx.j.trace()) + JLOG(j.trace()) << "Credential doesn't belong to the source account. Cred: " << h; return tecBAD_CREDENTIALS; @@ -175,7 +179,7 @@ valid(PreclaimContext const& ctx, AccountID const& src) if (!(sleCred->getFlags() & lsfAccepted)) { - JLOG(ctx.j.trace()) << "Credential isn't accepted. Cred: " << h; + JLOG(j.trace()) << "Credential isn't accepted. Cred: " << h; return tecBAD_CREDENTIALS; } @@ -352,10 +356,12 @@ verifyValidDomain( TER verifyDepositPreauth( - ApplyContext& ctx, + STTx const& tx, + ApplyView& view, AccountID const& src, AccountID const& dst, - std::shared_ptr const& sleDst) + std::shared_ptr const& sleDst, + beast::Journal j) { // If depositPreauth is enabled, then an account that requires // authorization has at least two ways to get a payment in: @@ -363,24 +369,21 @@ verifyDepositPreauth( // 2. If src is deposit preauthorized by dst (either by account or by // credentials). - bool const credentialsPresent = ctx.tx.isFieldPresent(sfCredentialIDs); + bool const credentialsPresent = tx.isFieldPresent(sfCredentialIDs); if (credentialsPresent && - credentials::removeExpired( - ctx.view(), ctx.tx.getFieldV256(sfCredentialIDs), ctx.journal)) + credentials::removeExpired(view, tx.getFieldV256(sfCredentialIDs), j)) return tecEXPIRED; if (sleDst && (sleDst->getFlags() & lsfDepositAuth)) { if (src != dst) { - if (!ctx.view().exists(keylet::depositPreauth(dst, src))) + if (!view.exists(keylet::depositPreauth(dst, src))) return !credentialsPresent ? tecNO_PERMISSION : credentials::authorizedDepositPreauth( - ctx.view(), - ctx.tx.getFieldV256(sfCredentialIDs), - dst); + view, tx.getFieldV256(sfCredentialIDs), dst); } } diff --git a/src/xrpld/app/misc/CredentialHelpers.h b/src/xrpld/app/misc/CredentialHelpers.h index 162ddd6515d..84938180ce2 100644 --- a/src/xrpld/app/misc/CredentialHelpers.h +++ b/src/xrpld/app/misc/CredentialHelpers.h @@ -20,7 +20,16 @@ #ifndef RIPPLE_APP_MISC_CREDENTIALHELPERS_H_INCLUDED #define RIPPLE_APP_MISC_CREDENTIALHELPERS_H_INCLUDED -#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include namespace ripple { namespace credentials { @@ -48,13 +57,17 @@ deleteSLE( // Amendment and parameters checks for sfCredentialIDs field NotTEC -checkFields(PreflightContext const& ctx); +checkFields(STTx const& tx, beast::Journal j); // Accessing the ledger to check if provided credentials are valid. Do not use // in doApply (only in preclaim) since it does not remove expired credentials. // If you call it in prelaim, you also must call verifyDepositPreauth in doApply TER -valid(PreclaimContext const& ctx, AccountID const& src); +valid( + STTx const& tx, + ReadView const& view, + AccountID const& src, + beast::Journal j); // Check if subject has any credential maching the given domain. If you call it // in preclaim and it returns tecEXPIRED, you should call verifyValidDomain in @@ -93,10 +106,12 @@ verifyValidDomain( // Check expired credentials and for existing DepositPreauth ledger object TER verifyDepositPreauth( - ApplyContext& ctx, + STTx const& tx, + ApplyView& view, AccountID const& src, AccountID const& dst, - std::shared_ptr const& sleDst); + std::shared_ptr const& sleDst, + beast::Journal j); } // namespace ripple diff --git a/src/xrpld/app/tx/detail/DeleteAccount.cpp b/src/xrpld/app/tx/detail/DeleteAccount.cpp index 7aa47e05f38..4311aa79a8d 100644 --- a/src/xrpld/app/tx/detail/DeleteAccount.cpp +++ b/src/xrpld/app/tx/detail/DeleteAccount.cpp @@ -58,7 +58,8 @@ DeleteAccount::preflight(PreflightContext const& ctx) // An account cannot be deleted and give itself the resulting XRP. return temDST_IS_SRC; - if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err)) + if (auto const err = credentials::checkFields(ctx.tx, ctx.j); + !isTesSuccess(err)) return err; return preflight2(ctx); @@ -241,7 +242,8 @@ DeleteAccount::preclaim(PreclaimContext const& ctx) return tecDST_TAG_NEEDED; // If credentials are provided - check them anyway - if (auto const err = credentials::valid(ctx, account); !isTesSuccess(err)) + if (auto const err = credentials::valid(ctx.tx, ctx.view, account, ctx.j); + !isTesSuccess(err)) return err; // if credentials then postpone auth check to doApply, to check for expired @@ -376,7 +378,8 @@ DeleteAccount::doApply() if (ctx_.view().rules().enabled(featureDepositAuth) && ctx_.tx.isFieldPresent(sfCredentialIDs)) { - if (auto err = verifyDepositPreauth(ctx_, account_, dstID, dst); + if (auto err = verifyDepositPreauth( + ctx_.tx, ctx_.view(), account_, dstID, dst, ctx_.journal); !isTesSuccess(err)) return err; } diff --git a/src/xrpld/app/tx/detail/Escrow.cpp b/src/xrpld/app/tx/detail/Escrow.cpp index 75080da9a5c..8f7005d55c0 100644 --- a/src/xrpld/app/tx/detail/Escrow.cpp +++ b/src/xrpld/app/tx/detail/Escrow.cpp @@ -672,7 +672,8 @@ EscrowFinish::preflight(PreflightContext const& ctx) } } - if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err)) + if (auto const err = credentials::checkFields(ctx.tx, ctx.j); + !isTesSuccess(err)) return err; return tesSUCCESS; @@ -761,7 +762,8 @@ EscrowFinish::preclaim(PreclaimContext const& ctx) { if (ctx.view.rules().enabled(featureCredentials)) { - if (auto const err = credentials::valid(ctx, ctx.tx[sfAccount]); + if (auto const err = + credentials::valid(ctx.tx, ctx.view, ctx.tx[sfAccount], ctx.j); !isTesSuccess(err)) return err; } @@ -1107,7 +1109,8 @@ EscrowFinish::doApply() if (ctx_.view().rules().enabled(featureDepositAuth)) { - if (auto err = verifyDepositPreauth(ctx_, account_, destID, sled); + if (auto err = verifyDepositPreauth( + ctx_.tx, ctx_.view(), account_, destID, sled, ctx_.journal); !isTesSuccess(err)) return err; } diff --git a/src/xrpld/app/tx/detail/PayChan.cpp b/src/xrpld/app/tx/detail/PayChan.cpp index a42902f6acd..d9e53ac75c7 100644 --- a/src/xrpld/app/tx/detail/PayChan.cpp +++ b/src/xrpld/app/tx/detail/PayChan.cpp @@ -473,7 +473,8 @@ PayChanClaim::preflight(PreflightContext const& ctx) return temBAD_SIGNATURE; } - if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err)) + if (auto const err = credentials::checkFields(ctx.tx, ctx.j); + !isTesSuccess(err)) return err; return preflight2(ctx); @@ -485,7 +486,8 @@ PayChanClaim::preclaim(PreclaimContext const& ctx) if (!ctx.view.rules().enabled(featureCredentials)) return Transactor::preclaim(ctx); - if (auto const err = credentials::valid(ctx, ctx.tx[sfAccount]); + if (auto const err = + credentials::valid(ctx.tx, ctx.view, ctx.tx[sfAccount], ctx.j); !isTesSuccess(err)) return err; @@ -554,7 +556,8 @@ PayChanClaim::doApply() if (depositAuth) { - if (auto err = verifyDepositPreauth(ctx_, txAccount, dst, sled); + if (auto err = verifyDepositPreauth( + ctx_.tx, ctx_.view(), txAccount, dst, sled, ctx_.journal); !isTesSuccess(err)) return err; } diff --git a/src/xrpld/app/tx/detail/Payment.cpp b/src/xrpld/app/tx/detail/Payment.cpp index f36e1bfe3d0..692e03109ee 100644 --- a/src/xrpld/app/tx/detail/Payment.cpp +++ b/src/xrpld/app/tx/detail/Payment.cpp @@ -238,7 +238,8 @@ Payment::preflight(PreflightContext const& ctx) } } - if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err)) + if (auto const err = credentials::checkFields(ctx.tx, ctx.j); + !isTesSuccess(err)) return err; return preflight2(ctx); @@ -358,7 +359,8 @@ Payment::preclaim(PreclaimContext const& ctx) } } - if (auto const err = credentials::valid(ctx, ctx.tx[sfAccount]); + if (auto const err = + credentials::valid(ctx.tx, ctx.view, ctx.tx[sfAccount], ctx.j); !isTesSuccess(err)) return err; @@ -450,8 +452,13 @@ Payment::doApply() // 1. If Account == Destination, or // 2. If Account is deposit preauthorized by destination. - if (auto err = - verifyDepositPreauth(ctx_, account_, dstAccountID, sleDst); + if (auto err = verifyDepositPreauth( + ctx_.tx, + ctx_.view(), + account_, + dstAccountID, + sleDst, + ctx_.journal); !isTesSuccess(err)) return err; } @@ -521,8 +528,13 @@ Payment::doApply() ter != tesSUCCESS) return ter; - if (auto err = - verifyDepositPreauth(ctx_, account_, dstAccountID, sleDst); + if (auto err = verifyDepositPreauth( + ctx_.tx, + ctx_.view(), + account_, + dstAccountID, + sleDst, + ctx_.journal); !isTesSuccess(err)) return err; @@ -644,8 +656,13 @@ Payment::doApply() if (dstAmount > dstReserve || sleDst->getFieldAmount(sfBalance) > dstReserve) { - if (auto err = - verifyDepositPreauth(ctx_, account_, dstAccountID, sleDst); + if (auto err = verifyDepositPreauth( + ctx_.tx, + ctx_.view(), + account_, + dstAccountID, + sleDst, + ctx_.journal); !isTesSuccess(err)) return err; }