-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: AMM swap rounding #5002
fix: AMM swap rounding #5002
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,8 @@ | |
#include <ripple/basics/XRPAmount.h> | ||
#include <ripple/protocol/STAmount.h> | ||
|
||
#include <type_traits> | ||
|
||
namespace ripple { | ||
|
||
inline STAmount | ||
|
@@ -130,16 +132,44 @@ toAmount( | |
saveNumberRoundMode rm(Number::getround()); | ||
if (isXRP(issue)) | ||
Number::setround(mode); | ||
|
||
if constexpr (std::is_same_v<IOUAmount, T>) | ||
return IOUAmount(n); | ||
if constexpr (std::is_same_v<XRPAmount, T>) | ||
else if constexpr (std::is_same_v<XRPAmount, T>) | ||
return XRPAmount(static_cast<std::int64_t>(n)); | ||
if constexpr (std::is_same_v<STAmount, T>) | ||
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"); | ||
} | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about using
I don't think max There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought I got a compile error without the supporting I don't object to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It builds for me without I prefer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I hear you. I don't think this is worth spending too much time on. I'm going to keep it as is. |
||
template <typename T> | ||
T | ||
toMaxAmount(Issue 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<STAmount, T>) | ||
{ | ||
if (isXRP(issue)) | ||
return STAmount( | ||
issue, static_cast<std::int64_t>(STAmount::cMaxNativeN)); | ||
return STAmount(issue, STAmount::cMaxValue, STAmount::cMaxOffset); | ||
} | ||
else | ||
{ | ||
constexpr bool alwaysFalse = !std::is_same_v<T, T>; | ||
static_assert(alwaysFalse, "Unsupported type for toMaxAmount"); | ||
} | ||
} | ||
|
||
inline STAmount | ||
|
@@ -157,10 +187,15 @@ getIssue(T const& amt) | |
{ | ||
if constexpr (std::is_same_v<IOUAmount, T>) | ||
return noIssue(); | ||
if constexpr (std::is_same_v<XRPAmount, T>) | ||
else if constexpr (std::is_same_v<XRPAmount, T>) | ||
return xrpIssue(); | ||
if constexpr (std::is_same_v<STAmount, T>) | ||
else if constexpr (std::is_same_v<STAmount, T>) | ||
return amt.issue(); | ||
else | ||
{ | ||
constexpr bool alwaysFalse = !std::is_same_v<T, T>; | ||
static_assert(alwaysFalse, "Unsupported type for getIssue"); | ||
} | ||
} | ||
|
||
template <typename T> | ||
|
@@ -169,10 +204,15 @@ get(STAmount const& a) | |
{ | ||
if constexpr (std::is_same_v<IOUAmount, T>) | ||
return a.iou(); | ||
if constexpr (std::is_same_v<XRPAmount, T>) | ||
else if constexpr (std::is_same_v<XRPAmount, T>) | ||
return a.xrp(); | ||
if constexpr (std::is_same_v<STAmount, T>) | ||
else if constexpr (std::is_same_v<STAmount, T>) | ||
return a; | ||
else | ||
{ | ||
constexpr bool alwaysFalse = !std::is_same_v<T, T>; | ||
static_assert(alwaysFalse, "Unsupported type for get"); | ||
} | ||
} | ||
|
||
} // namespace ripple | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ | |
#include <ripple/basics/base_uint.h> | ||
#include <ripple/beast/hash/uhash.h> | ||
#include <ripple/protocol/STVector256.h> | ||
|
||
#include <unordered_set> | ||
|
||
namespace ripple { | ||
|
@@ -42,9 +43,14 @@ class Rules | |
public: | ||
Rules(Rules const&) = default; | ||
|
||
Rules(Rules&&) = default; | ||
|
||
Rules& | ||
operator=(Rules const&) = default; | ||
|
||
Rules& | ||
operator=(Rules&&) = default; | ||
|
||
Rules() = delete; | ||
|
||
/** Construct an empty rule set. | ||
|
@@ -90,5 +96,36 @@ class Rules | |
operator!=(Rules const& other) const; | ||
}; | ||
|
||
std::optional<Rules> const& | ||
getCurrentTransactionRules(); | ||
|
||
void | ||
setCurrentTransactionRules(std::optional<Rules> r); | ||
|
||
/** RAII class to set and restore the current transaction rules | ||
*/ | ||
class CurrentTransactionRulesGuard | ||
{ | ||
public: | ||
explicit CurrentTransactionRulesGuard(Rules r) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This class should not be CopyConstructible nor CopyAssignable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, agreed, thanks! Fixed in |
||
: saved_(getCurrentTransactionRules()) | ||
{ | ||
setCurrentTransactionRules(std::move(r)); | ||
} | ||
|
||
~CurrentTransactionRulesGuard() | ||
{ | ||
setCurrentTransactionRules(saved_); | ||
} | ||
|
||
CurrentTransactionRulesGuard() = delete; | ||
CurrentTransactionRulesGuard(CurrentTransactionRulesGuard const&) = delete; | ||
CurrentTransactionRulesGuard& | ||
operator=(CurrentTransactionRulesGuard const&) = delete; | ||
|
||
private: | ||
std::optional<Rules> saved_; | ||
}; | ||
|
||
} // namespace ripple | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to always round upwards
getFee()
and downwardfeeMult()
. The fee is added to the pool so we want always to maximize it's effect. Can have the default just in case it needs to be changed in some instances: