mirror of
https://github.com/Xahau/xahaud.git
synced 2026-06-02 16:26:37 +00:00
Retire Flow Cross amendment (#5562)
The FlowCross amendment is now permanently enabled, so all code branches that have this amendment disabled are removed.
This commit is contained in:
@@ -124,7 +124,6 @@ XRPL_FEATURE(HardenedValidations, Supported::yes, VoteBehavior::DefaultYe
|
||||
// fix1781: XRPEndpointSteps should be included in the circular payment check
|
||||
XRPL_FIX (1781, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(RequireFullyCanonicalSig, Supported::yes, VoteBehavior::DefaultYes)
|
||||
// fixQualityUpperBound should be activated before FlowCross
|
||||
XRPL_FIX (QualityUpperBound, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(DeletableAccounts, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (PayChanRecipientOwnerDir, Supported::yes, VoteBehavior::DefaultYes)
|
||||
@@ -142,7 +141,6 @@ XRPL_FIX (1571, Supported::yes, VoteBehavior::DefaultYe
|
||||
XRPL_FEATURE(Checks, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(DepositAuth, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (1513, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(FlowCross, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(Flow, Supported::yes, VoteBehavior::DefaultYes)
|
||||
|
||||
// The following amendments are obsolete, but must remain supported
|
||||
@@ -185,5 +183,6 @@ XRPL_RETIRE(fix1201)
|
||||
XRPL_RETIRE(fix1512)
|
||||
XRPL_RETIRE(fix1523)
|
||||
XRPL_RETIRE(fix1528)
|
||||
XRPL_RETIRE(FlowCross)
|
||||
|
||||
// clang-format on
|
||||
|
||||
@@ -77,10 +77,8 @@ public:
|
||||
auto const gw = Account("gateway");
|
||||
auto const USD = gw["USD"];
|
||||
|
||||
// The number of allowed offers to cross is different between
|
||||
// Taker and FlowCross. Taker allows 850 and FlowCross allows 1000.
|
||||
// Accommodate that difference in the test.
|
||||
int const maxConsumed = features[featureFlowCross] ? 1000 : 850;
|
||||
// The payment engine allows 1000 offers to cross.
|
||||
int const maxConsumed = 1000;
|
||||
|
||||
env.fund(XRP(100000000), gw, "alice", "bob", "carol");
|
||||
int const bobsOfferCount = maxConsumed + 150;
|
||||
@@ -119,11 +117,8 @@ public:
|
||||
|
||||
env.fund(XRP(100000000), gw, "alice", "bob", "carol", "dan", "evita");
|
||||
|
||||
// The number of offers allowed to cross is different between
|
||||
// Taker and FlowCross. Taker allows 850 and FlowCross allows 1000.
|
||||
// Accommodate that difference in the test.
|
||||
bool const isFlowCross{features[featureFlowCross]};
|
||||
int const maxConsumed = isFlowCross ? 1000 : 850;
|
||||
// The payment engine allows 1000 offers to cross.
|
||||
int const maxConsumed = 1000;
|
||||
|
||||
int const evitasOfferCount{maxConsumed + 49};
|
||||
env.trust(USD(1000), "alice");
|
||||
@@ -133,14 +128,8 @@ public:
|
||||
env.trust(USD(evitasOfferCount + 1), "evita");
|
||||
env(pay(gw, "evita", USD(evitasOfferCount + 1)));
|
||||
|
||||
// Taker and FlowCross have another difference we must accommodate.
|
||||
// Taker allows a total of 1000 unfunded offers to be consumed
|
||||
// beyond the 850 offers it can take. FlowCross draws no such
|
||||
// distinction; its limit is 1000 funded or unfunded.
|
||||
//
|
||||
// Give carol an extra 150 (unfunded) offers when we're using Taker
|
||||
// to accommodate that difference.
|
||||
int const carolsOfferCount{isFlowCross ? 700 : 850};
|
||||
// The payment engine has a limit of 1000 funded or unfunded offers.
|
||||
int const carolsOfferCount{700};
|
||||
n_offers(env, 400, "alice", XRP(1), USD(1));
|
||||
n_offers(env, carolsOfferCount, "carol", XRP(1), USD(1));
|
||||
n_offers(env, evitasOfferCount, "evita", XRP(1), USD(1));
|
||||
@@ -268,9 +257,9 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
testAutoBridgedLimitsFlowCross(FeatureBitset features)
|
||||
testAutoBridgedLimits(FeatureBitset features)
|
||||
{
|
||||
testcase("Auto Bridged Limits FlowCross");
|
||||
testcase("Auto Bridged Limits");
|
||||
|
||||
// If any book step in a payment strand consumes 1000 offers, the
|
||||
// liquidity from the offers is used, but that strand will be marked as
|
||||
@@ -452,26 +441,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testAutoBridgedLimits(FeatureBitset features)
|
||||
{
|
||||
// Taker and FlowCross are too different in the way they handle
|
||||
// autobridging to make one test suit both approaches.
|
||||
//
|
||||
// o Taker alternates between books, completing one full increment
|
||||
// before returning to make another pass.
|
||||
//
|
||||
// o FlowCross extracts as much as possible in one book at one Quality
|
||||
// before proceeding to the other book. This reduces the number of
|
||||
// times we change books.
|
||||
//
|
||||
// So the tests for the two forms of autobridging are separate.
|
||||
if (features[featureFlowCross])
|
||||
testAutoBridgedLimitsFlowCross(features);
|
||||
else
|
||||
testAutoBridgedLimitsTaker(features);
|
||||
}
|
||||
|
||||
void
|
||||
testOfferOverflow(FeatureBitset features)
|
||||
{
|
||||
@@ -522,11 +491,10 @@ public:
|
||||
n_offers(env, 998, alice, XRP(0.96), USD(1));
|
||||
n_offers(env, 998, alice, XRP(0.95), USD(1));
|
||||
|
||||
bool const withFlowCross = features[featureFlowCross];
|
||||
bool const withSortStrands = features[featureFlowSortStrands];
|
||||
|
||||
auto const expectedTER = [&]() -> TER {
|
||||
if (withFlowCross && !withSortStrands)
|
||||
if (!withSortStrands)
|
||||
return TER{tecOVERSIZE};
|
||||
return tesSUCCESS;
|
||||
}();
|
||||
@@ -535,8 +503,6 @@ public:
|
||||
env.close();
|
||||
|
||||
auto const expectedUSD = [&] {
|
||||
if (!withFlowCross)
|
||||
return USD(850);
|
||||
if (!withSortStrands)
|
||||
return USD(0);
|
||||
return USD(1996);
|
||||
@@ -558,11 +524,9 @@ public:
|
||||
using namespace jtx;
|
||||
auto const sa = supported_amendments();
|
||||
testAll(sa);
|
||||
testAll(sa - featureFlowSortStrands);
|
||||
testAll(sa - featurePermissionedDEX);
|
||||
testAll(sa - featureFlowSortStrands - featurePermissionedDEX);
|
||||
testAll(
|
||||
sa - featureFlowCross - featureFlowSortStrands -
|
||||
featurePermissionedDEX);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -143,8 +143,6 @@ public:
|
||||
{
|
||||
using namespace jtx;
|
||||
auto const sa = supported_amendments();
|
||||
test_convert_all_of_an_asset(
|
||||
sa - featureFlowCross - featurePermissionedDEX);
|
||||
test_convert_all_of_an_asset(sa - featurePermissionedDEX);
|
||||
test_convert_all_of_an_asset(sa);
|
||||
}
|
||||
|
||||
@@ -155,7 +155,6 @@ public:
|
||||
{
|
||||
using namespace test::jtx;
|
||||
auto const sa = supported_amendments();
|
||||
testXRPDiscrepancy(sa - featureFlowCross - featurePermissionedDEX);
|
||||
testXRPDiscrepancy(sa - featureTouch - featurePermissionedDEX);
|
||||
testXRPDiscrepancy(sa - featurePermissionedDEX);
|
||||
testXRPDiscrepancy(sa);
|
||||
|
||||
@@ -1333,7 +1333,6 @@ struct Flow_test : public beast::unit_test::suite
|
||||
|
||||
using namespace jtx;
|
||||
auto const sa = supported_amendments();
|
||||
testWithFeats(sa - featureFlowCross - featurePermissionedDEX);
|
||||
testWithFeats(sa - featurePermissionedDEX);
|
||||
testWithFeats(sa);
|
||||
testEmptyStrand(sa);
|
||||
@@ -1347,12 +1346,9 @@ struct Flow_manual_test : public Flow_test
|
||||
{
|
||||
using namespace jtx;
|
||||
auto const all = supported_amendments();
|
||||
FeatureBitset const flowCross{featureFlowCross};
|
||||
FeatureBitset const f1513{fix1513};
|
||||
FeatureBitset const permDex{featurePermissionedDEX};
|
||||
|
||||
testWithFeats(all - flowCross - f1513 - permDex);
|
||||
testWithFeats(all - flowCross - permDex);
|
||||
testWithFeats(all - f1513 - permDex);
|
||||
testWithFeats(all - permDex);
|
||||
testWithFeats(all);
|
||||
|
||||
@@ -977,24 +977,12 @@ class Freeze_test : public beast::unit_test::suite
|
||||
env.close();
|
||||
|
||||
// test: A1 wants to buy, must fail
|
||||
if (features[featureFlowCross])
|
||||
{
|
||||
env(offer(A1, USD(1), XRP(2)),
|
||||
txflags(tfFillOrKill),
|
||||
ter(tecKILLED));
|
||||
env.close();
|
||||
env.require(
|
||||
balance(A1, USD(1002)),
|
||||
balance(A2, USD(997)),
|
||||
offers(A1, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
// The transaction that should be here would succeed.
|
||||
// I don't want to adjust balances in following tests. Flow
|
||||
// cross feature flag is not relevant to this particular test
|
||||
// case so we're not missing out some corner cases checks.
|
||||
}
|
||||
env(offer(A1, USD(1), XRP(2)),
|
||||
txflags(tfFillOrKill),
|
||||
ter(tecKILLED));
|
||||
env.close();
|
||||
env.require(
|
||||
balance(A1, USD(1002)), balance(A2, USD(997)), offers(A1, 0));
|
||||
|
||||
// test: A1 can create passive sell offer
|
||||
env(offer(A1, XRP(2), USD(1)), txflags(tfPassive));
|
||||
@@ -2021,18 +2009,16 @@ public:
|
||||
using namespace test::jtx;
|
||||
auto const sa = supported_amendments();
|
||||
testAll(
|
||||
sa - featureFlowCross - featureDeepFreeze - featurePermissionedDEX -
|
||||
fixEnforceNFTokenTrustlineV2);
|
||||
testAll(
|
||||
sa - featureFlowCross - featurePermissionedDEX -
|
||||
sa - featureDeepFreeze - featurePermissionedDEX -
|
||||
fixEnforceNFTokenTrustlineV2);
|
||||
testAll(
|
||||
sa - featureTouch - featurePermissionedDEX -
|
||||
fixEnforceNFTokenTrustlineV2);
|
||||
testAll(
|
||||
sa - featureDeepFreeze - featurePermissionedDEX -
|
||||
fixEnforceNFTokenTrustlineV2);
|
||||
testAll(sa - featurePermissionedDEX - fixEnforceNFTokenTrustlineV2);
|
||||
testAll(sa - featureDeepFreeze - featurePermissionedDEX);
|
||||
testAll(sa - featurePermissionedDEX);
|
||||
testAll(sa - fixEnforceNFTokenTrustlineV2);
|
||||
testAll(sa - featureDeepFreeze);
|
||||
testAll(sa);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1343,18 +1343,10 @@ public:
|
||||
|
||||
// NOTE :
|
||||
// At this point, all offers are expected to be consumed.
|
||||
// Alas, they are not - because of a bug in the Taker auto-bridging
|
||||
// implementation which is addressed by fixTakerDryOfferRemoval.
|
||||
// The pre-fixTakerDryOfferRemoval implementation (incorrect) leaves
|
||||
// an empty offer in the second leg of the bridge. Validate both the
|
||||
// old and the new behavior.
|
||||
{
|
||||
auto acctOffers = offersOnAccount(env, account_to_test);
|
||||
bool const noStaleOffers{
|
||||
features[featureFlowCross] ||
|
||||
features[fixTakerDryOfferRemoval]};
|
||||
|
||||
BEAST_EXPECT(acctOffers.size() == (noStaleOffers ? 0 : 1));
|
||||
BEAST_EXPECT(acctOffers.size() == 0);
|
||||
for (auto const& offerPtr : acctOffers)
|
||||
{
|
||||
auto const& offer = *offerPtr;
|
||||
@@ -1464,8 +1456,7 @@ public:
|
||||
std::uint32_t const bobOfferSeq = env.seq(bob);
|
||||
env(offer(bob, XRP(2000), USD(1)));
|
||||
|
||||
if (localFeatures[featureFlowCross] &&
|
||||
localFeatures[fixReducedOffersV2])
|
||||
if (localFeatures[fixReducedOffersV2])
|
||||
{
|
||||
// With the rounding introduced by fixReducedOffersV2, bob's
|
||||
// offer does not cross alice's offer and goes straight into
|
||||
@@ -1489,8 +1480,7 @@ public:
|
||||
// crossing algorithms becomes apparent. The old offer crossing
|
||||
// would consume small_amount and transfer no XRP. The new offer
|
||||
// crossing transfers a single drop, rather than no drops.
|
||||
auto const crossingDelta =
|
||||
localFeatures[featureFlowCross] ? drops(1) : drops(0);
|
||||
auto const crossingDelta = drops(1);
|
||||
|
||||
jrr = ledgerEntryState(env, alice, gw, "USD");
|
||||
BEAST_EXPECT(
|
||||
@@ -2044,15 +2034,9 @@ public:
|
||||
|
||||
env.require(balance(carol, USD(0)));
|
||||
env.require(balance(carol, EUR(none)));
|
||||
// If neither featureFlowCross nor fixTakerDryOfferRemoval are defined
|
||||
// then carol's offer will be left on the books, but with zero value.
|
||||
int const emptyOfferCount{
|
||||
features[featureFlowCross] || features[fixTakerDryOfferRemoval]
|
||||
? 0
|
||||
: 1};
|
||||
|
||||
env.require(offers(carol, 0 + emptyOfferCount));
|
||||
env.require(owners(carol, 1 + emptyOfferCount));
|
||||
env.require(offers(carol, 0));
|
||||
env.require(owners(carol, 1));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4236,22 +4220,13 @@ public:
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
TestData const takerTests[]{
|
||||
// btcStart ------------------- actor[0] -------------------- ------------------- actor[1] --------------------
|
||||
{0, 0, 1, BTC(5), {{"deb", 0, drops(3900000'000000 - 4 * baseFee), BTC(5), USD(3000)}, {"dan", 0, drops(4100000'000000 - 3 * baseFee), BTC(0), USD(750)}}}, // no BTC xfer fee
|
||||
{0, 0, 0, BTC(5), {{"flo", 0, drops(4000000'000000 - 5 * baseFee), BTC(5), USD(2000)} }} // no xfer fee
|
||||
};
|
||||
|
||||
TestData const flowTests[]{
|
||||
TestData const tests[]{
|
||||
// btcStart ------------------- actor[0] -------------------- ------------------- actor[1] --------------------
|
||||
{0, 0, 1, BTC(5), {{"gay", 1, drops(3950000'000000 - 4 * baseFee), BTC(5), USD(2500)}, {"gar", 1, drops(4050000'000000 - 3 * baseFee), BTC(0), USD(1375)}}}, // no BTC xfer fee
|
||||
{0, 0, 0, BTC(5), {{"hye", 2, drops(4000000'000000 - 5 * baseFee), BTC(5), USD(2000)} }} // no xfer fee
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// Pick the right tests.
|
||||
auto const& tests = features[featureFlowCross] ? flowTests : takerTests;
|
||||
|
||||
for (auto const& t : tests)
|
||||
{
|
||||
Account const& self = t.actors[t.self].acct;
|
||||
@@ -4378,9 +4353,8 @@ public:
|
||||
// 1. alice creates an offer to acquire USD/gw, an asset for which
|
||||
// she does not have a trust line. At some point in the future,
|
||||
// gw adds lsfRequireAuth. Then, later, alice's offer is crossed.
|
||||
// a. With Taker alice's unauthorized offer is consumed.
|
||||
// b. With FlowCross alice's offer is deleted, not consumed,
|
||||
// since alice is not authorized to hold USD/gw.
|
||||
// Alice's offer is deleted, not consumed, since alice is not
|
||||
// authorized to hold USD/gw.
|
||||
//
|
||||
// 2. alice tries to create an offer for USD/gw, now that gw has
|
||||
// lsfRequireAuth set. This time the offer create fails because
|
||||
@@ -4428,33 +4402,17 @@ public:
|
||||
// gw now requires authorization and bob has gwUSD(50). Let's see if
|
||||
// bob can cross alice's offer.
|
||||
//
|
||||
// o With Taker bob's offer should cross alice's.
|
||||
// o With FlowCross bob's offer shouldn't cross and alice's
|
||||
// unauthorized offer should be deleted.
|
||||
// Bob's offer shouldn't cross and alice's unauthorized offer should be
|
||||
// deleted.
|
||||
env(offer(bob, XRP(4000), gwUSD(40)));
|
||||
env.close();
|
||||
std::uint32_t const bobOfferSeq = env.seq(bob) - 1;
|
||||
|
||||
bool const flowCross = features[featureFlowCross];
|
||||
|
||||
env.require(offers(alice, 0));
|
||||
if (flowCross)
|
||||
{
|
||||
// alice's unauthorized offer is deleted & bob's offer not crossed.
|
||||
env.require(balance(alice, gwUSD(none)));
|
||||
env.require(offers(bob, 1));
|
||||
env.require(balance(bob, gwUSD(50)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// alice's offer crosses bob's
|
||||
env.require(balance(alice, gwUSD(40)));
|
||||
env.require(offers(bob, 0));
|
||||
env.require(balance(bob, gwUSD(10)));
|
||||
|
||||
// The rest of the test verifies FlowCross behavior.
|
||||
return;
|
||||
}
|
||||
// alice's unauthorized offer is deleted & bob's offer not crossed.
|
||||
env.require(balance(alice, gwUSD(none)));
|
||||
env.require(offers(bob, 1));
|
||||
env.require(balance(bob, gwUSD(50)));
|
||||
|
||||
// See if alice can create an offer without authorization. alice
|
||||
// should not be able to create the offer and bob's offer should be
|
||||
@@ -5397,9 +5355,7 @@ public:
|
||||
// tfFillOrKill, TakerPays must be filled
|
||||
{
|
||||
TER const err =
|
||||
features[fixFillOrKill] || !features[featureFlowCross]
|
||||
? TER(tesSUCCESS)
|
||||
: tecKILLED;
|
||||
features[fixFillOrKill] ? TER(tesSUCCESS) : tecKILLED;
|
||||
|
||||
env(offer(maker, XRP(100), USD(100)));
|
||||
env.close();
|
||||
@@ -5624,7 +5580,6 @@ public:
|
||||
using namespace jtx;
|
||||
static FeatureBitset const all{
|
||||
supported_amendments() - featureXahauGenesis};
|
||||
static FeatureBitset const flowCross{featureFlowCross};
|
||||
static FeatureBitset const takerDryOffer{fixTakerDryOfferRemoval};
|
||||
static FeatureBitset const rmSmallIncreasedQOffers{
|
||||
fixRmSmallIncreasedQOffers};
|
||||
@@ -5633,10 +5588,9 @@ public:
|
||||
FeatureBitset const fillOrKill{fixFillOrKill};
|
||||
FeatureBitset const permDEX{featurePermissionedDEX};
|
||||
|
||||
static std::array<FeatureBitset, 7> const feats{
|
||||
static std::array<FeatureBitset, 6> const feats{
|
||||
all - takerDryOffer - immediateOfferKilled - permDEX,
|
||||
all - flowCross - takerDryOffer - immediateOfferKilled - permDEX,
|
||||
all - flowCross - immediateOfferKilled - permDEX,
|
||||
all - immediateOfferKilled - permDEX,
|
||||
all - rmSmallIncreasedQOffers - immediateOfferKilled - fillOrKill -
|
||||
permDEX,
|
||||
all - fillOrKill - permDEX,
|
||||
@@ -5658,7 +5612,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class OfferWOFlowCross_test : public OfferBaseUtil_test
|
||||
class OfferWTakerDryOffer_test : public OfferBaseUtil_test
|
||||
{
|
||||
void
|
||||
run() override
|
||||
@@ -5667,7 +5621,7 @@ class OfferWOFlowCross_test : public OfferBaseUtil_test
|
||||
}
|
||||
};
|
||||
|
||||
class OfferWTakerDryOffer_test : public OfferBaseUtil_test
|
||||
class OfferWOSmallQOffers_test : public OfferBaseUtil_test
|
||||
{
|
||||
void
|
||||
run() override
|
||||
@@ -5676,7 +5630,7 @@ class OfferWTakerDryOffer_test : public OfferBaseUtil_test
|
||||
}
|
||||
};
|
||||
|
||||
class OfferWOSmallQOffers_test : public OfferBaseUtil_test
|
||||
class OfferWOFillOrKill_test : public OfferBaseUtil_test
|
||||
{
|
||||
void
|
||||
run() override
|
||||
@@ -5685,7 +5639,7 @@ class OfferWOSmallQOffers_test : public OfferBaseUtil_test
|
||||
}
|
||||
};
|
||||
|
||||
class OfferWOFillOrKill_test : public OfferBaseUtil_test
|
||||
class OfferWOPermDEX_test : public OfferBaseUtil_test
|
||||
{
|
||||
void
|
||||
run() override
|
||||
@@ -5694,21 +5648,12 @@ class OfferWOFillOrKill_test : public OfferBaseUtil_test
|
||||
}
|
||||
};
|
||||
|
||||
class OfferWOPermDEX_test : public OfferBaseUtil_test
|
||||
{
|
||||
void
|
||||
run() override
|
||||
{
|
||||
OfferBaseUtil_test::run(5);
|
||||
}
|
||||
};
|
||||
|
||||
class OfferAllFeatures_test : public OfferBaseUtil_test
|
||||
{
|
||||
void
|
||||
run() override
|
||||
{
|
||||
OfferBaseUtil_test::run(6, true);
|
||||
OfferBaseUtil_test::run(5, true);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5719,26 +5664,23 @@ class Offer_manual_test : public OfferBaseUtil_test
|
||||
{
|
||||
using namespace jtx;
|
||||
FeatureBitset const all{supported_amendments() - featureXahauGenesis};
|
||||
FeatureBitset const flowCross{featureFlowCross};
|
||||
FeatureBitset const f1513{fix1513};
|
||||
FeatureBitset const immediateOfferKilled{featureImmediateOfferKilled};
|
||||
FeatureBitset const takerDryOffer{fixTakerDryOfferRemoval};
|
||||
FeatureBitset const fillOrKill{fixFillOrKill};
|
||||
FeatureBitset const permDEX{featurePermissionedDEX};
|
||||
|
||||
testAll(all - flowCross - f1513 - immediateOfferKilled - permDEX);
|
||||
testAll(all - flowCross - immediateOfferKilled - permDEX);
|
||||
testAll(all - f1513 - immediateOfferKilled - permDEX);
|
||||
testAll(all - immediateOfferKilled - fillOrKill - permDEX);
|
||||
testAll(all - fillOrKill - permDEX);
|
||||
testAll(all - permDEX);
|
||||
testAll(all);
|
||||
|
||||
testAll(all - flowCross - takerDryOffer - permDEX);
|
||||
testAll(all - takerDryOffer - permDEX);
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE_PRIO(OfferBaseUtil, tx, ripple, 2);
|
||||
BEAST_DEFINE_TESTSUITE_PRIO(OfferWOFlowCross, tx, ripple, 2);
|
||||
BEAST_DEFINE_TESTSUITE_PRIO(OfferWTakerDryOffer, tx, ripple, 2);
|
||||
BEAST_DEFINE_TESTSUITE_PRIO(OfferWOSmallQOffers, tx, ripple, 2);
|
||||
BEAST_DEFINE_TESTSUITE_PRIO(OfferWOFillOrKill, tx, ripple, 2);
|
||||
|
||||
@@ -1268,15 +1268,12 @@ struct PayStrand_test : public beast::unit_test::suite
|
||||
{
|
||||
using namespace jtx;
|
||||
auto const sa = supported_amendments();
|
||||
testToStrand(sa - featureFlowCross - featurePermissionedDEX);
|
||||
testToStrand(sa - featurePermissionedDEX);
|
||||
testToStrand(sa);
|
||||
|
||||
testRIPD1373(sa - featureFlowCross - featurePermissionedDEX);
|
||||
testRIPD1373(sa - featurePermissionedDEX);
|
||||
testRIPD1373(sa);
|
||||
|
||||
testLoop(sa - featureFlowCross - featurePermissionedDEX);
|
||||
testLoop(sa - featurePermissionedDEX);
|
||||
testLoop(sa);
|
||||
|
||||
|
||||
@@ -207,24 +207,6 @@ class PermissionedDEX_test : public beast::unit_test::suite
|
||||
env.close();
|
||||
}
|
||||
|
||||
// test preflight: permissioned dex cannot be used without enable
|
||||
// flowcross
|
||||
{
|
||||
Env env(*this, features - featureFlowCross);
|
||||
auto const& [gw, domainOwner, alice, bob, carol, USD, domainID, credType] =
|
||||
PermissionedDEX(env);
|
||||
|
||||
env(offer(bob, XRP(10), USD(10)),
|
||||
domain(domainID),
|
||||
ter(temDISABLED));
|
||||
env.close();
|
||||
|
||||
env.enableFeature(featureFlowCross);
|
||||
env.close();
|
||||
env(offer(bob, XRP(10), USD(10)), domain(domainID));
|
||||
env.close();
|
||||
}
|
||||
|
||||
// preclaim - someone outside of the domain cannot create domain offer
|
||||
{
|
||||
Env env(*this, features);
|
||||
|
||||
@@ -75,7 +75,6 @@ struct SetAuth_test : public beast::unit_test::suite
|
||||
{
|
||||
using namespace jtx;
|
||||
auto const sa = supported_amendments();
|
||||
testAuth(sa - featureFlowCross - featurePermissionedDEX);
|
||||
testAuth(sa - featurePermissionedDEX);
|
||||
testAuth(sa);
|
||||
}
|
||||
|
||||
@@ -481,7 +481,6 @@ public:
|
||||
|
||||
using namespace test::jtx;
|
||||
auto const sa = supported_amendments();
|
||||
testWithFeatures(sa - featureFlowCross - featurePermissionedDEX);
|
||||
testWithFeatures(sa - featurePermissionedDEX);
|
||||
testWithFeatures(sa);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,6 @@ struct BookDirs_test : public beast::unit_test::suite
|
||||
{
|
||||
using namespace jtx;
|
||||
auto const sa = supported_amendments();
|
||||
test_bookdir(sa - featureFlowCross - featurePermissionedDEX);
|
||||
test_bookdir(sa - featurePermissionedDEX);
|
||||
test_bookdir(sa);
|
||||
}
|
||||
|
||||
@@ -421,7 +421,6 @@ public:
|
||||
};
|
||||
using namespace jtx;
|
||||
auto const sa = supported_amendments();
|
||||
testAll(sa - featureFlowCross - featurePermissionedDEX);
|
||||
testAll(sa - featurePermissionedDEX);
|
||||
testAll(sa);
|
||||
}
|
||||
|
||||
@@ -252,10 +252,7 @@ public:
|
||||
{
|
||||
using namespace jtx;
|
||||
auto const sa = supported_amendments();
|
||||
for (auto feature :
|
||||
{sa - featureFlowCross - featurePermissionedDEX,
|
||||
sa - featurePermissionedDEX,
|
||||
sa})
|
||||
for (auto feature : {sa - featurePermissionedDEX, sa})
|
||||
{
|
||||
testGWB(feature);
|
||||
testGWBApiVersions(feature);
|
||||
|
||||
@@ -294,7 +294,6 @@ public:
|
||||
};
|
||||
using namespace jtx;
|
||||
auto const sa = supported_amendments();
|
||||
withFeatsTests(sa - featureFlowCross - featurePermissionedDEX);
|
||||
withFeatsTests(sa - featurePermissionedDEX);
|
||||
withFeatsTests(sa);
|
||||
}
|
||||
|
||||
@@ -740,7 +740,6 @@ BookStep<TIn, TOut, TDerived>::forEachOffer(
|
||||
FlowOfferStream<TIn, TOut> offers(
|
||||
sb, afView, book_, sb.parentCloseTime(), counter, j_);
|
||||
|
||||
bool const flowCross = afView.rules().enabled(featureFlowCross);
|
||||
bool offerAttempted = false;
|
||||
std::optional<Quality> ofrQ;
|
||||
auto execOffer = [&](auto& offer) {
|
||||
@@ -757,8 +756,8 @@ BookStep<TIn, TOut, TDerived>::forEachOffer(
|
||||
|
||||
// Make sure offer owner has authorization to own IOUs from issuer.
|
||||
// An account can always own XRP or their own IOUs.
|
||||
if (flowCross && (!isXRP(offer.issueIn().currency)) &&
|
||||
(offer.owner() != offer.issueIn().account))
|
||||
if (!isXRP(offer.issueIn().currency) &&
|
||||
offer.owner() != offer.issueIn().account)
|
||||
{
|
||||
auto const& issuerID = offer.issueIn().account;
|
||||
auto const issuer = afView.read(keylet::account(issuerID));
|
||||
|
||||
@@ -50,12 +50,6 @@ CreateOffer::preflight(PreflightContext const& ctx)
|
||||
!ctx.rules.enabled(featurePermissionedDEX))
|
||||
return temDISABLED;
|
||||
|
||||
// Permissioned offers should use the PE (which must be enabled by
|
||||
// featureFlowCross amendment)
|
||||
if (ctx.rules.enabled(featurePermissionedDEX) &&
|
||||
!ctx.rules.enabled(featureFlowCross))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -703,54 +697,6 @@ CreateOffer::step_account(OfferStream& stream, Taker const& taker)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fill as much of the offer as possible by consuming offers
|
||||
// already on the books. Return the status and the amount of
|
||||
// the offer to left unfilled.
|
||||
std::pair<TER, Amounts>
|
||||
CreateOffer::takerCross(
|
||||
Sandbox& sb,
|
||||
Sandbox& sbCancel,
|
||||
Amounts const& takerAmount)
|
||||
{
|
||||
NetClock::time_point const when = sb.parentCloseTime();
|
||||
|
||||
beast::WrappedSink takerSink(j_, "Taker ");
|
||||
|
||||
Taker taker(
|
||||
cross_type_,
|
||||
sb,
|
||||
account_,
|
||||
takerAmount,
|
||||
ctx_.tx.getFlags(),
|
||||
beast::Journal(takerSink));
|
||||
|
||||
// If the taker is unfunded before we begin crossing
|
||||
// there's nothing to do - just return an error.
|
||||
//
|
||||
// We check this in preclaim, but when selling XRP
|
||||
// charged fees can cause a user's available balance
|
||||
// to go to 0 (by causing it to dip below the reserve)
|
||||
// so we check this case again.
|
||||
if (taker.unfunded())
|
||||
{
|
||||
JLOG(j_.debug()) << "Not crossing: taker is unfunded.";
|
||||
return {tecUNFUNDED_OFFER, takerAmount};
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (cross_type_ == CrossType::IouToIou)
|
||||
return bridged_cross(taker, sb, sbCancel, when);
|
||||
|
||||
return direct_cross(taker, sb, sbCancel, when);
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
JLOG(j_.error()) << "Exception during offer crossing: " << e.what();
|
||||
return {tecINTERNAL, taker.remaining_offer()};
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<TER, Amounts>
|
||||
CreateOffer::flowCross(
|
||||
PaymentSandbox& psb,
|
||||
@@ -962,22 +908,11 @@ CreateOffer::cross(
|
||||
Amounts const& takerAmount,
|
||||
std::optional<uint256> const& domainID)
|
||||
{
|
||||
if (sb.rules().enabled(featureFlowCross))
|
||||
{
|
||||
PaymentSandbox psbFlow{&sb};
|
||||
PaymentSandbox psbCancelFlow{&sbCancel};
|
||||
auto const ret =
|
||||
flowCross(psbFlow, psbCancelFlow, takerAmount, domainID);
|
||||
psbFlow.apply(sb);
|
||||
psbCancelFlow.apply(sbCancel);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Sandbox sbTaker{&sb};
|
||||
Sandbox sbCancelTaker{&sbCancel};
|
||||
auto const ret = takerCross(sbTaker, sbCancelTaker, takerAmount);
|
||||
sbTaker.apply(sb);
|
||||
sbCancelTaker.apply(sbCancel);
|
||||
PaymentSandbox psbFlow{&sb};
|
||||
PaymentSandbox psbCancelFlow{&sbCancel};
|
||||
auto const ret = flowCross(psbFlow, psbCancelFlow, takerAmount, domainID);
|
||||
psbFlow.apply(sb);
|
||||
psbCancelFlow.apply(sbCancel);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -109,13 +109,6 @@ private:
|
||||
bool
|
||||
reachedOfferCrossingLimit(Taker const& taker) const;
|
||||
|
||||
// Fill offer as much as possible by consuming offers already on the books,
|
||||
// and adjusting account balances accordingly.
|
||||
//
|
||||
// Charges fees on top to taker.
|
||||
std::pair<TER, Amounts>
|
||||
takerCross(Sandbox& sb, Sandbox& sbCancel, Amounts const& takerAmount);
|
||||
|
||||
// Use the payment flow code to perform offer crossing.
|
||||
std::pair<TER, Amounts>
|
||||
flowCross(
|
||||
|
||||
Reference in New Issue
Block a user