Always enable fix1141 dated July 1, 2016 17:00:00 UTC

This commit is contained in:
Scott Schurr
2019-12-09 18:24:37 -08:00
committed by Manoj doshi
parent fc0a082700
commit a176f58a92
8 changed files with 70 additions and 226 deletions

View File

@@ -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)

View File

@@ -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_)

View File

@@ -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())

View File

@@ -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);

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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"];

View File

@@ -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);
{