diff --git a/src/ripple/app/paths/cursor/DeliverNodeReverse.cpp b/src/ripple/app/paths/cursor/DeliverNodeReverse.cpp index deb3b7cdd2..9e2d0282f1 100644 --- a/src/ripple/app/paths/cursor/DeliverNodeReverse.cpp +++ b/src/ripple/app/paths/cursor/DeliverNodeReverse.cpp @@ -24,6 +24,15 @@ namespace ripple { namespace path { +static +bool enableDirRestartFix ( + std::uint32_t parentCloseTime) +{ + // Mon Aug 3 11:00:00am PDT + static std::uint32_t const enableAfter = 491940000; + return parentCloseTime > enableAfter; +} + // At the right most node of a list of consecutive offer nodes, given the amount // requested to be delivered, push towards the left nodes the amount requested // for the right nodes so we can compute how much to deliver from the source. @@ -44,6 +53,12 @@ TER PathCursor::deliverNodeReverseImpl ( ) const { TER resultCode = tesSUCCESS; + + if (!enableDirRestartFix (rippleCalc_.view.info ().parentCloseTime)) + { + node().directory.restart(multiQuality_); + } + // Accumulation of what the previous node must deliver. // Possible optimization: Note this gets zeroed on each increment, ideally // only on first increment, then it could be a limit on the forward pass. @@ -351,8 +366,11 @@ TER PathCursor::deliverNodeReverse ( // increment ) const { - for (int i = nodeIndex_; i >= 0 && !node (i).isAccount(); --i) - node (i).directory.restart (multiQuality_); + if (enableDirRestartFix (rippleCalc_.view.info ().parentCloseTime)) + { + for (int i = nodeIndex_; i >= 0 && !node (i).isAccount(); --i) + node (i).directory.restart (multiQuality_); + } return deliverNodeReverseImpl(uOutAccountID, saOutReq, saOutAct); } diff --git a/src/ripple/app/tx/tests/Offer.test.cpp b/src/ripple/app/tx/tests/Offer.test.cpp index 65778e1a6d..4e195b1dc1 100644 --- a/src/ripple/app/tx/tests/Offer.test.cpp +++ b/src/ripple/app/tx/tests/Offer.test.cpp @@ -41,50 +41,73 @@ public: // would remove the first "taker gets" xrp offer, even though the offer is // still funded and not used for the payment. - using namespace jtx; - Env env (*this); - auto const gw = Account ("gateway"); - auto const USD = gw["USD"]; - auto const BTC = gw["BTC"]; - Account const alice ("alice"); - Account const bob ("bob"); - Account const carol ("carol"); + // Mon Aug 3 11:00:00am PDT + static NetClock::time_point const switchoverTime ( + std::chrono::seconds (491940000)); - env.fund (XRP (10000), alice, bob, carol, gw); - env.trust (USD (1000), alice, bob, carol); - env.trust (BTC (1000), alice, bob, carol); + for(int i=0; i<2; ++i) + { + using namespace jtx; + Env env (*this); - env (pay (gw, alice, BTC (1000))); + auto const tp = switchoverTime + std::chrono::seconds (i); + bool const enableFix = tp > switchoverTime; + expect (enableFix == bool(i)); - env (pay (gw, carol, USD (1000))); - env (pay (gw, carol, BTC (1000))); + // ledger close times have a dynamic resolution depending on network + // conditions it appears the resolution in test is 10 seconds + env.close (tp); - // Must be two offers at the same quality - // "taker gets" must be XRP - // (Different amounts so I can distinguish the offers) - env (offer (carol, BTC (49), XRP (49))); - env (offer (carol, BTC (51), XRP (51))); + NetClock::time_point const pct ( + std::chrono::seconds (env.open ()->info ().parentCloseTime)); + if (enableFix) + expect (pct > switchoverTime); + else + expect (pct <= switchoverTime); - // Offers for the poor quality path - // Must be two offers at the same quality - env (offer (carol, XRP (50), USD (50))); - env (offer (carol, XRP (50), USD (50))); + auto const gw = Account ("gateway"); + auto const USD = gw["USD"]; + auto const BTC = gw["BTC"]; + Account const alice ("alice"); + Account const bob ("bob"); + Account const carol ("carol"); - // Offers for the good quality path - env (offer (carol, BTC (1), USD (100))); + env.fund (XRP (10000), alice, bob, carol, gw); + env.trust (USD (1000), alice, bob, carol); + env.trust (BTC (1000), alice, bob, carol); - PathSet paths ( - Path (XRP, USD), - Path (USD)); + env (pay (gw, alice, BTC (1000))); - env (pay ("alice", "bob", USD (100)), - json (paths.json ()), - sendmax (BTC (1000)), - txflags (tfPartialPayment)); + env (pay (gw, carol, USD (1000))); + env (pay (gw, carol, BTC (1000))); - require (balance ("bob", USD (100))); - expect (!isOffer (env, "carol", BTC (1), USD (100)) && - isOffer (env, "carol", BTC (49), XRP (49))); + // Must be two offers at the same quality + // "taker gets" must be XRP + // (Different amounts so I can distinguish the offers) + env (offer (carol, BTC (49), XRP (49))); + env (offer (carol, BTC (51), XRP (51))); + + // Offers for the poor quality path + // Must be two offers at the same quality + env (offer (carol, XRP (50), USD (50))); + env (offer (carol, XRP (50), USD (50))); + + // Offers for the good quality path + env (offer (carol, BTC (1), USD (100))); + + PathSet paths (Path (XRP, USD), Path (USD)); + + env (pay ("alice", "bob", USD (100)), json (paths.json ()), + sendmax (BTC (1000)), txflags (tfPartialPayment)); + + require (balance ("bob", USD (100))); + if (enableFix) + expect (!isOffer (env, "carol", BTC (1), USD (100)) && + isOffer (env, "carol", BTC (49), XRP (49))); + else + expect (!isOffer (env, "carol", BTC (1), USD (100)) && + !isOffer (env, "carol", BTC (49), XRP (49))); + } } void testCanceledOffer () {