Skip to content

Commit

Permalink
MPT integration into DEX
Browse files Browse the repository at this point in the history
  • Loading branch information
gregtatcam committed Aug 30, 2024
1 parent 57c21a6 commit c02197d
Show file tree
Hide file tree
Showing 45 changed files with 1,607 additions and 990 deletions.
4 changes: 2 additions & 2 deletions include/xrpl/protocol/AccountID.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

#include <xrpl/protocol/tokens.h>
// VFALCO Uncomment when the header issues are resolved
//#include <ripple/protocol/PublicKey.h>
// #include <ripple/protocol/PublicKey.h>
#include <xrpl/basics/UnorderedContainers.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/json/json_value.h>
Expand Down Expand Up @@ -87,7 +87,7 @@ bool
to_issuer(AccountID&, std::string const&);

// DEPRECATED Should be checking the currency or native flag
inline bool
inline constexpr bool
isXRP(AccountID const& c)
{
return c == beast::zero;
Expand Down
54 changes: 39 additions & 15 deletions include/xrpl/protocol/AmountConversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,19 @@

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

#include <type_traits>

namespace ripple {

template <typename Amnt, typename Iss>
concept ValidAmountIssue = (std::is_same_v<Amnt, STMPTAmount> &&
std::is_same_v<Iss, MPTIssue>) ||
(!std::is_same_v<Amnt, STMPTAmount> && std::is_same_v<Iss, Issue>);

inline STAmount
toSTAmount(IOUAmount const& iou, Issue const& iss)
{
Expand Down Expand Up @@ -63,6 +70,12 @@ toSTAmount(XRPAmount const& xrp, Issue const& iss)
return toSTAmount(xrp);
}

inline STAmount
toSTAmount(STMPTAmount const& amount)
{
return STAmount{noIssue(), amount.value()};
}

template <class T>
T
toAmount(STAmount const& amt) = delete;
Expand Down Expand Up @@ -122,31 +135,42 @@ toAmount<XRPAmount>(XRPAmount const& amt)
return amt;
}

template <typename T>
template <typename T, typename Iss>
requires ValidAmountIssue<T, Iss>
T
toAmount(
Issue const& issue,
Iss const& issue,
Number const& n,
Number::rounding_mode mode = Number::getround())
{
saveNumberRoundMode rm(Number::getround());
if (isXRP(issue))
Number::setround(mode);

if constexpr (std::is_same_v<IOUAmount, T>)
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<STAmount, T>)
if constexpr (std::is_same_v<Iss, Issue>)
{
saveNumberRoundMode rm(Number::getround());
if (isXRP(issue))
return STAmount(issue, static_cast<std::int64_t>(n));
return STAmount(issue, n.mantissa(), n.exponent());
Number::setround(mode);

if constexpr (std::is_same_v<IOUAmount, T>)
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<STAmount, T>)
{
if (isXRP(issue))
return STAmount(issue, static_cast<std::int64_t>(n));
return STAmount(issue, n.mantissa(), n.exponent());
}
else
{
constexpr bool alwaysFalse = !std::is_same_v<T, T>;
static_assert(alwaysFalse, "Unsupported type for toAmount");
}
}
else
{
constexpr bool alwaysFalse = !std::is_same_v<T, T>;
static_assert(alwaysFalse, "Unsupported type for toAmount");
saveNumberRoundMode rm(mode);
if (n > maxMPTokenAmount)
Throw<std::runtime_error>("MPT overflow");
return STMPTAmount{issue, static_cast<std::int64_t>(n)};
}
}

Expand Down
70 changes: 57 additions & 13 deletions include/xrpl/protocol/Book.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
#define RIPPLE_PROTOCOL_BOOK_H_INCLUDED

#include <xrpl/basics/CountedObject.h>
#include <xrpl/protocol/CommonConstraints.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/MPTIssue.h>
#include <boost/utility/base_from_member.hpp>

namespace ripple {
Expand All @@ -33,14 +35,15 @@ namespace ripple {
class Book final : public CountedObject<Book>
{
public:
Issue in;
Issue out;
std::variant<Issue, MPTIssue> in;
std::variant<Issue, MPTIssue> out;

Book()
{
}

Book(Issue const& in_, Issue const& out_) : in(in_), out(out_)
template <typename TIn, typename TOut>
Book(TIn const& in_, TOut const& out_) : in(in_), out(out_)
{
}
};
Expand All @@ -59,7 +62,8 @@ void
hash_append(Hasher& h, Book const& b)
{
using beast::hash_append;
hash_append(h, b.in, b.out);
std::visit(
[&](auto&& in, auto&& out) { hash_append(h, in, out); }, b.in, b.out);
}

Book
Expand All @@ -79,9 +83,23 @@ operator==(Book const& lhs, Book const& rhs)
[[nodiscard]] inline constexpr std::weak_ordering
operator<=>(Book const& lhs, Book const& rhs)
{
if (auto const c{lhs.in <=> rhs.in}; c != 0)
return c;
return lhs.out <=> rhs.out;
return std::visit(
[&]<typename LIn, typename LOut, typename RIn, typename ROut>(
LIn&& lin, LOut&& lout, RIn& rin, ROut&& rout) {
if constexpr (
std::is_same_v<LIn, RIn> && std::is_same_v<LOut, ROut>)
{
if (auto const c{lin <=> rin}; c != 0)
return c;
return lout <=> rout;
}
else
return std::weak_ordering::less;
},
lhs.in,
lhs.out,
rhs.in,
rhs.out);
}
/** @} */

Expand Down Expand Up @@ -119,15 +137,36 @@ struct hash<ripple::Issue>
}
};

template <>
struct hash<ripple::MPTIssue>
{
public:
explicit hash() = default;
using value_type = std::size_t;
using argument_type = ripple::MPTIssue;

value_type
operator()(argument_type const& value) const
{
return ::beast::uhash<>{}(value.getMptID());
}
};

//------------------------------------------------------------------------------

template <>
struct hash<ripple::Book>
{
private:
using hasher = std::hash<ripple::Issue>;

hasher m_hasher;
template <ripple::ValidIssueType Iss>
struct hasher
{
std::size_t
operator()(Iss const& issue) const
{
return hash<Iss>{}(issue);
}
};

public:
explicit hash() = default;
Expand All @@ -138,9 +177,14 @@ struct hash<ripple::Book>
value_type
operator()(argument_type const& value) const
{
value_type result(m_hasher(value.in));
boost::hash_combine(result, m_hasher(value.out));
return result;
return std::visit(
[&]<typename TIn, typename TOut>(TIn const& in, TOut const& out) {
value_type result(hasher<TIn>()(in));
boost::hash_combine(result, hasher<TOut>()(out));
return result;
},
value.in,
value.out);
}
};

Expand Down
50 changes: 50 additions & 0 deletions include/xrpl/protocol/CommonConstraints.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2024 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================

#ifndef RIPPLE_PROTOCOL_COMMONCONSTRAINTS_H_INCLUDED
#define RIPPLE_PROTOCOL_COMMONCONSTRAINTS_H_INCLUDED

#include <type_traits>

namespace ripple {

class STAmount;
class STMPTAmount;
class Issue;
class MPTIssue;

// clang-format off
template <typename TAmnt>
concept ValidSerialAmountType =
std::is_same_v<TAmnt, STAmount> || std::is_same_v<TAmnt, STMPTAmount>;

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

template <typename Amnt1, typename Amnt2, typename Iss>
concept ValidAmountIssueComboType =
(std::is_same_v<Amnt1, STMPTAmount> || std::is_same_v<Amnt2, STMPTAmount> ||
(std::is_same_v<Amnt1, STAmount> && std::is_same_v<Amnt2, STAmount> &&
std::is_same_v<Iss, MPTIssue>));
// clang-format on

} // namespace ripple

#endif // RIPPLE_PROTOCOL_COMMONCONSTRAINTS_H_INCLUDED
5 changes: 4 additions & 1 deletion include/xrpl/protocol/ErrorCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,11 @@ enum error_code_i {
// Oracle
rpcORACLE_MALFORMED = 94,

// MPT
rpcMPT_ISS_ID_MALFORMED = 95,

rpcLAST =
rpcORACLE_MALFORMED // rpcLAST should always equal the last code.=
rpcMPT_ISS_ID_MALFORMED // rpcLAST should always equal the last code.=
};

/** Codes returned in the `warnings` array of certain RPC commands.
Expand Down
3 changes: 2 additions & 1 deletion include/xrpl/protocol/Feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ namespace detail {
// Feature.cpp. Because it's only used to reserve storage, and determine how
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
// the actual number of amendments. A LogicError on startup will verify this.
static constexpr std::size_t numFeatures = 80;
static constexpr std::size_t numFeatures = 81;

/** Amendments that this server supports and the default voting behavior.
Whether they are enabled depends on the Rules defined in the validated
Expand Down Expand Up @@ -373,6 +373,7 @@ extern uint256 const fixInnerObjTemplate2;
extern uint256 const featureInvariantsV1_1;
extern uint256 const fixNFTokenPageLinks;
extern uint256 const featureMPTokensV1;
extern uint256 const featureMPTokensV2;

} // namespace ripple

Expand Down
21 changes: 20 additions & 1 deletion include/xrpl/protocol/MPTIssue.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,34 @@ operator!=(MPTIssue const& lhs, MPTIssue const& rhs)
return !(lhs.mptID_ == rhs.mptID_);
}

inline bool
inline constexpr bool
isXRP(MPTID const&)
{
return false;
}

// Always true, unlike isConsistent(Issue),
// which checks currency/account consistency
inline bool
isConsistent(MPTIssue const&)
{
return true;
}

Json::Value
to_json(MPTIssue const& issue);

std::string
to_string(MPTIssue const& issue);

template <class Hasher>
void
hash_append(Hasher& h, MPTIssue const& issue)
{
using ::beast::hash_append;
hash_append(h, issue.getMptID());
}

} // namespace ripple

#endif // RIPPLE_PROTOCOL_MPTISSUE_H_INCLUDED
7 changes: 6 additions & 1 deletion include/xrpl/protocol/Quality.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,19 @@
#include <xrpl/basics/IOUAmount.h>
#include <xrpl/basics/XRPAmount.h>
#include <xrpl/protocol/AmountConversions.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STEitherAmount.h>

#include <algorithm>
#include <cstdint>
#include <ostream>

namespace ripple {

template <typename T>
concept ValidSTAmountType =
(std::is_same_v<T, STAmount> || std::is_same_v<T, IOUAmount> ||
std::is_same_v<T, XRPAmount>);

/** Represents a pair of input and output currencies.
The input currency can be converted to the output
Expand Down
10 changes: 10 additions & 0 deletions include/xrpl/protocol/Rate.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,23 @@ multiply(STMPTAmount const& amount, Rate const& rate);
STAmount
multiplyRound(STAmount const& amount, Rate const& rate, bool roundUp);

STMPTAmount
multiplyRound(STMPTAmount const& amount, Rate const& rate, bool roundUp);

STAmount
multiplyRound(
STAmount const& amount,
Rate const& rate,
Issue const& issue,
bool roundUp);

STMPTAmount
multiplyRound(
STMPTAmount const& amount,
Rate const& rate,
MPTIssue const& issue,
bool roundUp);

STAmount
divide(STAmount const& amount, Rate const& rate);

Expand Down
Loading

0 comments on commit c02197d

Please sign in to comment.