mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-26 22:15:52 +00:00
Compare commits
3 Commits
ripple/was
...
pratik/Ret
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ef9db4d9a | ||
|
|
6e1b53847b | ||
|
|
89f42b91e8 |
@@ -195,38 +195,6 @@ mulRatio(
|
|||||||
std::uint32_t den,
|
std::uint32_t den,
|
||||||
bool roundUp);
|
bool roundUp);
|
||||||
|
|
||||||
// Since many uses of the number class do not have access to a ledger,
|
|
||||||
// getSTNumberSwitchover needs to be globally accessible.
|
|
||||||
|
|
||||||
bool
|
|
||||||
getSTNumberSwitchover();
|
|
||||||
|
|
||||||
void
|
|
||||||
setSTNumberSwitchover(bool v);
|
|
||||||
|
|
||||||
/** RAII class to set and restore the Number switchover.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class NumberSO
|
|
||||||
{
|
|
||||||
bool saved_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
~NumberSO()
|
|
||||||
{
|
|
||||||
setSTNumberSwitchover(saved_);
|
|
||||||
}
|
|
||||||
|
|
||||||
NumberSO(NumberSO const&) = delete;
|
|
||||||
NumberSO&
|
|
||||||
operator=(NumberSO const&) = delete;
|
|
||||||
|
|
||||||
explicit NumberSO(bool v) : saved_(getSTNumberSwitchover())
|
|
||||||
{
|
|
||||||
setSTNumberSwitchover(v);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ XRPL_FEATURE(Clawback, Supported::yes, VoteBehavior::DefaultNo
|
|||||||
XRPL_FIX (ReducedOffersV1, Supported::yes, VoteBehavior::DefaultNo)
|
XRPL_FIX (ReducedOffersV1, Supported::yes, VoteBehavior::DefaultNo)
|
||||||
XRPL_FIX (NFTokenRemint, Supported::yes, VoteBehavior::DefaultNo)
|
XRPL_FIX (NFTokenRemint, Supported::yes, VoteBehavior::DefaultNo)
|
||||||
XRPL_FIX (NonFungibleTokensV1_2, Supported::yes, VoteBehavior::DefaultNo)
|
XRPL_FIX (NonFungibleTokensV1_2, Supported::yes, VoteBehavior::DefaultNo)
|
||||||
XRPL_FIX (UniversalNumber, Supported::yes, VoteBehavior::DefaultNo)
|
|
||||||
XRPL_FEATURE(XRPFees, Supported::yes, VoteBehavior::DefaultNo)
|
XRPL_FEATURE(XRPFees, Supported::yes, VoteBehavior::DefaultNo)
|
||||||
XRPL_FEATURE(DisallowIncoming, Supported::yes, VoteBehavior::DefaultNo)
|
XRPL_FEATURE(DisallowIncoming, Supported::yes, VoteBehavior::DefaultNo)
|
||||||
XRPL_FEATURE(ImmediateOfferKilled, Supported::yes, VoteBehavior::DefaultNo)
|
XRPL_FEATURE(ImmediateOfferKilled, Supported::yes, VoteBehavior::DefaultNo)
|
||||||
@@ -144,6 +143,7 @@ XRPL_RETIRE(fixCheckThreading)
|
|||||||
XRPL_RETIRE(fixRmSmallIncreasedQOffers)
|
XRPL_RETIRE(fixRmSmallIncreasedQOffers)
|
||||||
XRPL_RETIRE(fixSTAmountCanonicalize)
|
XRPL_RETIRE(fixSTAmountCanonicalize)
|
||||||
XRPL_RETIRE(fixTakerDryOfferRemoval)
|
XRPL_RETIRE(fixTakerDryOfferRemoval)
|
||||||
|
XRPL_RETIRE(fixUniversalNumber)
|
||||||
XRPL_RETIRE(CryptoConditions)
|
XRPL_RETIRE(CryptoConditions)
|
||||||
XRPL_RETIRE(Escrow)
|
XRPL_RETIRE(Escrow)
|
||||||
XRPL_RETIRE(EnforceInvariants)
|
XRPL_RETIRE(EnforceInvariants)
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ ammAuctionTimeSlot(std::uint64_t current, STObject const& auctionSlot)
|
|||||||
bool
|
bool
|
||||||
ammEnabled(Rules const& rules)
|
ammEnabled(Rules const& rules)
|
||||||
{
|
{
|
||||||
return rules.enabled(featureAMM) && rules.enabled(fixUniversalNumber);
|
return rules.enabled(featureAMM);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|||||||
@@ -35,32 +35,8 @@
|
|||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
// Use a static inside a function to help prevent order-of-initialzation issues
|
|
||||||
LocalValue<bool>&
|
|
||||||
getStaticSTNumberSwitchover()
|
|
||||||
{
|
|
||||||
static LocalValue<bool> r{true};
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
bool
|
|
||||||
getSTNumberSwitchover()
|
|
||||||
{
|
|
||||||
return *getStaticSTNumberSwitchover();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
setSTNumberSwitchover(bool v)
|
|
||||||
{
|
|
||||||
*getStaticSTNumberSwitchover() = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The range for the mantissa when normalized */
|
/* The range for the mantissa when normalized */
|
||||||
static std::int64_t constexpr minMantissa = 1000000000000000ull;
|
static std::int64_t constexpr minMantissa = 1000000000000000ull;
|
||||||
static std::int64_t constexpr maxMantissa = 9999999999999999ull;
|
|
||||||
/* The range for the exponent when normalized */
|
/* The range for the exponent when normalized */
|
||||||
static int constexpr minExponent = -96;
|
static int constexpr minExponent = -96;
|
||||||
static int constexpr maxExponent = 80;
|
static int constexpr maxExponent = 80;
|
||||||
@@ -80,49 +56,13 @@ IOUAmount::normalize()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getSTNumberSwitchover())
|
Number const v{mantissa_, exponent_};
|
||||||
{
|
mantissa_ = v.mantissa();
|
||||||
Number const v{mantissa_, exponent_};
|
exponent_ = v.exponent();
|
||||||
mantissa_ = v.mantissa();
|
|
||||||
exponent_ = v.exponent();
|
|
||||||
if (exponent_ > maxExponent)
|
|
||||||
Throw<std::overflow_error>("value overflow");
|
|
||||||
if (exponent_ < minExponent)
|
|
||||||
*this = beast::zero;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool const negative = (mantissa_ < 0);
|
|
||||||
|
|
||||||
if (negative)
|
|
||||||
mantissa_ = -mantissa_;
|
|
||||||
|
|
||||||
while ((mantissa_ < minMantissa) && (exponent_ > minExponent))
|
|
||||||
{
|
|
||||||
mantissa_ *= 10;
|
|
||||||
--exponent_;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (mantissa_ > maxMantissa)
|
|
||||||
{
|
|
||||||
if (exponent_ >= maxExponent)
|
|
||||||
Throw<std::overflow_error>("IOUAmount::normalize");
|
|
||||||
|
|
||||||
mantissa_ /= 10;
|
|
||||||
++exponent_;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((exponent_ < minExponent) || (mantissa_ < minMantissa))
|
|
||||||
{
|
|
||||||
*this = beast::zero;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exponent_ > maxExponent)
|
if (exponent_ > maxExponent)
|
||||||
Throw<std::overflow_error>("value overflow");
|
Throw<std::overflow_error>("value overflow");
|
||||||
|
if (exponent_ < minExponent)
|
||||||
if (negative)
|
*this = beast::zero;
|
||||||
mantissa_ = -mantissa_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IOUAmount::IOUAmount(Number const& other)
|
IOUAmount::IOUAmount(Number const& other)
|
||||||
@@ -146,37 +86,7 @@ IOUAmount::operator+=(IOUAmount const& other)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getSTNumberSwitchover())
|
*this = IOUAmount{Number{*this} + Number{other}};
|
||||||
{
|
|
||||||
*this = IOUAmount{Number{*this} + Number{other}};
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
auto m = other.mantissa_;
|
|
||||||
auto e = other.exponent_;
|
|
||||||
|
|
||||||
while (exponent_ < e)
|
|
||||||
{
|
|
||||||
mantissa_ /= 10;
|
|
||||||
++exponent_;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (e < exponent_)
|
|
||||||
{
|
|
||||||
m /= 10;
|
|
||||||
++e;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This addition cannot overflow an std::int64_t but we may throw from
|
|
||||||
// normalize if the result isn't representable.
|
|
||||||
mantissa_ += m;
|
|
||||||
|
|
||||||
if (mantissa_ >= -10 && mantissa_ <= 10)
|
|
||||||
{
|
|
||||||
*this = beast::zero;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
normalize();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -385,53 +385,9 @@ operator+(STAmount const& v1, STAmount const& v2)
|
|||||||
if (v1.holds<MPTIssue>())
|
if (v1.holds<MPTIssue>())
|
||||||
return {v1.mAsset, v1.mpt().value() + v2.mpt().value()};
|
return {v1.mAsset, v1.mpt().value() + v2.mpt().value()};
|
||||||
|
|
||||||
if (getSTNumberSwitchover())
|
auto x = v1;
|
||||||
{
|
x = v1.iou() + v2.iou();
|
||||||
auto x = v1;
|
return x;
|
||||||
x = v1.iou() + v2.iou();
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ov1 = v1.exponent(), ov2 = v2.exponent();
|
|
||||||
std::int64_t vv1 = static_cast<std::int64_t>(v1.mantissa());
|
|
||||||
std::int64_t vv2 = static_cast<std::int64_t>(v2.mantissa());
|
|
||||||
|
|
||||||
if (v1.negative())
|
|
||||||
vv1 = -vv1;
|
|
||||||
|
|
||||||
if (v2.negative())
|
|
||||||
vv2 = -vv2;
|
|
||||||
|
|
||||||
while (ov1 < ov2)
|
|
||||||
{
|
|
||||||
vv1 /= 10;
|
|
||||||
++ov1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (ov2 < ov1)
|
|
||||||
{
|
|
||||||
vv2 /= 10;
|
|
||||||
++ov2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This addition cannot overflow an std::int64_t. It can overflow an
|
|
||||||
// STAmount and the constructor will throw.
|
|
||||||
|
|
||||||
std::int64_t fv = vv1 + vv2;
|
|
||||||
|
|
||||||
if ((fv >= -10) && (fv <= 10))
|
|
||||||
return {v1.getFName(), v1.asset()};
|
|
||||||
|
|
||||||
if (fv >= 0)
|
|
||||||
return STAmount{
|
|
||||||
v1.getFName(),
|
|
||||||
v1.asset(),
|
|
||||||
static_cast<std::uint64_t>(fv),
|
|
||||||
ov1,
|
|
||||||
false};
|
|
||||||
|
|
||||||
return STAmount{
|
|
||||||
v1.getFName(), v1.asset(), static_cast<std::uint64_t>(-fv), ov1, true};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STAmount
|
STAmount
|
||||||
@@ -868,42 +824,17 @@ STAmount::canonicalize()
|
|||||||
if (mAsset.holds<MPTIssue>() && mOffset > 18)
|
if (mAsset.holds<MPTIssue>() && mOffset > 18)
|
||||||
Throw<std::runtime_error>("MPT amount out of range");
|
Throw<std::runtime_error>("MPT amount out of range");
|
||||||
|
|
||||||
if (getSTNumberSwitchover())
|
Number num(
|
||||||
{
|
mIsNegative ? -mValue : mValue, mOffset, Number::unchecked{});
|
||||||
Number num(
|
auto set = [&](auto const& val) {
|
||||||
mIsNegative ? -mValue : mValue, mOffset, Number::unchecked{});
|
mIsNegative = val.value() < 0;
|
||||||
auto set = [&](auto const& val) {
|
mValue = mIsNegative ? -val.value() : val.value();
|
||||||
mIsNegative = val.value() < 0;
|
};
|
||||||
mValue = mIsNegative ? -val.value() : val.value();
|
if (native())
|
||||||
};
|
set(XRPAmount{num});
|
||||||
if (native())
|
|
||||||
set(XRPAmount{num});
|
|
||||||
else
|
|
||||||
set(MPTAmount{num});
|
|
||||||
mOffset = 0;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
set(MPTAmount{num});
|
||||||
while (mOffset < 0)
|
mOffset = 0;
|
||||||
{
|
|
||||||
mValue /= 10;
|
|
||||||
++mOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (mOffset > 0)
|
|
||||||
{
|
|
||||||
// N.B. do not move the overflow check to after the
|
|
||||||
// multiplication
|
|
||||||
if (native() && mValue > cMaxNativeN)
|
|
||||||
Throw<std::runtime_error>(
|
|
||||||
"Native currency amount out of range");
|
|
||||||
else if (!native() && mValue > maxMPTokenAmount)
|
|
||||||
Throw<std::runtime_error>("MPT amount out of range");
|
|
||||||
|
|
||||||
mValue *= 10;
|
|
||||||
--mOffset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (native() && mValue > cMaxNativeN)
|
if (native() && mValue > cMaxNativeN)
|
||||||
Throw<std::runtime_error>("Native currency amount out of range");
|
Throw<std::runtime_error>("Native currency amount out of range");
|
||||||
@@ -913,54 +844,7 @@ STAmount::canonicalize()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getSTNumberSwitchover())
|
*this = iou();
|
||||||
{
|
|
||||||
*this = iou();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mValue == 0)
|
|
||||||
{
|
|
||||||
mOffset = -100;
|
|
||||||
mIsNegative = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((mValue < cMinValue) && (mOffset > cMinOffset))
|
|
||||||
{
|
|
||||||
mValue *= 10;
|
|
||||||
--mOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (mValue > cMaxValue)
|
|
||||||
{
|
|
||||||
if (mOffset >= cMaxOffset)
|
|
||||||
Throw<std::runtime_error>("value overflow");
|
|
||||||
|
|
||||||
mValue /= 10;
|
|
||||||
++mOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((mOffset < cMinOffset) || (mValue < cMinValue))
|
|
||||||
{
|
|
||||||
mValue = 0;
|
|
||||||
mIsNegative = false;
|
|
||||||
mOffset = -100;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mOffset > cMaxOffset)
|
|
||||||
Throw<std::runtime_error>("value overflow");
|
|
||||||
|
|
||||||
XRPL_ASSERT(
|
|
||||||
(mValue == 0) || ((mValue >= cMinValue) && (mValue <= cMaxValue)),
|
|
||||||
"ripple::STAmount::canonicalize : value inside range");
|
|
||||||
XRPL_ASSERT(
|
|
||||||
(mValue == 0) || ((mOffset >= cMinOffset) && (mOffset <= cMaxOffset)),
|
|
||||||
"ripple::STAmount::canonicalize : offset inside range");
|
|
||||||
XRPL_ASSERT(
|
|
||||||
(mValue != 0) || (mOffset != -100),
|
|
||||||
"ripple::STAmount::canonicalize : value or offset set");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1339,44 +1223,8 @@ multiply(STAmount const& v1, STAmount const& v2, Asset const& asset)
|
|||||||
return STAmount(asset, minV * maxV);
|
return STAmount(asset, minV * maxV);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getSTNumberSwitchover())
|
auto const r = Number{v1} * Number{v2};
|
||||||
{
|
return STAmount{asset, r.mantissa(), r.exponent()};
|
||||||
auto const r = Number{v1} * Number{v2};
|
|
||||||
return STAmount{asset, r.mantissa(), r.exponent()};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::uint64_t value1 = v1.mantissa();
|
|
||||||
std::uint64_t value2 = v2.mantissa();
|
|
||||||
int offset1 = v1.exponent();
|
|
||||||
int offset2 = v2.exponent();
|
|
||||||
|
|
||||||
if (v1.native() || v1.holds<MPTIssue>())
|
|
||||||
{
|
|
||||||
while (value1 < STAmount::cMinValue)
|
|
||||||
{
|
|
||||||
value1 *= 10;
|
|
||||||
--offset1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v2.native() || v2.holds<MPTIssue>())
|
|
||||||
{
|
|
||||||
while (value2 < STAmount::cMinValue)
|
|
||||||
{
|
|
||||||
value2 *= 10;
|
|
||||||
--offset2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We multiply the two mantissas (each is between 10^15
|
|
||||||
// and 10^16), so their product is in the 10^30 to 10^32
|
|
||||||
// range. Dividing their product by 10^14 maintains the
|
|
||||||
// precision, by scaling the result to 10^16 to 10^18.
|
|
||||||
return STAmount(
|
|
||||||
asset,
|
|
||||||
muldiv(value1, value2, tenTo14) + 7,
|
|
||||||
offset1 + offset2 + 14,
|
|
||||||
v1.negative() != v2.negative());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the legacy version of canonicalizeRound. It's been in use
|
// This is the legacy version of canonicalizeRound. It's been in use
|
||||||
|
|||||||
@@ -4858,25 +4858,18 @@ private:
|
|||||||
using namespace jtx;
|
using namespace jtx;
|
||||||
FeatureBitset const all{testable_amendments()};
|
FeatureBitset const all{testable_amendments()};
|
||||||
FeatureBitset const noAMM{all - featureAMM};
|
FeatureBitset const noAMM{all - featureAMM};
|
||||||
FeatureBitset const noNumber{all - fixUniversalNumber};
|
|
||||||
FeatureBitset const noAMMAndNumber{
|
|
||||||
all - featureAMM - fixUniversalNumber};
|
|
||||||
|
|
||||||
for (auto const& feature : {noAMM, noNumber, noAMMAndNumber})
|
Env env{*this, noAMM};
|
||||||
{
|
fund(env, gw, {alice}, {USD(1'000)}, Fund::All);
|
||||||
Env env{*this, feature};
|
AMM amm(env, alice, XRP(1'000), USD(1'000), ter(temDISABLED));
|
||||||
fund(env, gw, {alice}, {USD(1'000)}, Fund::All);
|
|
||||||
AMM amm(env, alice, XRP(1'000), USD(1'000), ter(temDISABLED));
|
|
||||||
|
|
||||||
env(amm.bid({.bidMax = 1000}), ter(temMALFORMED));
|
env(amm.bid({.bidMax = 1000}), ter(temMALFORMED));
|
||||||
env(amm.bid({}), ter(temDISABLED));
|
env(amm.bid({}), ter(temDISABLED));
|
||||||
amm.vote(VoteArg{.tfee = 100, .err = ter(temDISABLED)});
|
amm.vote(VoteArg{.tfee = 100, .err = ter(temDISABLED)});
|
||||||
amm.withdraw(WithdrawArg{.tokens = 100, .err = ter(temMALFORMED)});
|
amm.withdraw(WithdrawArg{.tokens = 100, .err = ter(temMALFORMED)});
|
||||||
amm.withdraw(WithdrawArg{.err = ter(temDISABLED)});
|
amm.withdraw(WithdrawArg{.err = ter(temDISABLED)});
|
||||||
amm.deposit(
|
amm.deposit(DepositArg{.asset1In = USD(100), .err = ter(temDISABLED)});
|
||||||
DepositArg{.asset1In = USD(100), .err = ter(temDISABLED)});
|
amm.ammDelete(alice, ter(temDISABLED));
|
||||||
amm.ammDelete(alice, ter(temDISABLED));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -2375,13 +2375,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite
|
|||||||
|
|
||||||
// See the impact of rounding when the nft is sold for small amounts
|
// See the impact of rounding when the nft is sold for small amounts
|
||||||
// of drops.
|
// of drops.
|
||||||
for (auto NumberSwitchOver : {true})
|
|
||||||
{
|
{
|
||||||
if (NumberSwitchOver)
|
|
||||||
env.enableFeature(fixUniversalNumber);
|
|
||||||
else
|
|
||||||
env.disableFeature(fixUniversalNumber);
|
|
||||||
|
|
||||||
// An nft with a transfer fee of 1 basis point.
|
// An nft with a transfer fee of 1 basis point.
|
||||||
uint256 const nftID =
|
uint256 const nftID =
|
||||||
token::getNextID(env, alice, 0u, tfTransferable, 1);
|
token::getNextID(env, alice, 0u, tfTransferable, 1);
|
||||||
@@ -2405,7 +2399,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite
|
|||||||
|
|
||||||
// minter sells to carol. The payment is just small enough that
|
// minter sells to carol. The payment is just small enough that
|
||||||
// alice does not get any transfer fee.
|
// alice does not get any transfer fee.
|
||||||
auto pmt = NumberSwitchOver ? drops(50000) : drops(99999);
|
auto pmt = drops(50000);
|
||||||
STAmount carolBalance = env.balance(carol);
|
STAmount carolBalance = env.balance(carol);
|
||||||
uint256 const minterSellOfferIndex =
|
uint256 const minterSellOfferIndex =
|
||||||
keylet::nftoffer(minter, env.seq(minter)).key;
|
keylet::nftoffer(minter, env.seq(minter)).key;
|
||||||
@@ -2424,7 +2418,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite
|
|||||||
STAmount beckyBalance = env.balance(becky);
|
STAmount beckyBalance = env.balance(becky);
|
||||||
uint256 const beckyBuyOfferIndex =
|
uint256 const beckyBuyOfferIndex =
|
||||||
keylet::nftoffer(becky, env.seq(becky)).key;
|
keylet::nftoffer(becky, env.seq(becky)).key;
|
||||||
pmt = NumberSwitchOver ? drops(50001) : drops(100000);
|
pmt = drops(50001);
|
||||||
env(token::createOffer(becky, nftID, pmt), token::owner(carol));
|
env(token::createOffer(becky, nftID, pmt), token::owner(carol));
|
||||||
env.close();
|
env.close();
|
||||||
env(token::acceptBuyOffer(carol, beckyBuyOfferIndex));
|
env(token::acceptBuyOffer(carol, beckyBuyOfferIndex));
|
||||||
|
|||||||
@@ -2030,53 +2030,39 @@ public:
|
|||||||
|
|
||||||
using namespace jtx;
|
using namespace jtx;
|
||||||
|
|
||||||
for (auto NumberSwitchOver : {false, true})
|
Env env{*this, features};
|
||||||
{
|
|
||||||
Env env{*this, features};
|
|
||||||
if (NumberSwitchOver)
|
|
||||||
env.enableFeature(fixUniversalNumber);
|
|
||||||
else
|
|
||||||
env.disableFeature(fixUniversalNumber);
|
|
||||||
|
|
||||||
auto const gw = Account{"gateway"};
|
auto const gw = Account{"gateway"};
|
||||||
auto const alice = Account{"alice"};
|
auto const alice = Account{"alice"};
|
||||||
auto const bob = Account{"bob"};
|
auto const bob = Account{"bob"};
|
||||||
auto const USD = gw["USD"];
|
auto const USD = gw["USD"];
|
||||||
|
|
||||||
env.fund(XRP(10000), gw, alice, bob);
|
env.fund(XRP(10000), gw, alice, bob);
|
||||||
env.close();
|
env.close();
|
||||||
|
|
||||||
env(rate(gw, 1.005));
|
env(rate(gw, 1.005));
|
||||||
|
|
||||||
env(trust(alice, USD(1000)));
|
env(trust(alice, USD(1000)));
|
||||||
env(trust(bob, USD(1000)));
|
env(trust(bob, USD(1000)));
|
||||||
env(trust(gw, alice["USD"](50)));
|
env(trust(gw, alice["USD"](50)));
|
||||||
|
|
||||||
env(pay(gw, bob, bob["USD"](1)));
|
env(pay(gw, bob, bob["USD"](1)));
|
||||||
env(pay(alice, gw, USD(50)));
|
env(pay(alice, gw, USD(50)));
|
||||||
|
|
||||||
env(trust(gw, alice["USD"](0)));
|
env(trust(gw, alice["USD"](0)));
|
||||||
|
|
||||||
env(offer(alice, USD(50), XRP(150000)));
|
env(offer(alice, USD(50), XRP(150000)));
|
||||||
env(offer(bob, XRP(100), USD(0.1)));
|
env(offer(bob, XRP(100), USD(0.1)));
|
||||||
|
|
||||||
auto jrr = ledgerEntryState(env, alice, gw, "USD");
|
auto jrr = ledgerEntryState(env, alice, gw, "USD");
|
||||||
BEAST_EXPECT(
|
BEAST_EXPECT(
|
||||||
jrr[jss::node][sfBalance.fieldName][jss::value] ==
|
jrr[jss::node][sfBalance.fieldName][jss::value] ==
|
||||||
"49.96666666666667");
|
"49.96666666666667");
|
||||||
|
|
||||||
jrr = ledgerEntryState(env, bob, gw, "USD");
|
jrr = ledgerEntryState(env, bob, gw, "USD");
|
||||||
Json::Value const bobsUSD =
|
Json::Value const bobsUSD =
|
||||||
jrr[jss::node][sfBalance.fieldName][jss::value];
|
jrr[jss::node][sfBalance.fieldName][jss::value];
|
||||||
if (!NumberSwitchOver)
|
BEAST_EXPECT(bobsUSD == "-0.9665000000333333");
|
||||||
{
|
|
||||||
BEAST_EXPECT(bobsUSD == "-0.966500000033334");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BEAST_EXPECT(bobsUSD == "-0.9665000000333333");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -700,7 +700,6 @@ public:
|
|||||||
void
|
void
|
||||||
test_toSTAmount()
|
test_toSTAmount()
|
||||||
{
|
{
|
||||||
NumberSO stNumberSO{true};
|
|
||||||
Issue const issue;
|
Issue const issue;
|
||||||
Number const n{7'518'783'80596, -5};
|
Number const n{7'518'783'80596, -5};
|
||||||
saveNumberRoundMode const save{Number::setround(Number::to_nearest)};
|
saveNumberRoundMode const save{Number::setround(Number::to_nearest)};
|
||||||
|
|||||||
@@ -300,8 +300,6 @@ TxQ::MaybeTx::apply(Application& app, OpenView& view, beast::Journal j)
|
|||||||
// If the rules or flags change, preflight again
|
// If the rules or flags change, preflight again
|
||||||
XRPL_ASSERT(
|
XRPL_ASSERT(
|
||||||
pfresult, "ripple::TxQ::MaybeTx::apply : preflight result is set");
|
pfresult, "ripple::TxQ::MaybeTx::apply : preflight result is set");
|
||||||
NumberSO stNumberSO{view.rules().enabled(fixUniversalNumber)};
|
|
||||||
|
|
||||||
if (pfresult->rules != view.rules() || pfresult->flags != flags)
|
if (pfresult->rules != view.rules() || pfresult->flags != flags)
|
||||||
{
|
{
|
||||||
JLOG(j.debug()) << "Queued transaction " << txID
|
JLOG(j.debug()) << "Queued transaction " << txID
|
||||||
@@ -733,8 +731,6 @@ TxQ::apply(
|
|||||||
ApplyFlags flags,
|
ApplyFlags flags,
|
||||||
beast::Journal j)
|
beast::Journal j)
|
||||||
{
|
{
|
||||||
NumberSO stNumberSO{view.rules().enabled(fixUniversalNumber)};
|
|
||||||
|
|
||||||
// See if the transaction is valid, properly formed,
|
// See if the transaction is valid, properly formed,
|
||||||
// etc. before doing potentially expensive queue
|
// etc. before doing potentially expensive queue
|
||||||
// replace and multi-transaction operations.
|
// replace and multi-transaction operations.
|
||||||
|
|||||||
@@ -1163,9 +1163,6 @@ Transactor::operator()()
|
|||||||
{
|
{
|
||||||
JLOG(j_.trace()) << "apply: " << ctx_.tx.getTransactionID();
|
JLOG(j_.trace()) << "apply: " << ctx_.tx.getTransactionID();
|
||||||
|
|
||||||
// raii classes for the current ledger rules.
|
|
||||||
// fixUniversalNumber predate the rulesGuard and should be replaced.
|
|
||||||
NumberSO stNumberSO{view().rules().enabled(fixUniversalNumber)};
|
|
||||||
CurrentTransactionRulesGuard currentTransctionRulesGuard(view().rules());
|
CurrentTransactionRulesGuard currentTransctionRulesGuard(view().rules());
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|||||||
@@ -138,7 +138,6 @@ template <typename PreflightChecks>
|
|||||||
ApplyResult
|
ApplyResult
|
||||||
apply(Application& app, OpenView& view, PreflightChecks&& preflightChecks)
|
apply(Application& app, OpenView& view, PreflightChecks&& preflightChecks)
|
||||||
{
|
{
|
||||||
NumberSO stNumberSO{view.rules().enabled(fixUniversalNumber)};
|
|
||||||
return doApply(preclaim(preflightChecks(), app, view), app, view);
|
return doApply(preclaim(preflightChecks(), app, view), app, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user