From ecec6e5d33e3fd9da70945745e6e3e395d168fd0 Mon Sep 17 00:00:00 2001 From: Bronek Kozicki Date: Tue, 17 Dec 2024 15:38:27 +0000 Subject: [PATCH] Fix failing MPToken payment test --- src/xrpld/app/tx/detail/VaultDeposit.cpp | 29 ++++++++++--------- src/xrpld/ledger/View.h | 15 ++++++++++ src/xrpld/ledger/detail/View.cpp | 37 +++++++++++++++++++----- 3 files changed, 61 insertions(+), 20 deletions(-) diff --git a/src/xrpld/app/tx/detail/VaultDeposit.cpp b/src/xrpld/app/tx/detail/VaultDeposit.cpp index 810d97d3f6..7d340d35b0 100644 --- a/src/xrpld/app/tx/detail/VaultDeposit.cpp +++ b/src/xrpld/app/tx/detail/VaultDeposit.cpp @@ -81,20 +81,23 @@ VaultDeposit::doApply() // Make sure the depositor can hold shares. auto share = (*vault)[sfMPTokenIssuanceID]; - auto canHold = requireAuth(view(), MPTIssue(share), account_); - if (canHold == tecNO_LINE) + auto maybeToken = findToken(view(), MPTIssue(share), account_); + if (!maybeToken) { - if (auto ter = MPTokenAuthorize::authorize( - view(), - j_, - {.priorBalance = mPriorBalance, - .mptIssuanceID = share, - .accountID = account_})) - return ter; - } - else if (canHold != tesSUCCESS) - { - return canHold; + if (maybeToken.error() == tecNO_LINE) + { + if (auto ter = MPTokenAuthorize::authorize( + view(), + j_, + {.priorBalance = mPriorBalance, + .mptIssuanceID = share, + .accountID = account_})) + return ter; + } + else if (maybeToken.error() != tesSUCCESS) + { + return maybeToken.error(); + } } // Compute exchange before transferring any amounts. diff --git a/src/xrpld/ledger/View.h b/src/xrpld/ledger/View.h index 8680a4e64a..4e4899de62 100644 --- a/src/xrpld/ledger/View.h +++ b/src/xrpld/ledger/View.h @@ -561,6 +561,21 @@ transferXRP( STAmount const& amount, beast::Journal j); +struct TokenDescriptor +{ + std::shared_ptr token; + std::shared_ptr issuance; +}; + +[[nodiscard]] Expected +findToken( + ReadView const& view, + MPTIssue const& mptIssue, + AccountID const& account); + +[[nodiscard]] TER +requireAuth(ReadView const& view, Issue const& issue, AccountID const& account); + /** Check if the account lacks required authorization. * Return tecNO_AUTH or tecNO_LINE if it does * and tesSUCCESS otherwise. diff --git a/src/xrpld/ledger/detail/View.cpp b/src/xrpld/ledger/detail/View.cpp index abc4669c9c..a70c036f54 100644 --- a/src/xrpld/ledger/detail/View.cpp +++ b/src/xrpld/ledger/detail/View.cpp @@ -2021,8 +2021,8 @@ requireAuth(ReadView const& view, Issue const& issue, AccountID const& account) return tesSUCCESS; } -TER -requireAuth( +[[nodiscard]] Expected +findToken( ReadView const& view, MPTIssue const& mptIssue, AccountID const& account) @@ -2031,20 +2031,43 @@ requireAuth( auto const sleIssuance = view.read(mptID); if (!sleIssuance) - return tecOBJECT_NOT_FOUND; + return Unexpected(tecOBJECT_NOT_FOUND); auto const mptIssuer = sleIssuance->getAccountID(sfIssuer); - - // issuer is always "authorized" + // Issuer won't have mptoken, i.e. "the operation failed succcessfully" if (mptIssuer == account) - return tesSUCCESS; + return Unexpected(tesSUCCESS); auto const mptokenID = keylet::mptoken(mptID.key, account); auto const sleToken = view.read(mptokenID); // if account has no MPToken, fail if (!sleToken) - return tecNO_LINE; + return Unexpected(tecNO_LINE); + + return {TokenDescriptor{.token = sleToken, .issuance = sleIssuance}}; +} + +TER +requireAuth( + ReadView const& view, + MPTIssue const& mptIssue, + AccountID const& account) +{ + auto maybeToken = findToken(view, mptIssue, account); + + // Whatever reason why we could not find + if (!maybeToken) + { + // Convert tecNO_LINE to useful error + if (maybeToken.error() == tecNO_LINE) + return tecNO_AUTH; + // Note, error() is tesSUCCESS if no authorization was needed + return maybeToken.error(); + } + + auto sleToken = maybeToken->token; + auto sleIssuance = maybeToken->issuance; // mptoken must be authorized if issuance enabled requireAuth if (sleIssuance->getFieldU32(sfFlags) & lsfMPTRequireAuth &&