Fix failing MPToken payment test

This commit is contained in:
Bronek Kozicki
2024-12-17 15:38:27 +00:00
parent ad581661e3
commit ecec6e5d33
3 changed files with 61 additions and 20 deletions

View File

@@ -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.

View File

@@ -561,6 +561,21 @@ transferXRP(
STAmount const& amount,
beast::Journal j);
struct TokenDescriptor
{
std::shared_ptr<SLE const> token;
std::shared_ptr<SLE const> issuance;
};
[[nodiscard]] Expected<TokenDescriptor, TER>
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.

View File

@@ -2021,8 +2021,8 @@ requireAuth(ReadView const& view, Issue const& issue, AccountID const& account)
return tesSUCCESS;
}
TER
requireAuth(
[[nodiscard]] Expected<TokenDescriptor, TER>
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 &&