Add MPTIssue to STIssue (#5200)

Replace Issue in STIssue with Asset. STIssue with MPTIssue is only used in MPT tests.
Will be used in Vault and in transactions with STIssue fields once MPT is integrated into DEX.
This commit is contained in:
Gregory Tsipenyuk
2024-12-16 17:52:48 -05:00
committed by GitHub
parent eabca8439f
commit 5cd72f2431
22 changed files with 463 additions and 143 deletions

View File

@@ -26,10 +26,17 @@
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_convertible_v<A, Asset> || std::is_convertible_v<A, Issue> ||
std::is_convertible_v<A, MPTIssue> || std::is_convertible_v<A, MPTID>;
/* Asset is an abstraction of three different issue types: XRP, IOU, MPT.
* For historical reasons, two issue types XRP and IOU are wrapped in Issue
* type. Many functions and classes there were first written for Issue
@@ -37,8 +44,10 @@ concept ValidIssueType =
*/
class Asset
{
private:
public:
using value_type = std::variant<Issue, MPTIssue>;
private:
value_type issue_;
public:
@@ -92,8 +101,8 @@ public:
friend constexpr bool
operator==(Asset const& lhs, Asset const& rhs);
friend constexpr bool
operator!=(Asset const& lhs, Asset const& rhs);
friend constexpr std::weak_ordering
operator<=>(Asset const& lhs, Asset const& rhs);
friend constexpr bool
operator==(Currency const& lhs, Asset const& rhs);
@@ -151,10 +160,22 @@ operator==(Asset const& lhs, Asset const& rhs)
rhs.issue_);
}
constexpr bool
operator!=(Asset const& lhs, Asset const& rhs)
constexpr std::weak_ordering
operator<=>(Asset const& lhs, Asset const& rhs)
{
return !(lhs == rhs);
return std::visit(
[]<ValidIssueType TLhs, ValidIssueType TRhs>(
TLhs const& lhs_, TRhs const& rhs_) {
if constexpr (std::is_same_v<TLhs, TRhs>)
return std::weak_ordering(lhs_ <=> rhs_);
else if constexpr (
std::is_same_v<TLhs, Issue> && std::is_same_v<TRhs, MPTIssue>)
return std::weak_ordering::greater;
else
return std::weak_ordering::less;
},
lhs.issue_,
rhs.issue_);
}
constexpr bool

View File

@@ -274,7 +274,7 @@ nft_sells(uint256 const& id) noexcept;
/** AMM entry */
Keylet
amm(Issue const& issue1, Issue const& issue2) noexcept;
amm(Asset const& issue1, Asset const& issue2) noexcept;
Keylet
amm(uint256 const& amm) noexcept;

View File

@@ -58,6 +58,9 @@ public:
bool
native() const;
friend constexpr std::weak_ordering
operator<=>(Issue const& lhs, Issue const& rhs);
};
bool
@@ -95,7 +98,7 @@ operator==(Issue const& lhs, Issue const& rhs)
/** Strict weak ordering. */
/** @{ */
[[nodiscard]] inline constexpr std::weak_ordering
[[nodiscard]] constexpr std::weak_ordering
operator<=>(Issue const& lhs, Issue const& rhs)
{
if (auto const c{lhs.currency <=> rhs.currency}; c != 0)

View File

@@ -54,8 +54,8 @@ public:
friend constexpr bool
operator==(MPTIssue const& lhs, MPTIssue const& rhs);
friend constexpr bool
operator!=(MPTIssue const& lhs, MPTIssue const& rhs);
friend constexpr std::weak_ordering
operator<=>(MPTIssue const& lhs, MPTIssue const& rhs);
bool
native() const
@@ -70,10 +70,10 @@ operator==(MPTIssue const& lhs, MPTIssue const& rhs)
return lhs.mptID_ == rhs.mptID_;
}
constexpr bool
operator!=(MPTIssue const& lhs, MPTIssue const& rhs)
constexpr std::weak_ordering
operator<=>(MPTIssue const& lhs, MPTIssue const& rhs)
{
return !(lhs == rhs);
return lhs.mptID_ <=> rhs.mptID_;
}
/** MPT is a non-native token.

View File

@@ -40,7 +40,7 @@ enum SOEStyle {
};
/** Amount fields that can support MPT */
enum SOETxMPTAmount { soeMPTNone, soeMPTSupported, soeMPTNotSupported };
enum SOETxMPTIssue { soeMPTNone, soeMPTSupported, soeMPTNotSupported };
//------------------------------------------------------------------------------
@@ -50,7 +50,7 @@ class SOElement
// Use std::reference_wrapper so SOElement can be stored in a std::vector.
std::reference_wrapper<SField const> sField_;
SOEStyle style_;
SOETxMPTAmount supportMpt_ = soeMPTNone;
SOETxMPTIssue supportMpt_ = soeMPTNone;
private:
void
@@ -72,10 +72,13 @@ public:
{
init(fieldName);
}
template <typename T>
requires(std::is_same_v<T, STAmount> || std::is_same_v<T, STIssue>)
SOElement(
TypedField<STAmount> const& fieldName,
TypedField<T> const& fieldName,
SOEStyle style,
SOETxMPTAmount supportMpt = soeMPTNotSupported)
SOETxMPTIssue supportMpt = soeMPTNotSupported)
: sField_(fieldName), style_(style), supportMpt_(supportMpt)
{
init(fieldName);
@@ -93,7 +96,7 @@ public:
return style_;
}
SOETxMPTAmount
SOETxMPTIssue
supportMPT() const
{
return supportMpt_;

View File

@@ -36,11 +36,6 @@
namespace ripple {
template <typename A>
concept AssetType =
std::is_same_v<A, Asset> || std::is_convertible_v<A, Issue> ||
std::is_convertible_v<A, MPTIssue> || std::is_convertible_v<A, MPTID>;
// Internal form:
// 1: If amount is zero, then value is zero and offset is -100
// 2: Otherwise:

View File

@@ -21,7 +21,7 @@
#define RIPPLE_PROTOCOL_STISSUE_H_INCLUDED
#include <xrpl/basics/CountedObject.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STBase.h>
#include <xrpl/protocol/Serializer.h>
@@ -31,31 +31,40 @@ namespace ripple {
class STIssue final : public STBase, CountedObject<STIssue>
{
private:
Issue issue_{xrpIssue()};
Asset asset_{xrpIssue()};
public:
using value_type = Issue;
using value_type = Asset;
STIssue() = default;
explicit STIssue(SerialIter& sit, SField const& name);
explicit STIssue(SField const& name, Issue const& issue);
template <AssetType A>
explicit STIssue(SField const& name, A const& issue);
explicit STIssue(SField const& name);
Issue const&
issue() const;
template <ValidIssueType TIss>
TIss const&
get() const;
Issue const&
template <ValidIssueType TIss>
bool
holds() const;
value_type const&
value() const noexcept;
void
setIssue(Issue const& issue);
setIssue(Asset const& issue);
SerializedTypeID
getSType() const override;
std::string
getText() const override;
Json::Value getJson(JsonOptions) const override;
void
@@ -67,6 +76,18 @@ public:
bool
isDefault() const override;
friend constexpr bool
operator==(STIssue const& lhs, STIssue const& rhs);
friend constexpr std::weak_ordering
operator<=>(STIssue const& lhs, STIssue const& rhs);
friend constexpr bool
operator==(STIssue const& lhs, Asset const& rhs);
friend constexpr std::weak_ordering
operator<=>(STIssue const& lhs, Asset const& rhs);
private:
STBase*
copy(std::size_t n, void* buf) const override;
@@ -76,59 +97,72 @@ private:
friend class detail::STVar;
};
template <AssetType A>
STIssue::STIssue(SField const& name, A const& asset)
: STBase{name}, asset_{asset}
{
if (holds<Issue>() && !isConsistent(asset_.get<Issue>()))
Throw<std::runtime_error>(
"Invalid asset: currency and account native mismatch");
}
STIssue
issueFromJson(SField const& name, Json::Value const& v);
inline Issue const&
STIssue::issue() const
template <ValidIssueType TIss>
bool
STIssue::holds() const
{
return issue_;
return asset_.holds<TIss>();
}
inline Issue const&
template <ValidIssueType TIss>
TIss const&
STIssue::get() const
{
if (!holds<TIss>(asset_))
Throw<std::runtime_error>("Asset doesn't hold the requested issue");
return std::get<TIss>(asset_);
}
inline STIssue::value_type const&
STIssue::value() const noexcept
{
return issue_;
return asset_;
}
inline void
STIssue::setIssue(Issue const& issue)
STIssue::setIssue(Asset const& asset)
{
if (isXRP(issue_.currency) != isXRP(issue_.account))
if (holds<Issue>() && !isConsistent(asset_.get<Issue>()))
Throw<std::runtime_error>(
"invalid issue: currency and account native mismatch");
"Invalid asset: currency and account native mismatch");
issue_ = issue;
asset_ = asset;
}
inline bool
constexpr bool
operator==(STIssue const& lhs, STIssue const& rhs)
{
return lhs.issue() == rhs.issue();
return lhs.asset_ == rhs.asset_;
}
inline bool
operator!=(STIssue const& lhs, STIssue const& rhs)
constexpr std::weak_ordering
operator<=>(STIssue const& lhs, STIssue const& rhs)
{
return !operator==(lhs, rhs);
return lhs.asset_ <=> rhs.asset_;
}
inline bool
operator<(STIssue const& lhs, STIssue const& rhs)
constexpr bool
operator==(STIssue const& lhs, Asset const& rhs)
{
return lhs.issue() < rhs.issue();
return lhs.asset_ == rhs;
}
inline bool
operator==(STIssue const& lhs, Issue const& rhs)
constexpr std::weak_ordering
operator<=>(STIssue const& lhs, Asset const& rhs)
{
return lhs.issue() == rhs;
}
inline bool
operator<(STIssue const& lhs, Issue const& rhs)
{
return lhs.issue() < rhs;
return lhs.asset_ <=> rhs;
}
} // namespace ripple

View File

@@ -170,7 +170,7 @@ STXChainBridge::lockingChainDoor() const
inline Issue const&
STXChainBridge::lockingChainIssue() const
{
return lockingChainIssue_.value();
return lockingChainIssue_.value().get<Issue>();
};
inline AccountID const&
@@ -182,7 +182,7 @@ STXChainBridge::issuingChainDoor() const
inline Issue const&
STXChainBridge::issuingChainIssue() const
{
return issuingChainIssue_.value();
return issuingChainIssue_.value().get<Issue>();
};
inline STXChainBridge::value_type const&