mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-18 18:15:50 +00:00
Always enable fix1141 dated July 1, 2016 17:00:00 UTC
This commit is contained in:
committed by
Manoj doshi
parent
fc0a082700
commit
a176f58a92
@@ -332,7 +332,6 @@ TER RippleCalc::rippleCalculate (detail::FlowDebugInfo* flowDebugInfo)
|
||||
boost::container::flat_set<uint256> unfundedOffersFromBestPaths;
|
||||
|
||||
int iPass = 0;
|
||||
auto const dcSwitch = fix1141(view.info().parentCloseTime);
|
||||
|
||||
while (resultCode == temUNCERTAIN)
|
||||
{
|
||||
@@ -351,10 +350,8 @@ TER RippleCalc::rippleCalculate (detail::FlowDebugInfo* flowDebugInfo)
|
||||
{
|
||||
// If computing the only non-dry path, and not limiting quality,
|
||||
// compute multi-quality.
|
||||
multiQuality = dcSwitch
|
||||
? !inputFlags.limitQuality &&
|
||||
((pathStateList_.size () - iDry) == 1)
|
||||
: ((pathStateList_.size () - iDry) == 1);
|
||||
multiQuality = !inputFlags.limitQuality &&
|
||||
((pathStateList_.size() - iDry) == 1);
|
||||
|
||||
// Update to current amount processed.
|
||||
pathState->reset (actualAmountIn_, actualAmountOut_);
|
||||
@@ -378,7 +375,6 @@ TER RippleCalc::rippleCalculate (detail::FlowDebugInfo* flowDebugInfo)
|
||||
if (!pathState->quality())
|
||||
{
|
||||
// Path was dry.
|
||||
|
||||
++iDry;
|
||||
}
|
||||
else if (pathState->outPass() == beast::zero)
|
||||
|
||||
@@ -26,9 +26,8 @@ namespace path {
|
||||
|
||||
TER PathCursor::advanceNode (STAmount const& amount, bool reverse, bool callerHasLiquidity) const
|
||||
{
|
||||
bool const multi = fix1141 (view ().info ().parentCloseTime)
|
||||
? (multiQuality_ || (!callerHasLiquidity && amount == beast::zero))
|
||||
: (multiQuality_ || amount == beast::zero);
|
||||
bool const multi =
|
||||
(multiQuality_ || (!callerHasLiquidity && amount == beast::zero));
|
||||
|
||||
// If the multiQuality_ is unchanged, use the PathCursor we're using now.
|
||||
if (multi == multiQuality_)
|
||||
|
||||
@@ -238,15 +238,12 @@ TER PathCursor::deliverNodeReverseImpl (
|
||||
saInPassAct,
|
||||
saOutAct > beast::zero);
|
||||
|
||||
if (fix1141(view().info().parentCloseTime))
|
||||
// The recursive call is dry this time, but we have liquidity
|
||||
// from previous calls
|
||||
if (resultCode == tecPATH_DRY && saOutAct > beast::zero)
|
||||
{
|
||||
// The recursive call is dry this time, but we have liquidity
|
||||
// from previous calls
|
||||
if (resultCode == tecPATH_DRY && saOutAct > beast::zero)
|
||||
{
|
||||
resultCode = tesSUCCESS;
|
||||
break;
|
||||
}
|
||||
resultCode = tesSUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
JLOG (j_.trace())
|
||||
|
||||
@@ -328,9 +328,6 @@ transferXRP (ApplyView& view,
|
||||
STAmount const& amount,
|
||||
beast::Journal j);
|
||||
|
||||
[[nodiscard]] NetClock::time_point const& fix1141Time ();
|
||||
[[nodiscard]] bool fix1141 (NetClock::time_point const closeTime);
|
||||
|
||||
[[nodiscard]] NetClock::time_point const& fix1274Time ();
|
||||
[[nodiscard]] bool fix1274 (NetClock::time_point const closeTime);
|
||||
|
||||
|
||||
@@ -179,46 +179,33 @@ PaymentSandbox::balanceHook (AccountID const& account,
|
||||
*/
|
||||
|
||||
auto const currency = amount.getCurrency ();
|
||||
auto const switchover = fix1141 (info ().parentCloseTime);
|
||||
|
||||
auto adjustedAmt = amount;
|
||||
if (switchover)
|
||||
auto delta = amount.zeroed ();
|
||||
auto lastBal = amount;
|
||||
auto minBal = amount;
|
||||
for (auto curSB = this; curSB; curSB = curSB->ps_)
|
||||
{
|
||||
auto delta = amount.zeroed ();
|
||||
auto lastBal = amount;
|
||||
auto minBal = amount;
|
||||
for (auto curSB = this; curSB; curSB = curSB->ps_)
|
||||
if (auto adj = curSB->tab_.adjustments (account, issuer, currency))
|
||||
{
|
||||
if (auto adj = curSB->tab_.adjustments (account, issuer, currency))
|
||||
{
|
||||
delta += adj->debits;
|
||||
lastBal = adj->origBalance;
|
||||
if (lastBal < minBal)
|
||||
minBal = lastBal;
|
||||
}
|
||||
}
|
||||
adjustedAmt = std::min(amount, lastBal - delta);
|
||||
if (rules().enabled(fix1368))
|
||||
{
|
||||
// The adjusted amount should never be larger than the balance. In
|
||||
// some circumstances, it is possible for the deferred credits table
|
||||
// to compute usable balance just slightly above what the ledger
|
||||
// calculates (but always less than the actual balance).
|
||||
adjustedAmt = std::min(adjustedAmt, minBal);
|
||||
}
|
||||
if (fix1274 (info ().parentCloseTime))
|
||||
adjustedAmt.setIssuer(amount.getIssuer());
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto curSB = this; curSB; curSB = curSB->ps_)
|
||||
{
|
||||
if (auto adj = curSB->tab_.adjustments (account, issuer, currency))
|
||||
{
|
||||
adjustedAmt -= adj->credits;
|
||||
}
|
||||
delta += adj->debits;
|
||||
lastBal = adj->origBalance;
|
||||
if (lastBal < minBal)
|
||||
minBal = lastBal;
|
||||
}
|
||||
}
|
||||
adjustedAmt = std::min(amount, lastBal - delta);
|
||||
if (rules().enabled(fix1368))
|
||||
{
|
||||
// The adjusted amount should never be larger than the balance. In
|
||||
// some circumstances, it is possible for the deferred credits table
|
||||
// to compute usable balance just slightly above what the ledger
|
||||
// calculates (but always less than the actual balance).
|
||||
adjustedAmt = std::min(adjustedAmt, minBal);
|
||||
}
|
||||
|
||||
if (fix1274 (info ().parentCloseTime))
|
||||
adjustedAmt.setIssuer(amount.getIssuer());
|
||||
|
||||
if (isXRP(issuer) && adjustedAmt < beast::zero)
|
||||
// A calculated negative XRP balance is not an error case. Consider a
|
||||
|
||||
@@ -33,19 +33,6 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
NetClock::time_point const& fix1141Time ()
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
// Fri July 1, 2016 17:00:00 UTC
|
||||
static NetClock::time_point const soTime{520707600s};
|
||||
return soTime;
|
||||
}
|
||||
|
||||
bool fix1141 (NetClock::time_point const closeTime)
|
||||
{
|
||||
return closeTime > fix1141Time();
|
||||
}
|
||||
|
||||
NetClock::time_point const& fix1274Time ()
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
@@ -281,59 +268,32 @@ xrpLiquid (ReadView const& view, AccountID const& id,
|
||||
return beast::zero;
|
||||
|
||||
// Return balance minus reserve
|
||||
if (fix1141 (view.info ().parentCloseTime))
|
||||
{
|
||||
std::uint32_t const ownerCount = confineOwnerCount (
|
||||
view.ownerCountHook (id, sle->getFieldU32 (sfOwnerCount)),
|
||||
ownerCountAdj);
|
||||
std::uint32_t const ownerCount = confineOwnerCount (
|
||||
view.ownerCountHook (id, sle->getFieldU32 (sfOwnerCount)),
|
||||
ownerCountAdj);
|
||||
|
||||
auto const reserve =
|
||||
view.fees().accountReserve(ownerCount);
|
||||
auto const reserve =
|
||||
view.fees().accountReserve(ownerCount);
|
||||
|
||||
auto const fullBalance =
|
||||
sle->getFieldAmount(sfBalance);
|
||||
auto const fullBalance =
|
||||
sle->getFieldAmount(sfBalance);
|
||||
|
||||
auto const balance = view.balanceHook(id, xrpAccount(), fullBalance);
|
||||
auto const balance = view.balanceHook(id, xrpAccount(), fullBalance);
|
||||
|
||||
STAmount amount = balance - reserve;
|
||||
if (balance < reserve)
|
||||
amount.clear ();
|
||||
STAmount amount = balance - reserve;
|
||||
if (balance < reserve)
|
||||
amount.clear ();
|
||||
|
||||
JLOG (j.trace()) << "accountHolds:" <<
|
||||
" account=" << to_string (id) <<
|
||||
" amount=" << amount.getFullText() <<
|
||||
" fullBalance=" << fullBalance.getFullText() <<
|
||||
" balance=" << balance.getFullText() <<
|
||||
" reserve=" << reserve <<
|
||||
" ownerCount=" << ownerCount <<
|
||||
" ownerCountAdj=" << ownerCountAdj;
|
||||
JLOG (j.trace()) << "accountHolds:" <<
|
||||
" account=" << to_string (id) <<
|
||||
" amount=" << amount.getFullText() <<
|
||||
" fullBalance=" << fullBalance.getFullText() <<
|
||||
" balance=" << balance.getFullText() <<
|
||||
" reserve=" << reserve <<
|
||||
" ownerCount=" << ownerCount <<
|
||||
" ownerCountAdj=" << ownerCountAdj;
|
||||
|
||||
return amount.xrp();
|
||||
}
|
||||
else
|
||||
{
|
||||
// pre-switchover
|
||||
// XRP: return balance minus reserve
|
||||
std::uint32_t const ownerCount =
|
||||
confineOwnerCount (sle->getFieldU32 (sfOwnerCount), ownerCountAdj);
|
||||
auto const reserve =
|
||||
view.fees().accountReserve(sle->getFieldU32(sfOwnerCount));
|
||||
auto const balance = sle->getFieldAmount(sfBalance);
|
||||
|
||||
STAmount amount = balance - reserve;
|
||||
if (balance < reserve)
|
||||
amount.clear ();
|
||||
|
||||
JLOG (j.trace()) << "accountHolds:" <<
|
||||
" account=" << to_string (id) <<
|
||||
" amount=" << amount.getFullText() <<
|
||||
" balance=" << balance.getFullText() <<
|
||||
" reserve=" << reserve <<
|
||||
" ownerCount=" << ownerCount <<
|
||||
" ownerCountAdj=" << ownerCountAdj;
|
||||
|
||||
return view.balanceHook(id, xrpAccount(), amount).xrp();
|
||||
}
|
||||
return amount.xrp();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1245,37 +1205,8 @@ rippleCredit (ApplyView& view,
|
||||
return terResult;
|
||||
}
|
||||
|
||||
// Calculate the fee needed to transfer IOU assets between two parties.
|
||||
static
|
||||
STAmount
|
||||
rippleTransferFee (ReadView const& view,
|
||||
AccountID const& from,
|
||||
AccountID const& to,
|
||||
AccountID const& issuer,
|
||||
STAmount const& amount,
|
||||
beast::Journal j)
|
||||
{
|
||||
if (from != issuer && to != issuer)
|
||||
{
|
||||
Rate const rate = transferRate (view, issuer);
|
||||
|
||||
if (parityRate != rate)
|
||||
{
|
||||
auto const fee = multiply (amount, rate) - amount;
|
||||
|
||||
JLOG (j.debug()) << "rippleTransferFee:" <<
|
||||
" amount=" << amount.getFullText () <<
|
||||
" fee=" << fee.getFullText ();
|
||||
|
||||
return fee;
|
||||
}
|
||||
}
|
||||
|
||||
return amount.zeroed();
|
||||
}
|
||||
|
||||
// Send regardless of limits.
|
||||
// --> saAmount: Amount/currency/issuer to deliver to reciever.
|
||||
// --> saAmount: Amount/currency/issuer to deliver to receiver.
|
||||
// <-- saActual: Amount actually cost. Sender pays fees.
|
||||
static
|
||||
TER
|
||||
@@ -1302,19 +1233,7 @@ rippleSend (ApplyView& view,
|
||||
|
||||
// Calculate the amount to transfer accounting
|
||||
// for any transfer fees:
|
||||
if (!fix1141 (view.info ().parentCloseTime))
|
||||
{
|
||||
STAmount const saTransitFee = rippleTransferFee (
|
||||
view, uSenderID, uReceiverID, issuer, saAmount, j);
|
||||
|
||||
saActual = !saTransitFee ? saAmount : saAmount + saTransitFee;
|
||||
saActual.setIssuer (issuer); // XXX Make sure this done in + above.
|
||||
}
|
||||
else
|
||||
{
|
||||
saActual = multiply (saAmount,
|
||||
transferRate (view, issuer));
|
||||
}
|
||||
saActual = multiply (saAmount, transferRate (view, issuer));
|
||||
|
||||
JLOG (j.debug()) << "rippleSend> " <<
|
||||
to_string (uSenderID) <<
|
||||
@@ -1354,19 +1273,11 @@ accountSend (ApplyView& view,
|
||||
return rippleSend (view, uSenderID, uReceiverID, saAmount, saActual, j);
|
||||
}
|
||||
|
||||
auto const fv2Switch = fix1141 (view.info ().parentCloseTime);
|
||||
if (!fv2Switch)
|
||||
{
|
||||
auto const dummyBalance = saAmount.zeroed();
|
||||
view.creditHook (uSenderID, uReceiverID, saAmount, dummyBalance);
|
||||
}
|
||||
|
||||
/* XRP send which does not check reserve and can do pure adjustment.
|
||||
* Note that sender or receiver may be null and this not a mistake; this
|
||||
* setup is used during pathfinding and it is carefully controlled to
|
||||
* ensure that transfers are balanced.
|
||||
*/
|
||||
|
||||
TER terResult (tesSUCCESS);
|
||||
|
||||
SLE::pointer sender = uSenderID != beast::zero
|
||||
@@ -1406,8 +1317,7 @@ accountSend (ApplyView& view,
|
||||
else
|
||||
{
|
||||
auto const sndBal = sender->getFieldAmount (sfBalance);
|
||||
if (fv2Switch)
|
||||
view.creditHook (uSenderID, xrpAccount (), saAmount, sndBal);
|
||||
view.creditHook (uSenderID, xrpAccount (), saAmount, sndBal);
|
||||
|
||||
// Decrement XRP balance.
|
||||
sender->setFieldAmount (sfBalance, sndBal - saAmount);
|
||||
@@ -1420,9 +1330,7 @@ accountSend (ApplyView& view,
|
||||
// Increment XRP balance.
|
||||
auto const rcvBal = receiver->getFieldAmount (sfBalance);
|
||||
receiver->setFieldAmount (sfBalance, rcvBal + saAmount);
|
||||
|
||||
if (fv2Switch)
|
||||
view.creditHook (xrpAccount (), uReceiverID, saAmount, -rcvBal);
|
||||
view.creditHook (xrpAccount (), uReceiverID, saAmount, -rcvBal);
|
||||
|
||||
view.update (receiver);
|
||||
}
|
||||
|
||||
@@ -686,23 +686,18 @@ struct Flow_test : public beast::unit_test::suite
|
||||
|
||||
Env env (*this, features);
|
||||
|
||||
auto const closeTime = fix1141Time() +
|
||||
100 * env.closed ()->info ().closeTimeResolution;
|
||||
env.close (closeTime);
|
||||
|
||||
env.fund (XRP(10000), alice, carol, gw);
|
||||
env.fund (reserve(env, 5), bob);
|
||||
env.trust (USD (1000), alice, bob, carol);
|
||||
env.trust (EUR (1000), alice, bob, carol);
|
||||
|
||||
|
||||
env (pay (gw, alice, EUR (50)));
|
||||
env (pay (gw, bob, USD (50)));
|
||||
|
||||
// Bob has _just_ slightly less than 50 xrp available
|
||||
// If his owner count changes, he will have more liquidity.
|
||||
// This is one error case to test (when Flow is used).
|
||||
// Computing the incomming xrp to the XRP/USD offer will require two
|
||||
// Computing the incoming xrp to the XRP/USD offer will require two
|
||||
// recursive calls to the EUR/XRP offer. The second call will return
|
||||
// tecPATH_DRY, but the entire path should not be marked as dry. This
|
||||
// is the second error case to test (when flowV1 is used).
|
||||
@@ -733,31 +728,20 @@ struct Flow_test : public beast::unit_test::suite
|
||||
Account const bob ("bob");
|
||||
Account const carol ("carol");
|
||||
|
||||
auto const timeDelta = Env{*this}.closed ()->info ().closeTimeResolution;
|
||||
Env env (*this, FeatureBitset{});
|
||||
|
||||
for (auto const& d : {-100 * timeDelta, +100 * timeDelta})
|
||||
{
|
||||
auto const closeTime = fix1141Time () + d ;
|
||||
Env env (*this, FeatureBitset{});
|
||||
env.close (closeTime);
|
||||
env.fund (XRP(10000), alice, bob, carol, gw);
|
||||
|
||||
env.fund (XRP(10000), alice, bob, carol, gw);
|
||||
env.trust (USD(100), alice, bob, carol);
|
||||
env (pay (gw, bob, USD (100)));
|
||||
env (offer (bob, XRP (50), USD (50)));
|
||||
env (offer (bob, XRP (100), USD (50)));
|
||||
|
||||
env.trust (USD(100), alice, bob, carol);
|
||||
env (pay (gw, bob, USD (100)));
|
||||
env (offer (bob, XRP (50), USD (50)));
|
||||
env (offer (bob, XRP (100), USD (50)));
|
||||
env (pay (alice, carol, USD (100)), path (~USD), sendmax (XRP (100)),
|
||||
txflags (tfNoRippleDirect | tfPartialPayment | tfLimitQuality),
|
||||
ter (tesSUCCESS));
|
||||
|
||||
TER const expectedResult = closeTime < fix1141Time ()
|
||||
? TER {tecPATH_DRY}
|
||||
: TER {tesSUCCESS};
|
||||
env (pay (alice, carol, USD (100)), path (~USD), sendmax (XRP (100)),
|
||||
txflags (tfNoRippleDirect | tfPartialPayment | tfLimitQuality),
|
||||
ter (expectedResult));
|
||||
|
||||
if (expectedResult == tesSUCCESS)
|
||||
env.require (balance (carol, USD (50)));
|
||||
}
|
||||
env.require (balance (carol, USD (50)));
|
||||
}
|
||||
|
||||
// Helper function that returns the reserve on an account based on
|
||||
@@ -801,10 +785,6 @@ struct Flow_test : public beast::unit_test::suite
|
||||
|
||||
Env env (*this, features);
|
||||
|
||||
auto const closeTime =
|
||||
fix1141Time () + 100 * env.closed ()->info ().closeTimeResolution;
|
||||
env.close (closeTime);
|
||||
|
||||
env.fund (XRP (1000000), gw1, gw2);
|
||||
env.close ();
|
||||
|
||||
@@ -875,10 +855,6 @@ struct Flow_test : public beast::unit_test::suite
|
||||
|
||||
Env env (*this, features);
|
||||
|
||||
auto const closeTime =
|
||||
fix1141Time () + 100 * env.closed ()->info ().closeTimeResolution;
|
||||
env.close (closeTime);
|
||||
|
||||
env.fund (XRP (1000000), gw1, gw2);
|
||||
env.close ();
|
||||
|
||||
@@ -943,11 +919,6 @@ struct Flow_test : public beast::unit_test::suite
|
||||
|
||||
Env env(*this, features);
|
||||
|
||||
// Need new behavior from `accountHolds`
|
||||
auto const closeTime = fix1141Time() +
|
||||
env.closed()->info().closeTimeResolution;
|
||||
env.close(closeTime);
|
||||
|
||||
auto const alice = Account("alice");
|
||||
auto const gw = Account("gw");
|
||||
auto const USD = gw["USD"];
|
||||
|
||||
@@ -277,19 +277,10 @@ class PaymentSandbox_test : public beast::unit_test::suite
|
||||
STAmount hugeAmt (issue, STAmount::cMaxValue, STAmount::cMaxOffset - 1,
|
||||
false, false, STAmount::unchecked{});
|
||||
|
||||
for (auto d : {-1, 1})
|
||||
{
|
||||
auto const closeTime = fix1141Time () +
|
||||
d * env.closed()->info().closeTimeResolution;
|
||||
env.close (closeTime);
|
||||
ApplyViewImpl av (&*env.current (), tapNONE);
|
||||
PaymentSandbox pv (&av);
|
||||
pv.creditHook (gw, alice, hugeAmt, -tinyAmt);
|
||||
if (closeTime > fix1141Time ())
|
||||
BEAST_EXPECT(pv.balanceHook (alice, gw, hugeAmt) == tinyAmt);
|
||||
else
|
||||
BEAST_EXPECT(pv.balanceHook (alice, gw, hugeAmt) != tinyAmt);
|
||||
}
|
||||
ApplyViewImpl av (&*env.current (), tapNONE);
|
||||
PaymentSandbox pv (&av);
|
||||
pv.creditHook (gw, alice, hugeAmt, -tinyAmt);
|
||||
BEAST_EXPECT(pv.balanceHook (alice, gw, hugeAmt) == tinyAmt);
|
||||
}
|
||||
|
||||
void testReserve(FeatureBitset features)
|
||||
@@ -314,9 +305,7 @@ class PaymentSandbox_test : public beast::unit_test::suite
|
||||
Account const alice ("alice");
|
||||
env.fund (reserve(env, 1), alice);
|
||||
|
||||
auto const closeTime = fix1141Time () +
|
||||
100 * env.closed ()->info ().closeTimeResolution;
|
||||
env.close (closeTime);
|
||||
env.close();
|
||||
ApplyViewImpl av (&*env.current (), tapNONE);
|
||||
PaymentSandbox sb (&av);
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user