Skip to content

Commit

Permalink
Implement direct payment with mAsset in STAmount holding a union of I…
Browse files Browse the repository at this point in the history
…ssue/MPTIssue
  • Loading branch information
gregtatcam committed Feb 23, 2024
1 parent f57fe04 commit 28792f0
Show file tree
Hide file tree
Showing 52 changed files with 1,158 additions and 254 deletions.
2 changes: 2 additions & 0 deletions Builds/CMake/RippledCore.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ target_sources (xrpl_core PRIVATE
#]===============================]
src/ripple/protocol/impl/AccountID.cpp
src/ripple/protocol/impl/AMMCore.cpp
src/ripple/protocol/impl/Asset.cpp
src/ripple/protocol/impl/Book.cpp
src/ripple/protocol/impl/BuildInfo.cpp
src/ripple/protocol/impl/ErrorCodes.cpp
Expand All @@ -86,6 +87,7 @@ target_sources (xrpl_core PRIVATE
src/ripple/protocol/impl/Keylet.cpp
src/ripple/protocol/impl/LedgerFormats.cpp
src/ripple/protocol/impl/LedgerHeader.cpp
src/ripple/protocol/impl/MPTIssue.cpp
src/ripple/protocol/impl/PublicKey.cpp
src/ripple/protocol/impl/Quality.cpp
src/ripple/protocol/impl/QualityFunction.cpp
Expand Down
4 changes: 1 addition & 3 deletions src/ripple/app/paths/AMMLiquidity.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "ripple/app/misc/AMMHelpers.h"
#include "ripple/app/misc/AMMUtils.h"
#include "ripple/app/paths/AMMContext.h"
#include "ripple/app/paths/AMMOffer.h"
#include "ripple/basics/Log.h"
#include "ripple/ledger/ReadView.h"
#include "ripple/ledger/View.h"
Expand All @@ -31,9 +32,6 @@

namespace ripple {

template <typename TIn, typename TOut>
class AMMOffer;

/** AMMLiquidity class provides AMM offers to BookStep class.
* The offers are generated in two ways. If there are multiple
* paths specified to the payment transaction then the offers
Expand Down
6 changes: 5 additions & 1 deletion src/ripple/app/paths/AMMOffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,15 @@ template <typename TIn, typename TOut>
class AMMLiquidity;
class QualityFunction;

template <typename A>
concept OfferAmount =
!(std::is_same_v<A, STAmount> || std::is_same_v<A, MPTAmount>);

/** Represents synthetic AMM offer in BookStep. AMMOffer mirrors TOffer
* methods for use in generic BookStep methods. AMMOffer amounts
* are changed indirectly in BookStep limiting steps.
*/
template <typename TIn, typename TOut>
template <OfferAmount TIn, OfferAmount TOut>
class AMMOffer
{
private:
Expand Down
4 changes: 2 additions & 2 deletions src/ripple/app/paths/Credit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ creditLimit(
AccountID const& issuer,
Currency const& currency)
{
STAmount result({currency, account});
STAmount result(Issue{currency, account});

auto sleRippleState = view.read(keylet::line(account, issuer, currency));

Expand Down Expand Up @@ -64,7 +64,7 @@ creditBalance(
AccountID const& issuer,
Currency const& currency)
{
STAmount result({currency, account});
STAmount result(Issue{currency, account});

auto sleRippleState = view.read(keylet::line(account, issuer, currency));

Expand Down
6 changes: 6 additions & 0 deletions src/ripple/app/paths/Flow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ flow(
beast::Journal j,
path::detail::FlowDebugInfo* flowDebugInfo)
{
if (deliver.isMPT() || (sendMax && sendMax->isMPT()))
{
path::RippleCalc::Output result;
result.setResult(tecMPT_NOT_SUPPORTED);
}

Issue const srcIssue = [&] {
if (sendMax)
return sendMax->issue();
Expand Down
14 changes: 13 additions & 1 deletion src/ripple/app/paths/PathRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,12 @@ PathRequest::parseJson(Json::Value const& jvParams)
return PFR_PJ_INVALID;
}

if (saDstAmount.isMPT())
{
jvStatus = rpcError(rpcMPT_NOT_SUPPORTED);
return PFR_PJ_INVALID;
}

convert_all_ = saDstAmount == STAmount(saDstAmount.issue(), 1u, 0, true);

if ((saDstAmount.getCurrency().isZero() &&
Expand Down Expand Up @@ -344,6 +350,12 @@ PathRequest::parseJson(Json::Value const& jvParams)
jvStatus = rpcError(rpcSENDMAX_MALFORMED);
return PFR_PJ_INVALID;
}

if (saSendMax->isMPT())
{
jvStatus = rpcError(rpcMPT_NOT_SUPPORTED);
return PFR_PJ_INVALID;
}
}

if (jvParams.isMember(jss::source_currencies))
Expand Down Expand Up @@ -562,7 +574,7 @@ PathRequest::findPaths(
}();

STAmount saMaxAmount = saSendMax.value_or(
STAmount({issue.currency, sourceAccount}, 1u, 0, true));
STAmount(Issue{issue.currency, sourceAccount}, 1u, 0, true));

JLOG(m_journal.debug())
<< iIdentifier << " Paths found, calling rippleCalc";
Expand Down
7 changes: 4 additions & 3 deletions src/ripple/app/paths/Pathfinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,10 @@ Pathfinder::Pathfinder(
, mSrcCurrency(uSrcCurrency)
, mSrcIssuer(uSrcIssuer)
, mSrcAmount(srcAmount.value_or(STAmount(
{uSrcCurrency,
uSrcIssuer.value_or(
isXRP(uSrcCurrency) ? xrpAccount() : uSrcAccount)},
Issue{
uSrcCurrency,
uSrcIssuer.value_or(
isXRP(uSrcCurrency) ? xrpAccount() : uSrcAccount)},
1u,
0,
true)))
Expand Down
1 change: 0 additions & 1 deletion src/ripple/app/paths/impl/AMMLiquidity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,6 @@ AMMLiquidity<TIn, TOut>::getOffer(
return std::nullopt;
}

template class AMMLiquidity<STAmount, STAmount>;
template class AMMLiquidity<IOUAmount, IOUAmount>;
template class AMMLiquidity<XRPAmount, IOUAmount>;
template class AMMLiquidity<IOUAmount, XRPAmount>;
Expand Down
19 changes: 9 additions & 10 deletions src/ripple/app/paths/impl/AMMOffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

namespace ripple {

template <typename TIn, typename TOut>
template <OfferAmount TIn, OfferAmount TOut>
AMMOffer<TIn, TOut>::AMMOffer(
AMMLiquidity<TIn, TOut> const& ammLiquidity,
TAmounts<TIn, TOut> const& amounts,
Expand All @@ -37,35 +37,35 @@ AMMOffer<TIn, TOut>::AMMOffer(
{
}

template <typename TIn, typename TOut>
template <OfferAmount TIn, OfferAmount TOut>
Issue const&
AMMOffer<TIn, TOut>::issueIn() const
{
return ammLiquidity_.issueIn();
}

template <typename TIn, typename TOut>
template <OfferAmount TIn, OfferAmount TOut>
Issue const&
AMMOffer<TIn, TOut>::issueOut() const
{
return ammLiquidity_.issueOut();
}

template <typename TIn, typename TOut>
template <OfferAmount TIn, OfferAmount TOut>
AccountID const&
AMMOffer<TIn, TOut>::owner() const
{
return ammLiquidity_.ammAccount();
}

template <typename TIn, typename TOut>
template <OfferAmount TIn, OfferAmount TOut>
TAmounts<TIn, TOut> const&
AMMOffer<TIn, TOut>::amount() const
{
return amounts_;
}

template <typename TIn, typename TOut>
template <OfferAmount TIn, OfferAmount TOut>
void
AMMOffer<TIn, TOut>::consume(
ApplyView& view,
Expand All @@ -83,7 +83,7 @@ AMMOffer<TIn, TOut>::consume(
ammLiquidity_.context().setAMMUsed();
}

template <typename TIn, typename TOut>
template <OfferAmount TIn, OfferAmount TOut>
TAmounts<TIn, TOut>
AMMOffer<TIn, TOut>::limitOut(
TAmounts<TIn, TOut> const& offrAmt,
Expand Down Expand Up @@ -113,7 +113,7 @@ AMMOffer<TIn, TOut>::limitOut(
return {swapAssetOut(*balances_, limit, ammLiquidity_.tradingFee()), limit};
}

template <typename TIn, typename TOut>
template <OfferAmount TIn, OfferAmount TOut>
TAmounts<TIn, TOut>
AMMOffer<TIn, TOut>::limitIn(
TAmounts<TIn, TOut> const& offrAmt,
Expand All @@ -125,7 +125,7 @@ AMMOffer<TIn, TOut>::limitIn(
return {limit, swapAssetIn(*balances_, limit, ammLiquidity_.tradingFee())};
}

template <typename TIn, typename TOut>
template <OfferAmount TIn, OfferAmount TOut>
QualityFunction
AMMOffer<TIn, TOut>::getQualityFunc() const
{
Expand All @@ -135,7 +135,6 @@ AMMOffer<TIn, TOut>::getQualityFunc() const
*balances_, ammLiquidity_.tradingFee(), QualityFunction::AMMTag{}};
}

template class AMMOffer<STAmount, STAmount>;
template class AMMOffer<IOUAmount, IOUAmount>;
template class AMMOffer<XRPAmount, IOUAmount>;
template class AMMOffer<IOUAmount, XRPAmount>;
Expand Down
11 changes: 10 additions & 1 deletion src/ripple/app/paths/impl/AmountSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,18 @@ struct AmountSpec
{
XRPAmount xrp;
IOUAmount iou = {};
MPTAmount mpt;
};
std::optional<AccountID> issuer;
std::optional<Currency> currency;
std::optional<MPT> mptid;

friend std::ostream&
operator<<(std::ostream& stream, AmountSpec const& amt)
{
if (amt.native)
if (amt.mptid)
stream << to_string(*amt.mptid);
else if (amt.native)
stream << to_string(amt.xrp);
else
stream << to_string(amt.iou);
Expand Down Expand Up @@ -175,6 +179,11 @@ toAmountSpec(STAmount const& amt)
{
result.xrp = XRPAmount(sMant);
}
else if (amt.isMPT())
{
result.mptid = amt.mptIssue().mpt();
result.mpt = amt.mpt();
}
else
{
result.iou = IOUAmount(sMant, amt.exponent());
Expand Down
6 changes: 5 additions & 1 deletion src/ripple/app/paths/impl/Steps.h
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,12 @@ toStrands(
AMMContext& ammContext,
beast::Journal j);

template <typename A>
concept StepAsset =
!(std::is_same_v<A, STAmount> || std::is_same_v<A, MPTAmount>);

/// @cond INTERNAL
template <class TIn, class TOut, class TDerived>
template <StepAsset TIn, StepAsset TOut, class TDerived>
struct StepImp : public Step
{
explicit StepImp() = default;
Expand Down
2 changes: 1 addition & 1 deletion src/ripple/app/paths/impl/StrandFlow.h
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ class ActiveStrands
@return Actual amount in and out from the strands, errors, and payment
sandbox
*/
template <class TInAmt, class TOutAmt>
template <StepAsset TInAmt, StepAsset TOutAmt>
FlowResult<TInAmt, TOutAmt>
flow(
PaymentSandbox const& baseView,
Expand Down
6 changes: 6 additions & 0 deletions src/ripple/app/tx/impl/AMMCreate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ AMMCreate::preflight(PreflightContext const& ctx)
auto const amount = ctx.tx[sfAmount];
auto const amount2 = ctx.tx[sfAmount2];

if (amount.isMPT() || amount2.isIssue())
{
JLOG(ctx.j.debug()) << "AMM Instance: MPT is not supported.";
return temMPT_NOT_SUPPORTED;
}

if (amount.issue() == amount2.issue())
{
JLOG(ctx.j.debug())
Expand Down
4 changes: 4 additions & 0 deletions src/ripple/app/tx/impl/CashCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ CashCheck::preflight(PreflightContext const& ctx)
auto const optAmount = ctx.tx[~sfAmount];
auto const optDeliverMin = ctx.tx[~sfDeliverMin];

if ((optAmount && optAmount->isMPT()) ||
(optDeliverMin && optDeliverMin->isMPT()))
return temMPT_NOT_SUPPORTED;

if (static_cast<bool>(optAmount) == static_cast<bool>(optDeliverMin))
{
JLOG(ctx.j.warn())
Expand Down
3 changes: 3 additions & 0 deletions src/ripple/app/tx/impl/Clawback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ Clawback::preflight(PreflightContext const& ctx)
AccountID const issuer = ctx.tx[sfAccount];
STAmount const clawAmount = ctx.tx[sfAmount];

if (clawAmount.isMPT())
return temMPT_NOT_SUPPORTED;

// The issuer field is used for the token holder instead
AccountID const& holder = clawAmount.getIssuer();

Expand Down
4 changes: 4 additions & 0 deletions src/ripple/app/tx/impl/CreateCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ CreateCheck::preflight(PreflightContext const& ctx)

{
STAmount const sendMax{ctx.tx.getFieldAmount(sfSendMax)};

if (sendMax.isMPT())
return temMPT_NOT_SUPPORTED;

if (!isLegalNet(sendMax) || sendMax.signum() <= 0)
{
JLOG(ctx.j.warn()) << "Malformed transaction: bad sendMax amount: "
Expand Down
3 changes: 3 additions & 0 deletions src/ripple/app/tx/impl/CreateOffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ CreateOffer::preflight(PreflightContext const& ctx)
STAmount saTakerPays = tx[sfTakerPays];
STAmount saTakerGets = tx[sfTakerGets];

if (saTakerPays.isMPT() || saTakerGets.isMPT())
return temMPT_NOT_SUPPORTED;

if (!isLegalNet(saTakerPays) || !isLegalNet(saTakerGets))
return temBAD_AMOUNT;

Expand Down
3 changes: 3 additions & 0 deletions src/ripple/app/tx/impl/Escrow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ EscrowCreate::preflight(PreflightContext const& ctx)
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
return ret;

if (ctx.tx[sfAmount].isMPT())
return temMPT_NOT_SUPPORTED;

if (!isXRP(ctx.tx[sfAmount]))
return temBAD_AMOUNT;

Expand Down
3 changes: 3 additions & 0 deletions src/ripple/app/tx/impl/NFTokenAcceptOffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ NFTokenAcceptOffer::preclaim(PreclaimContext const& ctx)
if (!isTesSuccess(err2))
return err2;

if ((bo && (*bo)[sfAmount].isMPT()) || (so && (*so)[sfAmount].isMPT()))
return temMPT_NOT_SUPPORTED;

if (bo && so)
{
// Brokered mode:
Expand Down
3 changes: 3 additions & 0 deletions src/ripple/app/tx/impl/NFTokenCreateOffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ NFTokenCreateOffer::preflight(PreflightContext const& ctx)
{
STAmount const amount = ctx.tx[sfAmount];

if (amount.isMPT())
return temMPT_NOT_SUPPORTED;

if (amount.negative() && ctx.rules.enabled(fixNFTokenNegOffer))
// An offer for a negative amount makes no sense.
return temBAD_AMOUNT;
Expand Down
3 changes: 3 additions & 0 deletions src/ripple/app/tx/impl/PayChan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ PayChanCreate::preflight(PreflightContext const& ctx)
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
return ret;

if (ctx.tx[sfAmount].isMPT())
return temMPT_NOT_SUPPORTED;

if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero))
return temBAD_AMOUNT;

Expand Down
Loading

0 comments on commit 28792f0

Please sign in to comment.