Skip to content

Commit

Permalink
Next significant iteration of MPT DEX support (payment,offer,check no…
Browse files Browse the repository at this point in the history
…t supported), not unit-tested
  • Loading branch information
gregtatcam committed Sep 25, 2024
1 parent 98abf3c commit 96c8f3c
Show file tree
Hide file tree
Showing 79 changed files with 3,458 additions and 1,287 deletions.
6 changes: 6 additions & 0 deletions include/xrpl/basics/MPTAmount.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class MPTAmount : private boost::totally_ordered<MPTAmount>,
public:
MPTAmount() = default;
constexpr MPTAmount(MPTAmount const& other) = default;
constexpr MPTAmount(beast::Zero);
constexpr MPTAmount&
operator=(MPTAmount const& other) = default;

Expand Down Expand Up @@ -102,6 +103,11 @@ constexpr MPTAmount::MPTAmount(value_type value) : value_(value)
{
}

constexpr MPTAmount::MPTAmount(beast::Zero)
{
*this = beast::zero;
}

constexpr MPTAmount& MPTAmount::operator=(beast::Zero)
{
value_ = 0;
Expand Down
84 changes: 71 additions & 13 deletions include/xrpl/protocol/AmountConversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@

#include <xrpl/basics/IOUAmount.h>
#include <xrpl/basics/XRPAmount.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/STAmount.h>

#include <type_traits>

namespace ripple {

inline STAmount
toSTAmount(IOUAmount const& iou, Issue const& iss)
toSTAmount(IOUAmount const& iou, Asset const& iss)
{
assert(iss.holds<Issue>());
bool const isNeg = iou.signum() < 0;
std::uint64_t const umant = isNeg ? -iou.mantissa() : iou.mantissa();
return STAmount(iss, umant, iou.exponent(), isNeg, STAmount::unchecked());
Expand All @@ -51,12 +53,25 @@ toSTAmount(XRPAmount const& xrp)
}

inline STAmount
toSTAmount(XRPAmount const& xrp, Issue const& iss)
toSTAmount(XRPAmount const& xrp, Asset const& iss)
{
assert(isXRP(iss.account) && isXRP(iss.currency));
assert(isXRP(iss));
return toSTAmount(xrp);
}

inline STAmount
toSTAmount(MPTAmount const& mpt)
{
return STAmount(mpt, noMPT());
}

inline STAmount
toSTAmount(MPTAmount const& mpt, Asset const& iss)
{
assert(iss.holds<MPTIssue>());
return STAmount(mpt, iss.get<MPTIssue>());
}

template <class T>
T
toAmount(STAmount const& amt) = delete;
Expand Down Expand Up @@ -94,6 +109,19 @@ toAmount<XRPAmount>(STAmount const& amt)
return XRPAmount(sMant);
}

template <>
inline MPTAmount
toAmount<MPTAmount>(STAmount const& amt)
{
assert(amt.mantissa() < std::numeric_limits<std::int64_t>::max());
assert(amt.holds<MPTIssue>());
bool const isNeg = amt.negative();
std::int64_t const sMant =
isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();

return MPTAmount(sMant);
}

template <class T>
T
toAmount(IOUAmount const& amt) = delete;
Expand All @@ -116,10 +144,21 @@ toAmount<XRPAmount>(XRPAmount const& amt)
return amt;
}

template <class T>
T
toAmount(MPTAmount const& amt) = delete;

template <>
inline MPTAmount
toAmount<MPTAmount>(MPTAmount const& amt)
{
return amt;
}

template <typename T>
T
toAmount(
Issue const& issue,
Asset const& issue,
Number const& n,
Number::rounding_mode mode = Number::getround())
{
Expand All @@ -131,6 +170,8 @@ toAmount(
return IOUAmount(n);
else if constexpr (std::is_same_v<XRPAmount, T>)
return XRPAmount(static_cast<std::int64_t>(n));
else if constexpr (std::is_same_v<MPTAmount, T>)
return MPTAmount(static_cast<std::int64_t>(n));
else if constexpr (std::is_same_v<STAmount, T>)
{
if (isXRP(issue))
Expand All @@ -146,18 +187,31 @@ toAmount(

template <typename T>
T
toMaxAmount(Issue const& issue)
toMaxAmount(Asset const& issue)
{
if constexpr (std::is_same_v<IOUAmount, T>)
return IOUAmount(STAmount::cMaxValue, STAmount::cMaxOffset);
else if constexpr (std::is_same_v<XRPAmount, T>)
return XRPAmount(static_cast<std::int64_t>(STAmount::cMaxNativeN));
else if constexpr (std::is_same_v<MPTAmount, T>)
return MPTAmount(maxMPTokenAmount);
else if constexpr (std::is_same_v<STAmount, T>)
{
if (isXRP(issue))
return STAmount(
issue, static_cast<std::int64_t>(STAmount::cMaxNativeN));
return STAmount(issue, STAmount::cMaxValue, STAmount::cMaxOffset);
return std::visit(
[]<ValidIssueType TIss>(TIss const& issue_) {
if constexpr (std::is_same_v<TIss, Issue>)
{
if (isXRP(issue_))
return STAmount(
issue_,
static_cast<std::int64_t>(STAmount::cMaxNativeN));
return STAmount(
issue_, STAmount::cMaxValue, STAmount::cMaxOffset);
}
else
return STAmount(issue_, maxMPTokenAmount);
},
issue.value());
}
else
{
Expand All @@ -168,23 +222,25 @@ toMaxAmount(Issue const& issue)

inline STAmount
toSTAmount(
Issue const& issue,
Asset const& issue,
Number const& n,
Number::rounding_mode mode = Number::getround())
{
return toAmount<STAmount>(issue, n, mode);
}

template <typename T>
Issue
getIssue(T const& amt)
Asset
getAsset(T const& amt)
{
if constexpr (std::is_same_v<IOUAmount, T>)
return noIssue();
else if constexpr (std::is_same_v<XRPAmount, T>)
return xrpIssue();
else if constexpr (std::is_same_v<MPTAmount, T>)
return noMPT();
else if constexpr (std::is_same_v<STAmount, T>)
return amt.issue();
return amt.asset();
else
{
constexpr bool alwaysFalse = !std::is_same_v<T, T>;
Expand All @@ -200,6 +256,8 @@ get(STAmount const& a)
return a.iou();
else if constexpr (std::is_same_v<XRPAmount, T>)
return a.xrp();
else if constexpr (std::is_same_v<MPTAmount, T>)
return a.mpt();
else if constexpr (std::is_same_v<STAmount, T>)
return a;
else
Expand Down
58 changes: 40 additions & 18 deletions include/xrpl/protocol/Asset.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,12 @@
#define RIPPLE_PROTOCOL_ASSET_H_INCLUDED

#include <xrpl/basics/base_uint.h>
#include <xrpl/protocol/Concepts.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/MPTIssue.h>

namespace ripple {

class Asset;

template <typename TIss>
concept ValidIssueType =
std::is_same_v<TIss, Issue> || std::is_same_v<TIss, MPTIssue>;

template <typename A>
concept AssetType = std::is_same_v<A, Asset> ||
std::is_convertible_v<A, Issue> || std::is_convertible_v<A, MPTIssue>;

class Asset
{
private:
Expand All @@ -51,11 +42,9 @@ class Asset

Asset(MPTID const& mpt);

explicit
operator Issue() const;
explicit operator Issue() const;

explicit
operator MPTIssue() const;
explicit operator MPTIssue() const;

AccountID const&
getIssuer() const;
Expand Down Expand Up @@ -185,12 +174,45 @@ isXRP(Asset const& asset)
return asset.holds<Issue>() && isXRP(asset.get<Issue>());
}

template <typename Cb>
decltype(auto)
invokeForAsset(Asset const& asset, Cb&& f)
inline bool
isConsistent(Asset const& issue)
{
return std::visit(
[&]<typename TIss>(TIss const& issue_) {
if constexpr (std::is_same_v<TIss, Issue>)
return isConsistent(issue_);
else
return true;
},
issue.value());
}

inline bool
validAsset(Asset const& issue)
{
return std::visit(
[&](auto const& issue) { return f(issue); }, asset.value());
[&]<typename TIss>(TIss const& issue_) {
if constexpr (std::is_same_v<TIss, Issue>)
return isConsistent(issue_) && issue_.currency != badCurrency();
else
return true;
},
issue.value());
}

template <class Hasher>
void
hash_append(Hasher& h, Asset const& r)
{
using beast::hash_append;
std::visit(
[&]<ValidIssueType TIss>(TIss const& issue) {
if constexpr (std::is_same_v<TIss, Issue>)
hash_append(h, issue.currency, issue.account);
else
hash_append(h, issue.getMptID());
},
r.value());
}

std::string
Expand Down
41 changes: 22 additions & 19 deletions include/xrpl/protocol/Book.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,22 +141,27 @@ struct hash<ripple::Asset>
value_type
operator()(argument_type const& issue) const
{
return std::visit([&]<ripple::ValidIssueType TIss>(TIss const& issue_) {
if constexpr (std::is_same_v<TIss, ripple::Issue>)
{
value_type result(
currency_hash_type::member(issue_.currency));
if (!isXRP(issue_.currency))
boost::hash_combine(
result, issuer_hash_type::member(issue_.account));
return result;
}
else if constexpr (std::is_same_v<TIss, ripple::MPTIssue>)
{
value_type result(mpt_hash_type::member(issue_.getMptID()));
return result;
}
}, issue.value());
return std::visit(
[&]<ripple::ValidIssueType TIss>(TIss const& issue_) {
if constexpr (std::is_same_v<TIss, ripple::Issue>)
{
value_type result(currency_hash_type::member(
issue.get<ripple::Issue>().currency));
if (!isXRP(issue.get<ripple::Issue>().currency))
boost::hash_combine(
result,
issuer_hash_type::member(
issue.get<ripple::Issue>().account));
return result;
}
else if constexpr (std::is_same_v<TIss, ripple::MPTIssue>)
{
value_type result(mpt_hash_type::member(
issue.get<ripple::MPTIssue>().getMptID()));
return result;
}
},
issue.value());
}
};

Expand All @@ -166,7 +171,7 @@ template <>
struct hash<ripple::Book>
{
private:
using hasher = std::hash<ripple::Issue>;
using hasher = std::hash<ripple::Asset>;

hasher m_hasher;

Expand Down Expand Up @@ -207,8 +212,6 @@ struct hash<ripple::Asset> : std::hash<ripple::Asset>
explicit hash() = default;

using Base = std::hash<ripple::Asset>;
// VFALCO NOTE broken in vs2012
// using Base::Base; // inherit ctors
};

template <>
Expand Down
Loading

0 comments on commit 96c8f3c

Please sign in to comment.