From 186eda8fccc65e39d3ec40b2265b43bfad1f05a7 Mon Sep 17 00:00:00 2001 From: Scott Schurr Date: Tue, 4 Jun 2024 16:03:16 -0700 Subject: [PATCH] [FOLD] Address review comments --- src/ripple/app/paths/impl/BookStep.cpp | 8 ++++++-- src/test/app/Flow_test.cpp | 23 +++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/ripple/app/paths/impl/BookStep.cpp b/src/ripple/app/paths/impl/BookStep.cpp index 1d7793625b8..e5e264761fb 100644 --- a/src/ripple/app/paths/impl/BookStep.cpp +++ b/src/ripple/app/paths/impl/BookStep.cpp @@ -670,8 +670,12 @@ limitStepIn( auto const inLmt = mulRatio(stpAmt.in, QUALITY_ONE, transferRateIn, /*roundUp*/ false); // It turns out we can prevent order book blocking by (strictly) - // rounding down the ceil_in() result. This adjustment changes - // transaction outcomes, so it must be made under an amendment. + // rounding down the ceil_in() result. By rounding down we guarantee + // that the quality of an offer left in the ledger is as good or + // better than the quality of the containing order book page. + // + // This adjustment changes transaction outcomes, so it must be made + // under an amendment. ofrAmt = offer.limitIn(ofrAmt, inLmt, rules, /* roundUp */ false); stpAmt.out = ofrAmt.out; ownerGives = mulRatio( diff --git a/src/test/app/Flow_test.cpp b/src/test/app/Flow_test.cpp index a4adecfa4cf..8884e490952 100644 --- a/src/test/app/Flow_test.cpp +++ b/src/test/app/Flow_test.cpp @@ -514,6 +514,7 @@ struct Flow_test : public beast::unit_test::suite env(pay(gw, alice, USD(1000))); env(pay(gw, bob, EUR(1000))); + Keylet const bobUsdOffer = keylet::offer(bob, env.seq(bob)); env(offer(bob, USD(1), drops(2)), txflags(tfPassive)); env(offer(bob, drops(1), EUR(1000)), txflags(tfPassive)); @@ -536,6 +537,28 @@ struct Flow_test : public beast::unit_test::suite env.require(balance(carol, EUR(1))); env.require(balance(bob, USD(0.4))); env.require(balance(bob, EUR(999))); + + // Show that bob's USD offer is now a blocker. + std::shared_ptr const usdOffer = env.le(bobUsdOffer); + if (BEAST_EXPECT(usdOffer)) + { + std::uint64_t const bookRate = [&usdOffer]() { + // Extract the least significant 64 bits from the + // book page. That's where the quality is stored. + std::string bookDirStr = + to_string(usdOffer->at(sfBookDirectory)); + bookDirStr.erase(0, 48); + return std::stoull(bookDirStr, nullptr, 16); + }(); + std::uint64_t const actualRate = getRate( + usdOffer->at(sfTakerGets), usdOffer->at(sfTakerPays)); + + // We expect the actual rate of the offer to be worse + // (larger) than the rate of the book page holding the + // offer. This is a defect which is corrected by + // fixReducedOffersV2. + BEAST_EXPECT(actualRate > bookRate); + } } } }