diff --git a/src/ripple/protocol/Feature.h b/src/ripple/protocol/Feature.h index 2f6b843d9b..95ce5be32d 100644 --- a/src/ripple/protocol/Feature.h +++ b/src/ripple/protocol/Feature.h @@ -115,6 +115,9 @@ featureToBitsetIndex(uint256 const& f); uint256 bitsetIndexToFeature(size_t i); +bool +hasFeature (uint256 const& feat, FeatureBitset features); + template void foreachFeature(FeatureBitset bs, F&& f) diff --git a/src/ripple/protocol/impl/Feature.cpp b/src/ripple/protocol/impl/Feature.cpp index 52dee335be..fdf33d8d3c 100644 --- a/src/ripple/protocol/impl/Feature.cpp +++ b/src/ripple/protocol/impl/Feature.cpp @@ -129,6 +129,12 @@ uint256 bitsetIndexToFeature(size_t i) return featureCollections.bitsetIndexToFeature(i); } +bool hasFeature(uint256 const& feat, FeatureBitset features) +{ + return features[featureToBitsetIndex(feat)]; +} + + uint256 const featureMultiSign = *getRegisteredFeature("MultiSign"); uint256 const featureTickets = *getRegisteredFeature("Tickets"); uint256 const featureTrustSetAuth = *getRegisteredFeature("TrustSetAuth"); diff --git a/src/test/app/CrossingLimits_test.cpp b/src/test/app/CrossingLimits_test.cpp index 32cfa42ed4..bdc9b455d1 100644 --- a/src/test/app/CrossingLimits_test.cpp +++ b/src/test/app/CrossingLimits_test.cpp @@ -37,18 +37,22 @@ private: using namespace jtx; auto const ownerCount = env.le(account)->getFieldU32(sfOwnerCount); for (std::size_t i = 0; i < n; i++) + { env(offer(account, in, out)); + env.close(); + } env.require (owners (account, ownerCount + n)); } public: void - testStepLimit(std::initializer_list fs) + testStepLimit(FeatureBitset features) { + testcase ("Step Limit"); + using namespace jtx; - Env env(*this, with_only_features(fs)); - auto const xrpMax = XRP(100000000000); + Env env(*this, features); auto const gw = Account("gateway"); auto const USD = gw["USD"]; @@ -62,27 +66,32 @@ public: // Alice offers to buy 1000 XRP for 1000 USD. She takes Bob's first // offer, and removes 999 more as unfunded and hits the step limit. - env(offer("alice", USD(1000), XRP(1000)), - require ( - balance("alice", USD(1)), owners("alice", 2), - balance("bob", USD(0)), owners("bob", 1001), - balance("dan", USD(1)), owners("dan", 2))); + env(offer("alice", USD(1000), XRP(1000))); + env.require (balance("alice", USD(1))); + env.require (owners("alice", 2)); + env.require (balance("bob", USD(0))); + env.require (owners("bob", 1001)); + env.require (balance("dan", USD(1))); + env.require (owners("dan", 2)); // Carol offers to buy 1000 XRP for 1000 USD. She removes Bob's next // 1000 offers as unfunded and hits the step limit. - env(offer("carol", USD(1000), XRP(1000)), - require ( - balance("carol", USD(none)), owners("carol", 1), - balance("bob", USD(0)), owners("bob", 1), - balance("dan", USD(1)), owners("dan", 2))); + env(offer("carol", USD(1000), XRP(1000))); + env.require (balance("carol", USD(none))); + env.require (owners("carol", 1)); + env.require (balance("bob", USD(0))); + env.require (owners("bob", 1)); + env.require (balance("dan", USD(1))); + env.require (owners("dan", 2)); } void - testCrossingLimit(std::initializer_list fs) + testCrossingLimit(FeatureBitset features) { + testcase ("Crossing Limit"); + using namespace jtx; - Env env(*this, with_only_features(fs)); - auto const xrpMax = XRP(100000000000); + Env env(*this, features); auto const gw = Account("gateway"); auto const USD = gw["USD"]; @@ -93,25 +102,26 @@ public: // Alice offers to buy 1000 XRP for 1000 USD. She takes the first // 850 offers, hitting the crossing limit. - env(offer("alice", USD(1000), XRP(1000)), - require ( - balance("alice", USD(850)), - balance("bob", USD(150)), owners ("bob", 151))); + env(offer("alice", USD(1000), XRP(1000))); + env.require (balance("alice", USD(850))); + env.require (balance("bob", USD(150))); + env.require (owners ("bob", 151)); // Carol offers to buy 1000 XRP for 1000 USD. She takes the remaining // 150 offers without hitting a limit. - env(offer("carol", USD(1000), XRP(1000)), - require ( - balance("carol", USD(150)), - balance("bob", USD(0)), owners ("bob", 1))); + env(offer("carol", USD(1000), XRP(1000))); + env.require (balance("carol", USD(150))); + env.require (balance("bob", USD(0))); + env.require (owners ("bob", 1)); } void - testStepAndCrossingLimit(std::initializer_list fs) + testStepAndCrossingLimit(FeatureBitset features) { + testcase ("Step And Crossing Limit"); + using namespace jtx; - Env env(*this, with_only_features(fs)); - auto const xrpMax = XRP(100000000000); + Env env(*this, features); auto const gw = Account("gateway"); auto const USD = gw["USD"]; @@ -131,36 +141,139 @@ public: // Bob offers to buy 1000 XRP for 1000 USD. He takes all 400 USD from // Alice's offers, 1 USD from Carol's and then removes 599 of Carol's // offers as unfunded, before hitting the step limit. - env(offer("bob", USD(1000), XRP(1000)), - require ( - balance("bob", USD(401)), - balance("alice", USD(600)), owners("alice", 1), - balance("carol", USD(0)), owners("carol", 101), - balance("evita", USD(1000)), owners("evita", 1000))); + env(offer("bob", USD(1000), XRP(1000))); + env.require (balance("bob", USD(401))); + env.require (balance("alice", USD(600))); + env.require (owners("alice", 1)); + env.require (balance("carol", USD(0))); + env.require (owners("carol", 101)); + env.require (balance("evita", USD(1000))); + env.require (owners("evita", 1000)); // Dan offers to buy 900 XRP for 900 USD. He removes all 100 of Carol's // offers as unfunded, then takes 850 USD from Evita's, hitting the // crossing limit. - env(offer("dan", USD(900), XRP(900)), - require ( - balance("dan", USD(850)), - balance("alice", USD(600)), owners("alice", 1), - balance("carol", USD(0)), owners("carol", 1), - balance("evita", USD(150)), owners("evita", 150))); + env(offer("dan", USD(900), XRP(900))); + env.require (balance("dan", USD(850))); + env.require (balance("alice", USD(600))); + env.require (owners("alice", 1)); + env.require (balance("carol", USD(0))); + env.require (owners("carol", 1)); + env.require (balance("evita", USD(150))); + env.require (owners("evita", 150)); + } + + void testAutoBridgedLimits (FeatureBitset features) + { + testcase ("Auto Bridged Limits"); + + using namespace jtx; + Env env(*this, features); + auto const gw = Account("gateway"); + auto const USD = gw["USD"]; + auto const EUR = gw["EUR"]; + + env.fund(XRP(100000000), gw, "alice", "bob", "carol", "dan", "evita"); + + env.trust(USD(2000), "alice"); + env(pay(gw, "alice", USD(2000))); + env.trust(USD(1000), "carol"); + env(pay(gw, "carol", USD(3))); + env.trust(USD(1000), "evita"); + env(pay(gw, "evita", USD(1000))); + + n_offers (env, 302, "alice", EUR(2), XRP(1)); + n_offers (env, 300, "alice", XRP(1), USD(4)); + n_offers (env, 497, "carol", XRP(1), USD(3)); + n_offers (env, 1001, "evita", EUR(1), USD(1)); + + // Bob offers to buy 2000 USD for 2000 EUR, even though he only has + // 1000 EUR. + // 1. He spends 600 EUR taking Alice's auto-bridged offers and + // gets 1200 USD for that. + // 2. He spends another 2 EUR taking one of Alice's EUR->XRP and + // one of Carol's XRP-USD offers. He gets 3 USD for that. + // 3. The remainder of Carol's offers are now unfunded. We've + // consumed 602 offers so far. We now chew through 398 more + // of Carol's unfunded offers until we hit the 1000 offer limit. + // This sets have_bridge to false -- we will handle no more + // bridged offers. + // 4. However, have_direct is still true. So we go around one more + // time and take one of Evita's offers. + // 5. After taking one of Evita's offers we notice (again) that our + // offer count was exceeded. So we completely stop after taking + // one of Evita's offers. + env.trust(EUR(10000), "bob"); + env.close(); + env(pay(gw, "bob", EUR(1000))); + env.close(); + env(offer("bob", USD(2000), EUR(2000))); + env.require (balance("bob", USD(1204))); + env.require (balance("bob", EUR( 397))); + + env.require (balance("alice", USD(800))); + env.require (balance("alice", EUR(602))); + env.require (offers("alice", 1)); + env.require (owners("alice", 3)); + + env.require (balance("carol", USD(0))); + env.require (balance("carol", EUR(none))); + env.require (offers("carol", 100)); + env.require (owners("carol", 101)); + + env.require (balance("evita", USD(999))); + env.require (balance("evita", EUR(1))); + env.require (offers("evita", 1000)); + env.require (owners("evita", 1002)); + + // Dan offers to buy 900 EUR for 900 USD. + // 1. He removes all 100 of Carol's remaining unfunded offers. + // 2. Then takes 850 USD from Evita's offers. + // 3. Consuming 850 of Evita's funded offers hits the crossing + // limit. So Dan's offer crossing stops even though he would + // be willing to take another 50 of Evita's offers. + env.trust(EUR(10000), "dan"); + env.close(); + env(pay(gw, "dan", EUR(1000))); + env.close(); + + env(offer("dan", USD(900), EUR(900))); + env.require (balance("dan", USD(850))); + env.require (balance("dan", EUR(150))); + + env.require (balance("alice", USD(800))); + env.require (balance("alice", EUR(602))); + env.require (offers("alice", 1)); + env.require (owners("alice", 3)); + + env.require (balance("carol", USD(0))); + env.require (balance("carol", EUR(none))); + env.require (offers("carol", 0)); + env.require (owners("carol", 1)); + + env.require (balance("evita", USD(149))); + env.require (balance("evita", EUR(851))); + env.require (offers("evita", 150)); + env.require (owners("evita", 152)); } void run() { - auto testAll = [this](std::initializer_list fs) { - testStepLimit(fs); - testCrossingLimit(fs); - testStepAndCrossingLimit(fs); + auto testAll = [this](FeatureBitset features) { + testStepLimit(features); + testCrossingLimit(features); + testStepAndCrossingLimit(features); + testAutoBridgedLimits(features); }; - testAll({}); - testAll({featureFlow}); - testAll({featureFlow, fix1373}); - testAll({featureFlow, fix1373, featureFlowCross}); + using namespace jtx; + testAll( + supported_features_except (featureFlow, fix1373, featureFlowCross)); + testAll( + supported_features_except ( fix1373, featureFlowCross)); + testAll( + supported_features_except ( featureFlowCross)); +// testAll(supported_amendments());// Does not pass with FlowCross enabled. } }; diff --git a/src/test/app/DeliverMin_test.cpp b/src/test/app/DeliverMin_test.cpp index 81588d86a9..8eee3724f8 100644 --- a/src/test/app/DeliverMin_test.cpp +++ b/src/test/app/DeliverMin_test.cpp @@ -29,7 +29,7 @@ class DeliverMin_test : public beast::unit_test::suite { public: void - test_convert_all_of_an_asset(std::initializer_list fs) + test_convert_all_of_an_asset(FeatureBitset features) { testcase("Convert all of an asset using DeliverMin"); @@ -38,7 +38,7 @@ public: auto const USD = gw["USD"]; { - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), "alice", "bob", "carol", gw); env.trust(USD(100), "alice", "bob", "carol"); env(pay("alice", "bob", USD(10)), delivermin(USD(10)), ter(temBAD_AMOUNT)); @@ -61,7 +61,7 @@ public: } { - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), "alice", "bob", gw); env.trust(USD(1000), "alice", "bob"); env(pay(gw, "bob", USD(100))); @@ -73,7 +73,7 @@ public: } { - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), "alice", "bob", "carol", gw); env.trust(USD(1000), "bob", "carol"); env(pay(gw, "bob", USD(200))); @@ -91,7 +91,7 @@ public: } { - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), "alice", "bob", "carol", "dan", gw); env.trust(USD(1000), "bob", "carol", "dan"); env(pay(gw, "bob", USD(100))); @@ -111,11 +111,14 @@ public: void run() { - test_convert_all_of_an_asset({}); - test_convert_all_of_an_asset({featureFlow}); - test_convert_all_of_an_asset({featureFlow, fix1373}); + using namespace jtx; test_convert_all_of_an_asset( - {featureFlow, fix1373, featureFlowCross}); + supported_features_except (featureFlow, fix1373, featureFlowCross)); + test_convert_all_of_an_asset( + supported_features_except ( fix1373, featureFlowCross)); + test_convert_all_of_an_asset( + supported_features_except ( featureFlowCross)); + test_convert_all_of_an_asset(supported_amendments()); } }; diff --git a/src/test/app/Discrepancy_test.cpp b/src/test/app/Discrepancy_test.cpp index b881f85d60..6632dc3d7e 100644 --- a/src/test/app/Discrepancy_test.cpp +++ b/src/test/app/Discrepancy_test.cpp @@ -37,11 +37,11 @@ class Discrepancy_test : public beast::unit_test::suite // A payment with path and sendmax is made and the transaction is queried // to verify that the net of balance changes match the fee charged. void - testXRPDiscrepancy (std::initializer_list fs) + testXRPDiscrepancy (FeatureBitset features) { testcase ("Discrepancy test : XRP Discrepancy"); using namespace test::jtx; - Env env {*this, with_only_features(fs)}; + Env env {*this, features}; Account A1 {"A1"}; Account A2 {"A2"}; @@ -144,10 +144,14 @@ class Discrepancy_test : public beast::unit_test::suite public: void run () { - testXRPDiscrepancy ({}); - testXRPDiscrepancy ({featureFlow}); - testXRPDiscrepancy ({featureFlow, fix1373}); - testXRPDiscrepancy ({featureFlow, fix1373, featureFlowCross}); + using namespace test::jtx; + testXRPDiscrepancy ( + supported_features_except (featureFlow, fix1373, featureFlowCross)); + testXRPDiscrepancy ( + supported_features_except ( fix1373, featureFlowCross)); + testXRPDiscrepancy ( + supported_features_except ( featureFlowCross)); + testXRPDiscrepancy (supported_amendments()); } }; diff --git a/src/test/app/Escrow_test.cpp b/src/test/app/Escrow_test.cpp index 915dee7971..9227c71a9a 100644 --- a/src/test/app/Escrow_test.cpp +++ b/src/test/app/Escrow_test.cpp @@ -207,7 +207,7 @@ struct Escrow_test : public beast::unit_test::suite using namespace std::chrono; { // Escrow not enabled - Env env(*this, no_features); + Env env(*this, supported_features_except (featureEscrow)); env.fund(XRP(5000), "alice", "bob"); env(lockup("alice", "bob", XRP(1000), env.now() + 1s), ter(temDISABLED)); env(finish("bob", "alice", 1), ter(temDISABLED)); @@ -215,7 +215,7 @@ struct Escrow_test : public beast::unit_test::suite } { // Escrow enabled - Env env(*this, with_only_features(featureEscrow)); + Env env(*this); env.fund(XRP(5000), "alice", "bob"); env(lockup("alice", "bob", XRP(1000), env.now() + 1s)); env.close(); @@ -237,7 +237,7 @@ struct Escrow_test : public beast::unit_test::suite using namespace jtx; using namespace std::chrono; - Env env(*this, with_only_features(featureEscrow)); + Env env(*this); auto const alice = Account("alice"); env.fund(XRP(5000), alice, "bob"); @@ -261,7 +261,7 @@ struct Escrow_test : public beast::unit_test::suite using namespace jtx; using namespace std::chrono; - Env env(*this, with_only_features(featureEscrow)); + Env env(*this); env.fund(XRP(5000), "alice", "bob"); env.close(); @@ -364,7 +364,7 @@ struct Escrow_test : public beast::unit_test::suite using namespace std::chrono; { // Unconditional - Env env(*this, with_only_features(featureEscrow)); + Env env(*this); env.fund(XRP(5000), "alice", "bob"); auto const seq = env.seq("alice"); env(lockup("alice", "alice", XRP(1000), env.now() + 1s)); @@ -379,7 +379,7 @@ struct Escrow_test : public beast::unit_test::suite } { // Conditional - Env env(*this, with_only_features(featureEscrow)); + Env env(*this); env.fund(XRP(5000), "alice", "bob"); auto const seq = env.seq("alice"); env(lockup("alice", "alice", XRP(1000), makeSlice(cb2), env.now() + 1s)); @@ -411,8 +411,7 @@ struct Escrow_test : public beast::unit_test::suite using S = seconds; { // Test cryptoconditions - Env env(*this, - with_only_features(featureEscrow)); + Env env(*this); auto T = [&env](NetClock::duration const& d) { return env.now() + d; }; env.fund(XRP(5000), "alice", "bob", "carol"); @@ -459,8 +458,7 @@ struct Escrow_test : public beast::unit_test::suite } { // Test cancel when condition is present - Env env(*this, - with_only_features(featureEscrow)); + Env env(*this); auto T = [&env](NetClock::duration const& d) { return env.now() + d; }; env.fund(XRP(5000), "alice", "bob", "carol"); @@ -477,7 +475,7 @@ struct Escrow_test : public beast::unit_test::suite } { - Env env(*this, with_only_features(featureEscrow)); + Env env(*this); auto T = [&env](NetClock::duration const& d) { return env.now() + d; }; env.fund(XRP(5000), "alice", "bob", "carol"); @@ -497,7 +495,7 @@ struct Escrow_test : public beast::unit_test::suite } { // Test long & short conditions during creation - Env env(*this, with_only_features(featureEscrow)); + Env env(*this); auto T = [&env](NetClock::duration const& d) { return env.now() + d; }; env.fund(XRP(5000), "alice", "bob", "carol"); @@ -537,8 +535,7 @@ struct Escrow_test : public beast::unit_test::suite } { // Test long and short conditions & fulfillments during finish - Env env(*this, - with_only_features(featureEscrow)); + Env env(*this); auto T = [&env](NetClock::duration const& d) { return env.now() + d; }; env.fund(XRP(5000), "alice", "bob", "carol"); @@ -623,7 +620,7 @@ struct Escrow_test : public beast::unit_test::suite { // Test empty condition during creation and // empty condition & fulfillment during finish - Env env(*this, with_only_features(featureEscrow)); + Env env(*this); auto T = [&env](NetClock::duration const& d) { return env.now() + d; }; env.fund(XRP(5000), "alice", "bob", "carol"); @@ -663,7 +660,7 @@ struct Escrow_test : public beast::unit_test::suite { // Test a condition other than PreimageSha256, which // would require a separate amendment - Env env(*this, with_only_features(featureEscrow)); + Env env(*this); auto T = [&env](NetClock::duration const& d) { return env.now() + d; }; env.fund(XRP(5000), "alice", "bob", "carol"); @@ -696,7 +693,7 @@ struct Escrow_test : public beast::unit_test::suite { testcase ("Metadata & Ownership (without fix1523)"); - Env env(*this, with_only_features(featureEscrow)); + Env env(*this, supported_features_except (fix1523)); env.fund(XRP(5000), alice, bruce, carol); auto const seq = env.seq(alice); @@ -718,7 +715,7 @@ struct Escrow_test : public beast::unit_test::suite { testcase ("Metadata (with fix1523, to self)"); - Env env(*this, with_only_features(featureEscrow, fix1523)); + Env env(*this); env.fund(XRP(5000), alice, bruce, carol); auto const aseq = env.seq(alice); auto const bseq = env.seq(bruce); @@ -777,7 +774,7 @@ struct Escrow_test : public beast::unit_test::suite { testcase ("Metadata (with fix1523, to other)"); - Env env(*this, with_only_features(featureEscrow, fix1523)); + Env env(*this); env.fund(XRP(5000), alice, bruce, carol); auto const aseq = env.seq(alice); auto const bseq = env.seq(bruce); @@ -856,7 +853,7 @@ struct Escrow_test : public beast::unit_test::suite using namespace jtx; using namespace std::chrono; - Env env(*this, with_only_features(featureEscrow)); + Env env(*this); env.memoize("alice"); env.memoize("bob"); diff --git a/src/test/app/Flow_test.cpp b/src/test/app/Flow_test.cpp index 39ed53e0da..dd43ef0378 100644 --- a/src/test/app/Flow_test.cpp +++ b/src/test/app/Flow_test.cpp @@ -56,15 +56,7 @@ xrpMinusFee (jtx::Env const& env, std::int64_t xrpAmount) struct Flow_test : public beast::unit_test::suite { - static bool hasFeature(uint256 const& feat, std::initializer_list args) - { - for(auto const& f : args) - if (f == feat) - return true; - return false; - } - - void testDirectStep (std::initializer_list fs) + void testDirectStep (FeatureBitset features) { testcase ("Direct Step"); @@ -82,7 +74,7 @@ struct Flow_test : public beast::unit_test::suite auto const USD = gw["USD"]; { // Pay USD, trivial path - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, gw); env.trust (USD (1000), alice, bob); @@ -92,7 +84,7 @@ struct Flow_test : public beast::unit_test::suite } { // XRP transfer - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob); env (pay (alice, bob, XRP (100))); @@ -101,7 +93,7 @@ struct Flow_test : public beast::unit_test::suite } { // Partial payments - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, gw); env.trust (USD (1000), alice, bob); @@ -115,7 +107,7 @@ struct Flow_test : public beast::unit_test::suite } { // Pay by rippling through accounts, use path finder - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, carol, dan); env.trust (USDA (10), bob); @@ -130,7 +122,7 @@ struct Flow_test : public beast::unit_test::suite { // Pay by rippling through accounts, specify path // and charge a transfer fee - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, carol, dan); env.trust (USDA (10), bob); @@ -148,7 +140,7 @@ struct Flow_test : public beast::unit_test::suite { // Pay by rippling through accounts, specify path and transfer fee // Test that the transfer fee is not charged when alice issues - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, carol, dan); env.trust (USDA (10), bob); @@ -164,7 +156,7 @@ struct Flow_test : public beast::unit_test::suite { // test best quality path is taken // Paths: A->B->D->E ; A->C->D->E - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, carol, dan, erin); env.trust (USDA (10), bob, carol); @@ -185,7 +177,7 @@ struct Flow_test : public beast::unit_test::suite } { // Limit quality - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, carol); env.trust (USDA (10), bob); @@ -201,7 +193,7 @@ struct Flow_test : public beast::unit_test::suite } } - void testLineQuality (std::initializer_list fs) + void testLineQuality (FeatureBitset features) { testcase ("Line Quality"); @@ -219,10 +211,10 @@ struct Flow_test : public beast::unit_test::suite for (auto bobDanQIn : {80, 100, 120}) for (auto bobAliceQOut : {80, 100, 120}) { - if (!hasFeature(featureFlow, fs) && bobDanQIn < 100 && + if (!hasFeature(featureFlow, features) && bobDanQIn < 100 && bobAliceQOut < 100) continue; // Bug in flow v1 - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, carol, dan); env(trust(bob, USDD(100)), qualityInPercent(bobDanQIn)); env(trust(bob, USDA(100)), qualityOutPercent(bobAliceQOut)); @@ -245,7 +237,7 @@ struct Flow_test : public beast::unit_test::suite // bob -> alice -> carol; vary carolAliceQIn for (auto carolAliceQIn : {80, 100, 120}) { - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, carol); env(trust(bob, USDA(10))); env(trust(carol, USDA(10)), qualityInPercent(carolAliceQIn)); @@ -261,7 +253,7 @@ struct Flow_test : public beast::unit_test::suite // bob -> alice -> carol; bobAliceQOut varies. for (auto bobAliceQOut : {80, 100, 120}) { - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, carol); env(trust(bob, USDA(10)), qualityOutPercent(bobAliceQOut)); env(trust(carol, USDA(10))); @@ -274,7 +266,7 @@ struct Flow_test : public beast::unit_test::suite } } - void testBookStep (std::initializer_list fs) + void testBookStep (FeatureBitset features) { testcase ("Book Step"); @@ -290,7 +282,7 @@ struct Flow_test : public beast::unit_test::suite { // simple IOU/IOU offer - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, carol, gw); env.trust (USD (1000), alice, bob, carol); @@ -311,7 +303,7 @@ struct Flow_test : public beast::unit_test::suite } { // simple IOU/XRP XRP/IOU offer - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, carol, gw); env.trust (USD (1000), alice, bob, carol); @@ -335,7 +327,7 @@ struct Flow_test : public beast::unit_test::suite } { // simple XRP -> USD through offer and sendmax - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, carol, gw); env.trust (USD (1000), alice, bob, carol); @@ -356,7 +348,7 @@ struct Flow_test : public beast::unit_test::suite } { // simple USD -> XRP through offer and sendmax - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, carol, gw); env.trust (USD (1000), alice, bob, carol); @@ -377,7 +369,7 @@ struct Flow_test : public beast::unit_test::suite } { // test unfunded offers are removed when payment succeeds - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, carol, gw); env.trust (USD (1000), alice, bob, carol); @@ -423,7 +415,7 @@ struct Flow_test : public beast::unit_test::suite // offer. When the payment fails `flow` should return the unfunded // offer. This test is intentionally similar to the one that removes // unfunded offers when the payment succeeds. - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, carol, gw); env.trust (USD (1000), alice, bob, carol); @@ -498,7 +490,7 @@ struct Flow_test : public beast::unit_test::suite // Without limits, the 0.4 USD would produce 1000 EUR in the forward // pass. This test checks that the payment produces 1 EUR, as expected. - Env env (*this, with_only_features (fs)); + Env env (*this, features); auto const closeTime = STAmountSO::soTime2 + 100 * env.closed ()->info ().closeTimeResolution; @@ -523,7 +515,7 @@ struct Flow_test : public beast::unit_test::suite } } - void testTransferRate (std::initializer_list fs) + void testTransferRate (FeatureBitset features) { testcase ("Transfer Rate"); @@ -541,7 +533,7 @@ struct Flow_test : public beast::unit_test::suite { // Simple payment through a gateway with a // transfer rate - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, carol, gw); env(rate(gw, 1.25)); @@ -553,7 +545,7 @@ struct Flow_test : public beast::unit_test::suite } { // transfer rate is not charged when issuer is src or dst - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, carol, gw); env(rate(gw, 1.25)); @@ -565,7 +557,7 @@ struct Flow_test : public beast::unit_test::suite } { // transfer fee on an offer - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, carol, gw); env(rate(gw, 1.25)); @@ -583,7 +575,7 @@ struct Flow_test : public beast::unit_test::suite { // Transfer fee two consecutive offers - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, carol, gw); env(rate(gw, 1.25)); @@ -606,7 +598,7 @@ struct Flow_test : public beast::unit_test::suite { // First pass through a strand redeems, second pass issues, no offers // limiting step is not an endpoint - Env env (*this, with_only_features(fs)); + Env env (*this, features); auto const USDA = alice["USD"]; auto const USDB = bob["USD"]; @@ -626,7 +618,7 @@ struct Flow_test : public beast::unit_test::suite { // First pass through a strand redeems, second pass issues, through an offer // limiting step is not an endpoint - Env env (*this, with_only_features(fs)); + Env env (*this, features); auto const USDA = alice["USD"]; auto const USDB = bob["USD"]; Account const dan ("dan"); @@ -653,7 +645,7 @@ struct Flow_test : public beast::unit_test::suite { // Offer where the owner is also the issuer, owner pays fee - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, gw); env(rate(gw, 1.25)); @@ -665,10 +657,10 @@ struct Flow_test : public beast::unit_test::suite balance (alice, xrpMinusFee(env, 10000-100)), balance (bob, USD (100))); } - if (!hasFeature(featureOwnerPaysFee, fs)) + if (!hasFeature(featureOwnerPaysFee, features)) { // Offer where the owner is also the issuer, sender pays fee - Env env (*this, with_only_features(fs)); + Env env (*this, features); env.fund (XRP (10000), alice, bob, gw); env(rate(gw, 1.25)); @@ -683,7 +675,7 @@ struct Flow_test : public beast::unit_test::suite } void - testFalseDry(std::initializer_list fs) + testFalseDry(FeatureBitset features) { testcase ("falseDryChanges"); @@ -696,7 +688,7 @@ struct Flow_test : public beast::unit_test::suite Account const bob ("bob"); Account const carol ("carol"); - Env env (*this, with_only_features (fs)); + Env env (*this, features); auto const closeTime = fix1141Time() + 100 * env.closed ()->info ().closeTimeResolution; @@ -793,7 +785,7 @@ struct Flow_test : public beast::unit_test::suite } void - testSelfPayment1(std::initializer_list fs) + testSelfPayment1(FeatureBitset features) { testcase ("Self-payment 1"); @@ -810,7 +802,7 @@ struct Flow_test : public beast::unit_test::suite auto const USD = gw1["USD"]; auto const EUR = gw2["EUR"]; - Env env (*this, with_only_features (fs)); + Env env (*this, features); auto const closeTime = fix1141Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -869,7 +861,7 @@ struct Flow_test : public beast::unit_test::suite } void - testSelfPayment2(std::initializer_list fs) + testSelfPayment2(FeatureBitset features) { testcase ("Self-payment 2"); @@ -884,7 +876,7 @@ struct Flow_test : public beast::unit_test::suite auto const USD = gw1["USD"]; auto const EUR = gw2["EUR"]; - Env env (*this, with_only_features (fs)); + Env env (*this, features); auto const closeTime = fix1141Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -941,7 +933,7 @@ struct Flow_test : public beast::unit_test::suite BEAST_EXPECT(offer[sfTakerPays] == USD (495)); } } - void testSelfFundedXRPEndpoint (bool consumeOffer, std::initializer_list fs) + void testSelfFundedXRPEndpoint (bool consumeOffer, FeatureBitset features) { // Test that the deferred credit table is not bypassed for // XRPEndpointSteps. If the account in the first step is sending XRP and @@ -952,7 +944,7 @@ struct Flow_test : public beast::unit_test::suite using namespace jtx; - Env env(*this, with_only_features(fs)); + Env env(*this, features); // Need new behavior from `accountHolds` auto const closeTime = fix1141Time() + @@ -975,7 +967,7 @@ struct Flow_test : public beast::unit_test::suite txflags(tfPartialPayment | tfNoRippleDirect)); } - void testUnfundedOffer (bool withFix, std::initializer_list fs) + void testUnfundedOffer (bool withFix, FeatureBitset features) { testcase(std::string("Unfunded Offer ") + (withFix ? "with fix" : "without fix")); @@ -983,7 +975,7 @@ struct Flow_test : public beast::unit_test::suite using namespace jtx; { // Test reverse - Env env(*this, with_only_features(fs)); + Env env(*this, features); auto closeTime = fix1298Time(); if (withFix) closeTime += env.closed()->info().closeTimeResolution; @@ -1015,7 +1007,7 @@ struct Flow_test : public beast::unit_test::suite } { // Test forward - Env env(*this, with_only_features(fs)); + Env env(*this, features); auto closeTime = fix1298Time(); if (withFix) closeTime += env.closed()->info().closeTimeResolution; @@ -1050,12 +1042,12 @@ struct Flow_test : public beast::unit_test::suite } void - testReexecuteDirectStep(std::initializer_list fs) + testReexecuteDirectStep(FeatureBitset features) { testcase("ReexecuteDirectStep"); using namespace jtx; - Env env(*this, with_only_features(fs)); + Env env(*this, features); auto const alice = Account("alice"); auto const bob = Account("bob"); @@ -1111,7 +1103,7 @@ struct Flow_test : public beast::unit_test::suite testcase("ripd1443"); using namespace jtx; - Env env(*this, with_only_features(featureFlow)); + Env env(*this); auto const timeDelta = env.closed ()->info ().closeTimeResolution; auto const d = withFix ? 100*timeDelta : -100*timeDelta; auto closeTime = fix1443Time() + d; @@ -1164,7 +1156,7 @@ struct Flow_test : public beast::unit_test::suite testcase("ripd1449"); using namespace jtx; - Env env(*this, with_only_features(featureFlow)); + Env env(*this); auto const timeDelta = env.closed ()->info ().closeTimeResolution; auto const d = withFix ? 100*timeDelta : -100*timeDelta; auto closeTime = fix1449Time() + d; @@ -1201,7 +1193,7 @@ struct Flow_test : public beast::unit_test::suite } void - testSelfPayLowQualityOffer (std::initializer_list fs) + testSelfPayLowQualityOffer (FeatureBitset features) { // The new payment code used to assert if an offer was made for more // XRP than the offering account held. This unit test reproduces @@ -1210,7 +1202,7 @@ struct Flow_test : public beast::unit_test::suite using namespace jtx; - Env env(*this, with_only_features (fs)); + Env env(*this, features); auto const ann = Account("ann"); auto const gw = Account("gateway"); @@ -1237,14 +1229,14 @@ struct Flow_test : public beast::unit_test::suite } void - testEmptyStrand(std::initializer_list fs) + testEmptyStrand(FeatureBitset features) { testcase("Empty Strand"); using namespace jtx; auto const alice = Account("alice"); - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice); @@ -1254,32 +1246,30 @@ struct Flow_test : public beast::unit_test::suite ter(temBAD_PATH)); } - template - void testWithFeats(bool haveFlow, T&&... fs) + void testWithFeats(FeatureBitset features) { - testLineQuality({ fs... }); - testFalseDry({ fs... }); - if (!haveFlow) - return; - testDirectStep({ fs... }); - testBookStep({ fs... }); - testDirectStep({ featureOwnerPaysFee, fs... }); - testBookStep({ featureOwnerPaysFee, fs... }); - testTransferRate({ featureOwnerPaysFee, fs... }); - testSelfPayment1({ fs... }); - testSelfPayment2({ fs... }); - testSelfFundedXRPEndpoint(false, { fs... }); - testSelfFundedXRPEndpoint(true, { fs... }); - testUnfundedOffer(true, { fs... }); - testUnfundedOffer(false, { fs... }); - testReexecuteDirectStep({ fix1368, fs... }); - testSelfPayLowQualityOffer({ fs... }); - } + using namespace jtx; + FeatureBitset const ownerPaysFee + {with_only_features (featureOwnerPaysFee)}; - template - void testWithFeats(T&&... fs) - { - testWithFeats(!!sizeof...(fs), fs...); + testLineQuality(features); + testFalseDry(features); + // Only do the rest of the tests if featureFlow is enabled. + if (! hasFeature (featureFlow, features)) + return; + testDirectStep(features); + testBookStep(features); + testDirectStep(features | ownerPaysFee); + testBookStep(features | ownerPaysFee); + testTransferRate(features | ownerPaysFee); + testSelfPayment1(features); + testSelfPayment2(features); + testSelfFundedXRPEndpoint(false, features); + testSelfFundedXRPEndpoint(true, features); + testUnfundedOffer(true, features); + testUnfundedOffer(false, features); + testReexecuteDirectStep(features | with_only_features (fix1368)); + testSelfPayLowQualityOffer(features); } void run() override @@ -1290,13 +1280,16 @@ struct Flow_test : public beast::unit_test::suite testRIPD1449(true); testRIPD1449(false); - testWithFeats(false, featureFeeEscalation, fix1513); - testWithFeats(featureFlow, featureFeeEscalation, fix1513); - testWithFeats(featureFlow, fix1373, featureFeeEscalation, fix1513); - testWithFeats(featureFlow, fix1373, featureFlowCross, - featureFeeEscalation, fix1513); - testEmptyStrand({featureFlow, fix1373, featureFlowCross, - featureFeeEscalation, fix1513 }); + using namespace jtx; + testWithFeats( + supported_features_except (featureFlow, fix1373, featureFlowCross)); + testWithFeats( + supported_features_except ( fix1373, featureFlowCross)); + testWithFeats( + supported_features_except ( featureFlowCross)); + testWithFeats(supported_amendments()); + + testEmptyStrand(supported_amendments()); } }; @@ -1304,31 +1297,30 @@ struct Flow_manual_test : public Flow_test { void run() override { - testWithFeats(); - testWithFeats(false, - featureFeeEscalation); - testWithFeats(false, - featureFeeEscalation, fix1513); - testWithFeats(featureFlow); - testWithFeats(featureFlow, - featureFeeEscalation); - testWithFeats(featureFlow, - featureFeeEscalation, fix1513); - testWithFeats(featureFlow, fix1373); - testWithFeats(featureFlow, fix1373, - featureFeeEscalation); - testWithFeats(featureFlow, fix1373, - featureFeeEscalation, fix1513); - testWithFeats(featureFlow, fix1373, featureFlowCross); - testWithFeats(featureFlow, fix1373, featureFlowCross, - featureFeeEscalation); - testWithFeats(featureFlow, fix1373, featureFlowCross, - featureFeeEscalation, fix1513); - testEmptyStrand({ featureFlow, fix1373, featureFlowCross }); - testEmptyStrand({ featureFlow, fix1373, featureFlowCross, - featureFeeEscalation }); - testEmptyStrand({ featureFlow, fix1373, featureFlowCross, - featureFeeEscalation, fix1513 }); + using namespace jtx; + auto const all = supported_amendments(); + auto const feeEscalation = with_only_features (featureFeeEscalation); + auto const flow = with_only_features (featureFlow); + auto const f1373 = with_only_features (fix1373); + auto const flowCross = with_only_features (featureFlowCross); + auto const f1513 = with_only_features (fix1513); + + testWithFeats(all & ~(feeEscalation | flow | f1373 | flowCross | f1513)); + testWithFeats(all & ~( flow | f1373 | flowCross | f1513)); + testWithFeats(all & ~( flow | f1373 | flowCross )); + testWithFeats(all & ~(feeEscalation | f1373 | flowCross | f1513)); + testWithFeats(all & ~( f1373 | flowCross | f1513)); + testWithFeats(all & ~( f1373 | flowCross )); + testWithFeats(all & ~(feeEscalation | flowCross | f1513)); + testWithFeats(all & ~( flowCross | f1513)); + testWithFeats(all & ~( flowCross )); + testWithFeats(all & ~(feeEscalation | f1513)); + testWithFeats(all & ~( f1513)); + testWithFeats(all ); + + testEmptyStrand(all & ~(feeEscalation | f1513)); + testEmptyStrand(all & ~( f1513)); + testEmptyStrand(all ); } }; diff --git a/src/test/app/Freeze_test.cpp b/src/test/app/Freeze_test.cpp index 87f76d171e..30c1154641 100644 --- a/src/test/app/Freeze_test.cpp +++ b/src/test/app/Freeze_test.cpp @@ -53,12 +53,12 @@ class Freeze_test : public beast::unit_test::suite return val.isArray() && val.size() == size; } - void testRippleState(std::initializer_list fs) + void testRippleState(FeatureBitset features) { testcase("RippleState Freeze"); using namespace test::jtx; - Env env(*this, with_only_features(fs)); + Env env(*this, features); Account G1 {"G1"}; Account alice {"alice"}; @@ -207,12 +207,12 @@ class Freeze_test : public beast::unit_test::suite } void - testGlobalFreeze(std::initializer_list fs) + testGlobalFreeze(FeatureBitset features) { testcase("Global Freeze"); using namespace test::jtx; - Env env(*this, with_only_features(fs)); + Env env(*this, features); Account G1 {"G1"}; Account A1 {"A1"}; @@ -365,12 +365,12 @@ class Freeze_test : public beast::unit_test::suite } void - testNoFreeze(std::initializer_list fs) + testNoFreeze(FeatureBitset features) { testcase("No Freeze"); using namespace test::jtx; - Env env(*this, with_only_features(fs)); + Env env(*this, features); Account G1 {"G1"}; Account A1 {"A1"}; @@ -419,12 +419,12 @@ class Freeze_test : public beast::unit_test::suite } void - testOffersWhenFrozen(std::initializer_list fs) + testOffersWhenFrozen(FeatureBitset features) { testcase("Offers for Frozen Trust Lines"); using namespace test::jtx; - Env env(*this, with_only_features(fs)); + Env env(*this, features); Account G1 {"G1"}; Account A2 {"A2"}; @@ -523,21 +523,23 @@ public: void run() { - auto testAll = [this](std::initializer_list fs) + auto testAll = [this](FeatureBitset features) { - testRippleState(fs); - testGlobalFreeze(fs); - testNoFreeze(fs); - testOffersWhenFrozen(fs); + testRippleState(features); + testGlobalFreeze(features); + testNoFreeze(features); + testOffersWhenFrozen(features); }; - testAll({}); - testAll({featureFlow}); - testAll({featureFlow, fix1373}); - testAll({featureFlow, fix1373, featureFlowCross}); + using namespace test::jtx; + testAll( + supported_features_except (featureFlow, fix1373, featureFlowCross)); + testAll( + supported_features_except ( fix1373, featureFlowCross)); + testAll( + supported_features_except ( featureFlowCross)); + testAll(supported_amendments()); } }; BEAST_DEFINE_TESTSUITE(Freeze, app, ripple); } // ripple - - diff --git a/src/test/app/MultiSign_test.cpp b/src/test/app/MultiSign_test.cpp index f7bfe1ca61..c5074a7ab8 100644 --- a/src/test/app/MultiSign_test.cpp +++ b/src/test/app/MultiSign_test.cpp @@ -39,7 +39,7 @@ public: void test_noReserve() { using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); Account const alice {"alice", KeyType::secp256k1}; // Pay alice enough to meet the initial reserve, but not enough to @@ -87,7 +87,7 @@ public: void test_signerListSet() { using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); Account const alice {"alice", KeyType::ed25519}; env.fund(XRP(1000), alice); @@ -132,7 +132,7 @@ public: void test_phantomSigners() { using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); Account const alice {"alice", KeyType::ed25519}; env.fund(XRP(1000), alice); env.close(); @@ -233,7 +233,7 @@ public: void test_fee () { using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); Account const alice {"alice", KeyType::ed25519}; env.fund(XRP(1000), alice); env.close(); @@ -283,7 +283,7 @@ public: void test_misorderedSigners() { using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); Account const alice {"alice", KeyType::ed25519}; env.fund(XRP(1000), alice); env.close(); @@ -305,7 +305,7 @@ public: void test_masterSigners() { using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); Account const alice {"alice", KeyType::ed25519}; Account const becky {"becky", KeyType::secp256k1}; Account const cheri {"cheri", KeyType::ed25519}; @@ -357,7 +357,7 @@ public: void test_regularSigners() { using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); Account const alice {"alice", KeyType::secp256k1}; Account const becky {"becky", KeyType::ed25519}; Account const cheri {"cheri", KeyType::secp256k1}; @@ -415,7 +415,7 @@ public: void test_regularSignersUsingSubmitMulti() { using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); Account const alice {"alice", KeyType::secp256k1}; Account const becky {"becky", KeyType::ed25519}; Account const cheri {"cheri", KeyType::secp256k1}; @@ -618,7 +618,7 @@ public: void test_heterogeneousSigners() { using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); Account const alice {"alice", KeyType::secp256k1}; Account const becky {"becky", KeyType::ed25519}; Account const cheri {"cheri", KeyType::secp256k1}; @@ -733,7 +733,7 @@ public: void test_keyDisable() { using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); Account const alice {"alice", KeyType::ed25519}; env.fund(XRP(1000), alice); @@ -808,7 +808,7 @@ public: void test_regKey() { using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); Account const alice {"alice", KeyType::secp256k1}; env.fund(XRP(1000), alice); @@ -840,7 +840,7 @@ public: void test_txTypes() { using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); Account const alice {"alice", KeyType::secp256k1}; Account const becky {"becky", KeyType::ed25519}; Account const zelda {"zelda", KeyType::secp256k1}; @@ -924,7 +924,7 @@ public: // Verify that the text returned for signature failures is correct. using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); // lambda that submits an STTx and returns the resulting JSON. auto submitSTTx = [&env] (STTx const& stx) @@ -1058,7 +1058,7 @@ public: void test_noMultiSigners() { using namespace jtx; - Env env {*this, with_only_features(featureMultiSign)}; + Env env {*this}; Account const alice {"alice", KeyType::ed25519}; Account const becky {"becky", KeyType::secp256k1}; env.fund(XRP(1000), alice, becky); diff --git a/src/test/app/Offer_test.cpp b/src/test/app/Offer_test.cpp index ff28ba8ca8..9c8b76dba1 100644 --- a/src/test/app/Offer_test.cpp +++ b/src/test/app/Offer_test.cpp @@ -30,14 +30,6 @@ namespace test { class Offer_test : public beast::unit_test::suite { - static bool hasFeature(uint256 const& feat, std::initializer_list args) - { - for(auto const& f : args) - if (f == feat) - return true; - return false; - } - XRPAmount reserve(jtx::Env& env, std::uint32_t count) { return env.current()->fees().accountReserve (count); @@ -106,7 +98,7 @@ class Offer_test : public beast::unit_test::suite } public: - void testRmFundedOffer (std::initializer_list fs) + void testRmFundedOffer (FeatureBitset features) { testcase ("Incorrect Removal of Funded Offers"); @@ -120,7 +112,7 @@ public: // not used for the payment. using namespace jtx; - Env env {*this, with_only_features(fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -166,12 +158,12 @@ public: isOffer (env, carol, BTC (49), XRP (49))); } - void testCanceledOffer (std::initializer_list fs) + void testCanceledOffer (FeatureBitset features) { testcase ("Removing Canceled Offers"); using namespace jtx; - Env env {*this, with_only_features(fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -226,7 +218,7 @@ public: BEAST_EXPECT(!isOffer (env, alice, XRP (222), USD (111))); } - void testTinyPayment (std::initializer_list fs) + void testTinyPayment (FeatureBitset features) { testcase ("Tiny payments"); @@ -241,7 +233,7 @@ public: auto const USD = gw["USD"]; auto const EUR = gw["EUR"]; - Env env {*this, with_only_features(fs)}; + Env env {*this, features}; env.fund (XRP (10000), alice, bob, carol, gw); env.trust (USD (1000), alice, bob, carol); @@ -275,7 +267,7 @@ public: } } - void testXRPTinyPayment (std::initializer_list fs) + void testXRPTinyPayment (FeatureBitset features) { testcase ("XRP Tiny payments"); @@ -305,12 +297,15 @@ public: auto const USD = gw["USD"]; + FeatureBitset const feeEscAndFlow = + with_only_features (featureFeeEscalation, featureFlow); + for (auto withFix : {false, true}) { - if (!withFix && fs.size()) + if (!withFix && ((features & feeEscAndFlow) != FeatureBitset{})) continue; - Env env {*this, with_only_features(fs)}; + Env env {*this, features}; auto closeTime = [&] { @@ -374,7 +369,7 @@ public: } } - void testEnforceNoRipple (std::initializer_list fs) + void testEnforceNoRipple (FeatureBitset features) { testcase ("Enforce No Ripple"); @@ -391,7 +386,7 @@ public: { // No ripple with an implied account step after an offer - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -420,7 +415,7 @@ public: } { // Make sure payment works with default flags - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -452,7 +447,7 @@ public: } void - testInsufficientReserve (std::initializer_list fs) + testInsufficientReserve (FeatureBitset features) { testcase ("Insufficient Reserve"); @@ -475,7 +470,7 @@ public: // No crossing: { - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -500,7 +495,7 @@ public: // Partial cross: { - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -534,7 +529,7 @@ public: // if an offer were added. Attempt to sell IOUs to // buy XRP. If it fully crosses, we succeed. { - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -585,7 +580,7 @@ public: } void - testFillModes (std::initializer_list fs) + testFillModes (FeatureBitset features) { testcase ("Fill Modes"); @@ -600,7 +595,7 @@ public: // Fill or Kill - unless we fully cross, just charge // a fee and not place the offer on the books: { - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -645,7 +640,7 @@ public: // Immediate or Cancel - cross as much as possible // and add nothing on the books: { - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -701,7 +696,7 @@ public: // tfPassive -- place the offer without crossing it. { - Env env (*this, with_only_features (fs)); + Env env (*this, features); auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -758,7 +753,7 @@ public: // tfPassive -- cross only offers of better quality. { - Env env (*this, with_only_features (fs)); + Env env (*this, features); auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -799,7 +794,7 @@ public: } void - testMalformed(std::initializer_list fs) + testMalformed(FeatureBitset features) { testcase ("Malformed Detection"); @@ -810,7 +805,7 @@ public: auto const alice = Account {"alice"}; auto const USD = gw["USD"]; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -897,7 +892,7 @@ public: } void - testExpiration(std::initializer_list fs) + testExpiration(FeatureBitset features) { testcase ("Offer Expiration"); @@ -914,7 +909,7 @@ public: Json::StaticString const key ("Expiration"); - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -975,7 +970,7 @@ public: } void - testUnfundedCross(std::initializer_list fs) + testUnfundedCross(FeatureBitset features) { testcase ("Unfunded Crossing"); @@ -987,7 +982,7 @@ public: auto const usdOffer = USD (1000); auto const xrpOffer = XRP (1000); - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1041,7 +1036,7 @@ public: } void - testSelfCross(bool use_partner, std::initializer_list fs) + testSelfCross(bool use_partner, FeatureBitset features) { testcase (std::string("Self-crossing") + (use_partner ? ", with partner account" : "")); @@ -1053,7 +1048,7 @@ public: auto const USD = gw["USD"]; auto const BTC = gw["BTC"]; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1111,7 +1106,7 @@ public: { auto acctOffers = offersOnAccount (env, account_to_test); BEAST_EXPECT(acctOffers.size() == - (hasFeature (featureFlowCross, fs) ? 0 : 1)); + (hasFeature (featureFlowCross, features) ? 0 : 1)); for (auto const& offerPtr : acctOffers) { auto const& offer = *offerPtr; @@ -1160,7 +1155,7 @@ public: } void - testNegativeBalance(std::initializer_list fs) + testNegativeBalance(FeatureBitset features) { // This test creates an offer test for negative balance // with transfer fees and miniscule funds. @@ -1168,7 +1163,7 @@ public: using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1229,7 +1224,7 @@ public: // small_amount and transfer no XRP. The new offer crossing transfers // a single drop, rather than no drops. auto const crossingDelta = - (hasFeature (featureFlowCross, fs) ? drops (1) : drops (0)); + (hasFeature (featureFlowCross, features) ? drops (1) : drops (0)); jrr = ledgerEntryState (env, alice, gw, "USD"); BEAST_EXPECT(jrr[jss::node][sfBalance.fieldName][jss::value] == "50"); @@ -1247,7 +1242,7 @@ public: } void - testOfferCrossWithXRP(bool reverse_order, std::initializer_list fs) + testOfferCrossWithXRP(bool reverse_order, FeatureBitset features) { testcase (std::string("Offer Crossing with XRP, ") + (reverse_order ? "Reverse" : "Normal") + @@ -1255,7 +1250,7 @@ public: using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1309,13 +1304,13 @@ public: } void - testOfferCrossWithLimitOverride(std::initializer_list fs) + testOfferCrossWithLimitOverride(FeatureBitset features) { testcase ("Offer Crossing with Limit Override"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1359,13 +1354,13 @@ public: } void - testOfferAcceptThenCancel(std::initializer_list fs) + testOfferAcceptThenCancel(FeatureBitset features) { testcase ("Offer Accept then Cancel."); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1391,14 +1386,14 @@ public: } void - testOfferCancelPastAndFuture(std::initializer_list fs) + testOfferCancelPastAndFuture(FeatureBitset features) { testcase ("Offer Cancel Past and Future Sequence."); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1426,13 +1421,13 @@ public: } void - testCurrencyConversionEntire(std::initializer_list fs) + testCurrencyConversionEntire(FeatureBitset features) { testcase ("Currency Conversion: Entire Offer"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1491,13 +1486,13 @@ public: } void - testCurrencyConversionIntoDebt(std::initializer_list fs) + testCurrencyConversionIntoDebt(FeatureBitset features) { testcase ("Currency Conversion: Offerer Into Debt"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1524,13 +1519,13 @@ public: } void - testCurrencyConversionInParts(std::initializer_list fs) + testCurrencyConversionInParts(FeatureBitset features) { testcase ("Currency Conversion: In Parts"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1616,13 +1611,13 @@ public: } void - testCrossCurrencyStartXRP(std::initializer_list fs) + testCrossCurrencyStartXRP(FeatureBitset features) { testcase ("Cross Currency Payment: Start with XRP"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1660,13 +1655,13 @@ public: } void - testCrossCurrencyEndXRP(std::initializer_list fs) + testCrossCurrencyEndXRP(FeatureBitset features) { testcase ("Cross Currency Payment: End with XRP"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1712,13 +1707,13 @@ public: } void - testCrossCurrencyBridged(std::initializer_list fs) + testCrossCurrencyBridged(FeatureBitset features) { testcase ("Cross Currency Payment: Bridged"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1782,13 +1777,13 @@ public: } void - testOfferFeesConsumeFunds(std::initializer_list fs) + testOfferFeesConsumeFunds(FeatureBitset features) { testcase ("Offer Fees Consume Funds"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1840,13 +1835,13 @@ public: } void - testOfferCreateThenCross(std::initializer_list fs) + testOfferCreateThenCross(FeatureBitset features) { testcase ("Offer Create, then Cross"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1880,13 +1875,13 @@ public: } void - testSellFlagBasic(std::initializer_list fs) + testSellFlagBasic(FeatureBitset features) { testcase ("Offer tfSell: Basic Sell"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1926,13 +1921,13 @@ public: } void - testSellFlagExceedLimit(std::initializer_list fs) + testSellFlagExceedLimit(FeatureBitset features) { testcase ("Offer tfSell: 2x Sell Exceed Limit"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1974,13 +1969,13 @@ public: } void - testGatewayCrossCurrency(std::initializer_list fs) + testGatewayCrossCurrency(FeatureBitset features) { testcase ("Client Issue #535: Gateway Cross Currency"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -2077,7 +2072,7 @@ public: } } - void testPartialCross (std::initializer_list fs) + void testPartialCross (FeatureBitset features) { // Test a number of different corner cases regarding adding a // possibly crossable offer to an account. The test is table @@ -2089,7 +2084,7 @@ public: auto const gw = Account("gateway"); auto const USD = gw["USD"]; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -2237,7 +2232,7 @@ public: } void - testXRPDirectCross (std::initializer_list fs) + testXRPDirectCross (FeatureBitset features) { testcase ("XRP Direct Crossing"); @@ -2251,7 +2246,7 @@ public: auto const usdOffer = USD(1000); auto const xrpOffer = XRP(1000); - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -2321,7 +2316,7 @@ public: } void - testDirectCross (std::initializer_list fs) + testDirectCross (FeatureBitset features) { testcase ("Direct Crossing"); @@ -2336,7 +2331,7 @@ public: auto const usdOffer = USD(1000); auto const eurOffer = EUR(1000); - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -2417,7 +2412,7 @@ public: } void - testBridgedCross (std::initializer_list fs) + testBridgedCross (FeatureBitset features) { testcase ("Bridged Crossing"); @@ -2433,7 +2428,7 @@ public: auto const usdOffer = USD(1000); auto const eurOffer = EUR(1000); - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -2519,7 +2514,7 @@ public: } void - testSellOffer (std::initializer_list fs) + testSellOffer (FeatureBitset features) { // Test a number of different corner cases regarding offer crossing // when the tfSell flag is set. The test is table driven so it @@ -2531,7 +2526,7 @@ public: auto const gw = Account("gateway"); auto const USD = gw["USD"]; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -2695,7 +2690,7 @@ public: } void - testSellWithFillOrKill (std::initializer_list fs) + testSellWithFillOrKill (FeatureBitset features) { // Test a number of different corner cases regarding offer crossing // when both the tfSell flag and tfFillOrKill flags are set. @@ -2708,7 +2703,7 @@ public: auto const bob = Account("bob"); auto const USD = gw["USD"]; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -2779,7 +2774,7 @@ public: } void - testTransferRateOffer (std::initializer_list fs) + testTransferRateOffer (FeatureBitset features) { testcase ("Transfer Rate Offer"); @@ -2788,7 +2783,7 @@ public: auto const gw1 = Account("gateway1"); auto const USD = gw1["USD"]; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3092,7 +3087,7 @@ public: } void - testSelfCrossOffer1 (std::initializer_list fs) + testSelfCrossOffer1 (FeatureBitset features) { // The following test verifies some correct but slightly surprising // behavior in offer crossing. The scenario: @@ -3113,7 +3108,7 @@ public: auto const gw = Account("gateway"); auto const USD = gw["USD"]; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3166,7 +3161,7 @@ public: } void - testSelfCrossOffer2 (std::initializer_list fs) + testSelfCrossOffer2 (FeatureBitset features) { using namespace jtx; @@ -3176,7 +3171,7 @@ public: auto const USD = gw1["USD"]; auto const EUR = gw2["EUR"]; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3281,15 +3276,15 @@ public: } void - testSelfCrossOffer (std::initializer_list fs) + testSelfCrossOffer (FeatureBitset features) { testcase ("Self Cross Offer"); - testSelfCrossOffer1 (fs); - testSelfCrossOffer2 (fs); + testSelfCrossOffer1 (features); + testSelfCrossOffer2 (features); } void - testSelfIssueOffer (std::initializer_list fs) + testSelfIssueOffer (FeatureBitset features) { // Folks who issue their own currency have, in effect, as many // funds as they are trusted for. This test used to fail because @@ -3297,7 +3292,7 @@ public: // correctly now. using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3338,7 +3333,7 @@ public: } void - testBadPathAssert (std::initializer_list fs) + testBadPathAssert (FeatureBitset features) { // At one point in the past this invalid path caused an assert. It // should not be possible for user-supplied data to cause an assert. @@ -3349,8 +3344,7 @@ public: // The problem was identified when featureOwnerPaysFee was enabled, // so make sure that gets included. - Env env {*this, - with_only_features(fs) | with_only_features(featureOwnerPaysFee)}; + Env env {*this, features | with_only_features(featureOwnerPaysFee)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3400,7 +3394,7 @@ public: // Determine which TEC code we expect. TER const tecExpect = - hasFeature(featureFlow, fs) ? temBAD_PATH : tecPATH_DRY; + hasFeature(featureFlow, features) ? temBAD_PATH : tecPATH_DRY; // This payment caused the assert. env (pay (ann, ann, D_BUX(30)), @@ -3418,7 +3412,7 @@ public: } } - void testDirectToDirectPath (std::initializer_list fs) + void testDirectToDirectPath (FeatureBitset features) { // The offer crossing code expects that a DirectStep is always // preceded by a BookStep. In one instance the default path @@ -3428,7 +3422,7 @@ public: using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3474,7 +3468,7 @@ public: env.require (offers (cam, 0)); } - void testSelfCrossLowQualityOffer (std::initializer_list fs) + void testSelfCrossLowQualityOffer (FeatureBitset features) { // The Flow offer crossing code used to assert if an offer was made // for more XRP than the offering account held. This unit test @@ -3483,7 +3477,7 @@ public: using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3513,7 +3507,7 @@ public: BTC(0.687), drops(20000000000)), ter (tecINSUF_RESERVE_OFFER)); } - void testOfferInScaling (std::initializer_list fs) + void testOfferInScaling (FeatureBitset features) { // The Flow offer crossing code had a case where it was not rounding // the offer crossing correctly after a partial crossing. The @@ -3523,7 +3517,7 @@ public: using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3563,7 +3557,7 @@ public: } } - void testOfferInScalingWithXferRate (std::initializer_list fs) + void testOfferInScalingWithXferRate (FeatureBitset features) { // After adding the previous case, there were still failing rounding // cases in Flow offer crossing. This one was because the gateway @@ -3572,7 +3566,7 @@ public: using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3617,7 +3611,7 @@ public: } } - void testOfferThresholdWithReducedFunds (std::initializer_list fs) + void testOfferThresholdWithReducedFunds (FeatureBitset features) { // Another instance where Flow offer crossing was not always // working right was if the Taker had fewer funds than the Offer @@ -3626,7 +3620,7 @@ public: using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3679,13 +3673,13 @@ public: } } - void testTinyOffer (std::initializer_list fs) + void testTinyOffer (FeatureBitset features) { testcase ("Tiny Offer"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time() + 100 * env.closed()->info().closeTimeResolution; @@ -3728,7 +3722,7 @@ public: env.require (balance (bob, startXrpBalance - (fee * 2) + drops(1))); } - void testSelfPayXferFeeOffer (std::initializer_list fs) + void testSelfPayXferFeeOffer (FeatureBitset features) { testcase ("Self Pay Xfer Fee"); // The old offer crossing code does not charge a transfer fee @@ -3768,7 +3762,7 @@ public: using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time() + 100 * env.closed()->info().closeTimeResolution; @@ -3884,7 +3878,7 @@ public: } } - void testSelfPayUnlimitedFunds (std::initializer_list fs) + void testSelfPayUnlimitedFunds (FeatureBitset features) { testcase ("Self Pay Unlimited Funds"); // The Taker offer crossing code recognized when Alice was paying @@ -3920,7 +3914,7 @@ public: using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time() + 100 * env.closed()->info().closeTimeResolution; @@ -3975,7 +3969,7 @@ public: // Pick the right tests. auto const& tests = - hasFeature(featureFlowCross, fs) ? flowTests : takerTests; + hasFeature(featureFlowCross, features) ? flowTests : takerTests; for (auto const& t : tests) { @@ -4043,13 +4037,13 @@ public: } } - void testRequireAuth (std::initializer_list fs) + void testRequireAuth (FeatureBitset features) { testcase ("lsfRequireAuth"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time() + 100 * env.closed()->info().closeTimeResolution; @@ -4097,7 +4091,7 @@ public: env.require (balance (bob, gwUSD(10))); } - void testMissingAuth (std::initializer_list fs) + void testMissingAuth (FeatureBitset features) { testcase ("Missing Auth"); // 1. alice creates an offer to acquire USD/gw, an asset for which @@ -4121,7 +4115,7 @@ public: using namespace jtx; - Env env {*this, with_only_features(fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time() + 100 * env.closed()->info().closeTimeResolution; @@ -4164,7 +4158,7 @@ public: env.close(); std::uint32_t const bobOfferSeq = env.seq (bob) - 1; - bool const flowCross = hasFeature (featureFlowCross, fs); + bool const flowCross = hasFeature (featureFlowCross, features); env.require (offers (alice, 0)); if (flowCross) @@ -4238,12 +4232,12 @@ public: env.require (balance (bob, gwUSD(10))); } - void testRCSmoketest(std::initializer_list fs) + void testRCSmoketest(FeatureBitset features) { testcase("RippleConnect Smoketest payment flow"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time() + 100 * env.closed()->info().closeTimeResolution; @@ -4330,13 +4324,13 @@ public: env (pay (hotUS, coldEU, EUR(10)), sendmax (USD(11.1223326))); } - void testSelfAuth (std::initializer_list fs) + void testSelfAuth (FeatureBitset features) { testcase ("Self Auth"); using namespace jtx; - Env env {*this, with_only_features (fs)}; + Env env {*this, features}; auto const closeTime = fix1449Time() + 100 * env.closed()->info().closeTimeResolution; @@ -4370,8 +4364,7 @@ public: env.close(); // The test behaves differently with or without FlowCross. - bool const flowCross = - std::find (fs.begin(), fs.end(), featureFlowCross) != fs.end(); + bool const flowCross = hasFeature (featureFlowCross, features); // Before FlowCross an account with lsfRequireAuth set could not // create an offer to buy their own currency. After FlowCross @@ -4406,15 +4399,18 @@ public: env.require (offers (gw, 0)); } - void testTickSize (std::initializer_list fs) + void testTickSize (FeatureBitset features) { testcase ("Tick Size"); using namespace jtx; + // Should be called with TickSize enabled. + BEAST_EXPECT (hasFeature (featureTickSize, features)); + // Try to set tick size without enabling feature { - Env env {*this, with_only_features(fs)}; + Env env {*this, features & ~with_only_features(featureTickSize)}; auto const gw = Account {"gateway"}; env.fund (XRP(10000), gw); @@ -4423,12 +4419,9 @@ public: env(txn, ter(temDISABLED)); } - auto const fsPlus = - with_only_features(fs) | with_only_features(featureTickSize); - // Try to set tick size out of range { - Env env {*this, fsPlus}; + Env env {*this, features}; auto const gw = Account {"gateway"}; env.fund (XRP(10000), gw); @@ -4461,7 +4454,7 @@ public: BEAST_EXPECT (! env.le(gw)->isFieldPresent (sfTickSize)); } - Env env {*this, fsPlus}; + Env env {*this, features}; auto const gw = Account {"gateway"}; auto const alice = Account {"alice"}; auto const XTS = gw["XTS"]; @@ -4529,74 +4522,79 @@ public: BEAST_EXPECT (++it == offers.end()); } - void testAll(std::initializer_list fs) + void testAll(FeatureBitset features) { - testCanceledOffer(fs); - testRmFundedOffer(fs); - testTinyPayment(fs); - testXRPTinyPayment(fs); - testEnforceNoRipple(fs); - testInsufficientReserve(fs); - testFillModes(fs); - testMalformed(fs); - testExpiration(fs); - testUnfundedCross(fs); - testSelfCross(false, fs); - testSelfCross(true, fs); - testNegativeBalance(fs); - testOfferCrossWithXRP(true, fs); - testOfferCrossWithXRP(false, fs); - testOfferCrossWithLimitOverride(fs); - testOfferAcceptThenCancel(fs); - testOfferCancelPastAndFuture(fs); - testCurrencyConversionEntire(fs); - testCurrencyConversionIntoDebt(fs); - testCurrencyConversionInParts(fs); - testCrossCurrencyStartXRP(fs); - testCrossCurrencyEndXRP(fs); - testCrossCurrencyBridged(fs); - testOfferFeesConsumeFunds(fs); - testOfferCreateThenCross(fs); - testSellFlagBasic(fs); - testSellFlagExceedLimit(fs); - testGatewayCrossCurrency(fs); - testPartialCross(fs); - testXRPDirectCross(fs); - testDirectCross(fs); - testBridgedCross(fs); - testSellOffer(fs); - testSellWithFillOrKill(fs); - testTransferRateOffer(fs); - testSelfCrossOffer(fs); - testSelfIssueOffer(fs); - testBadPathAssert(fs); - testDirectToDirectPath(fs); - testSelfCrossLowQualityOffer(fs); - testOfferInScaling(fs); - testOfferInScalingWithXferRate(fs); - testOfferThresholdWithReducedFunds(fs); - testTinyOffer(fs); - testSelfPayXferFeeOffer(fs); - testSelfPayUnlimitedFunds(fs); - testRequireAuth(fs); - testMissingAuth(fs); - testRCSmoketest(fs); - testSelfAuth(fs); - testTickSize(fs); + testCanceledOffer(features); + testRmFundedOffer(features); + testTinyPayment(features); + testXRPTinyPayment(features); + testEnforceNoRipple(features); + testInsufficientReserve(features); + testFillModes(features); + testMalformed(features); + testExpiration(features); + testUnfundedCross(features); + testSelfCross(false, features); + testSelfCross(true, features); + testNegativeBalance(features); + testOfferCrossWithXRP(true, features); + testOfferCrossWithXRP(false, features); + testOfferCrossWithLimitOverride(features); + testOfferAcceptThenCancel(features); + testOfferCancelPastAndFuture(features); + testCurrencyConversionEntire(features); + testCurrencyConversionIntoDebt(features); + testCurrencyConversionInParts(features); + testCrossCurrencyStartXRP(features); + testCrossCurrencyEndXRP(features); + testCrossCurrencyBridged(features); + testOfferFeesConsumeFunds(features); + testOfferCreateThenCross(features); + testSellFlagBasic(features); + testSellFlagExceedLimit(features); + testGatewayCrossCurrency(features); + testPartialCross (features); + testXRPDirectCross (features); + testDirectCross (features); + testBridgedCross (features); + testSellOffer (features); + testSellWithFillOrKill (features); + testTransferRateOffer(features); + testSelfCrossOffer (features); + testSelfIssueOffer (features); + testBadPathAssert (features); + testDirectToDirectPath (features); + testSelfCrossLowQualityOffer (features); + testOfferInScaling (features); + testOfferInScalingWithXferRate (features); + testOfferThresholdWithReducedFunds (features); + testTinyOffer (features); + testSelfPayXferFeeOffer (features); + testSelfPayUnlimitedFunds (features); + testRequireAuth (features); + testMissingAuth (features); + testRCSmoketest (features); + testSelfAuth (features); + testTickSize (features); } + void run () override { -// The first three test variants below passed at one time in the past (and -// should still pass) but are commented out to conserve test time. -// testAll(jtx::no_features ); -// testAll({ featureFlowCross }); -// testAll({featureFlow }); - testAll({featureFlow, featureFlowCross, - featureFeeEscalation, fix1513 }); - testAll({ featureFlow, fix1373, - featureFeeEscalation, fix1513 }); - testAll({featureFlow, fix1373, featureFlowCross, - featureFeeEscalation, fix1513 }); + using namespace jtx; + auto const all = supported_amendments(); + auto const flow = with_only_features (featureFlow); + auto const f1373 = with_only_features (fix1373); + auto const flowCross = with_only_features (featureFlowCross); + (void) flow; + + // The first three test variants below passed at one time in the past + // (and should still pass) but are commented out to conserve test time. +// testAll(all & ~(flow | f1373 | flowCross)); +// testAll(all & ~(flow | f1373 )); +// testAll(all & ~( f1373 | flowCross)); + testAll(all & ~( f1373 )); + testAll(all & ~( flowCross)); + testAll(all ); } }; @@ -4604,31 +4602,32 @@ class Offer_manual_test : public Offer_test { void run() override { - testAll({}); - testAll({ featureFeeEscalation }); - testAll({ featureFeeEscalation, fix1513 }); - testAll({ featureFlowCross }); - testAll({ featureFlowCross, - featureFeeEscalation }); - testAll({ featureFlowCross, - featureFeeEscalation, fix1513 }); - testAll({featureFlow }); - testAll({ featureFlow, featureFeeEscalation }); - testAll({ featureFlow, featureFeeEscalation, fix1513 }); - testAll({featureFlow, featureFlowCross}); - testAll({featureFlow, featureFlowCross, - featureFeeEscalation }); - testAll({featureFlow, featureFlowCross, - featureFeeEscalation, fix1513 }); - testAll({featureFlow, fix1373 }); - testAll({ featureFlow, fix1373, featureFeeEscalation }); - testAll({ featureFlow, fix1373, featureFeeEscalation, fix1513 }); - testAll({ featureFlow, fix1373, featureFlowCross }); - testAll({featureFlow, fix1373, featureFlowCross, - featureFeeEscalation }); - testAll({featureFlow, fix1373, featureFlowCross, - featureFeeEscalation, fix1513 }); + using namespace jtx; + auto const all = supported_amendments(); + auto const feeEscalation = with_only_features (featureFeeEscalation); + auto const flow = with_only_features (featureFlow); + auto const f1373 = with_only_features (fix1373); + auto const flowCross = with_only_features (featureFlowCross); + auto const f1513 = with_only_features (fix1513); + testAll(all & ~(feeEscalation | flow | f1373 | flowCross | f1513)); + testAll(all & ~( flow | f1373 | flowCross | f1513)); + testAll(all & ~( flow | f1373 | flowCross )); + testAll(all & ~(feeEscalation | flow | f1373 | f1513)); + testAll(all & ~( flow | f1373 | f1513)); + testAll(all & ~( flow | f1373 )); + testAll(all & ~(feeEscalation | f1373 | flowCross | f1513)); + testAll(all & ~( f1373 | flowCross | f1513)); + testAll(all & ~( f1373 | flowCross )); + testAll(all & ~(feeEscalation | f1373 | f1513)); + testAll(all & ~( f1373 | f1513)); + testAll(all & ~( f1373 )); + testAll(all & ~(feeEscalation | flowCross | f1513)); + testAll(all & ~( flowCross | f1513)); + testAll(all & ~( flowCross )); + testAll(all & ~(feeEscalation | f1513)); + testAll(all & ~( f1513)); + testAll(all ); } }; diff --git a/src/test/app/OversizeMeta_test.cpp b/src/test/app/OversizeMeta_test.cpp index 7e921856eb..62040198e2 100644 --- a/src/test/app/OversizeMeta_test.cpp +++ b/src/test/app/OversizeMeta_test.cpp @@ -35,7 +35,10 @@ public: { using namespace jtx; for (std::size_t i = 1; i <= n; ++i) + { env(offer("alice", XRP(i), iou(1))); + env.close(); + } } void @@ -47,8 +50,8 @@ public: env.disable_sigs(); auto const gw = Account("gateway"); auto const USD = gw["USD"]; - env.fund(XRP(billion), gw, "alice", "bob", "carol"); - env.trust(USD(billion), "alice", "bob", "carol"); + env.fund(XRP(billion), gw, "alice"); + env.trust(USD(billion), "alice"); env(pay(gw, "alice", USD(billion))); createOffers(env, USD, n); } @@ -88,7 +91,10 @@ public: { using namespace jtx; for (std::size_t i = 1; i <= n; ++i) + { env(offer("alice", XRP(1), iou(1))); + env.close(); + } } void @@ -101,8 +107,8 @@ public: env.disable_sigs(); auto const gw = Account("gateway"); auto const USD = gw["USD"]; - env.fund(XRP(billion), gw, "alice", "bob", "carol"); - env.trust(USD(billion), "alice", "bob", "carol"); + env.fund(XRP(billion), gw, "alice"); + env.trust(USD(billion), "alice"); env(pay(gw, "alice", USD(billion))); createOffers(env, USD, n); env(pay("alice", gw, USD(billion))); @@ -151,7 +157,10 @@ public: { using namespace jtx; for (std::size_t i = 1; i <= n; ++i) + { env(offer("alice", XRP(i), iou(1))); + env.close(); + } } bool @@ -163,8 +172,8 @@ public: env.disable_sigs(); auto const gw = Account("gateway"); auto const USD = gw["USD"]; - env.fund(XRP(billion), gw, "alice", "bob", "carol"); - env.trust(USD(billion), "alice", "bob", "carol"); + env.fund(XRP(billion), gw, "alice"); + env.trust(USD(billion), "alice"); env(pay(gw, "alice", USD(billion))); createOffers(env, USD, n); env(pay("alice", gw, USD(billion))); diff --git a/src/test/app/PayStrand_test.cpp b/src/test/app/PayStrand_test.cpp index c344d25edf..534cdb4da9 100644 --- a/src/test/app/PayStrand_test.cpp +++ b/src/test/app/PayStrand_test.cpp @@ -625,14 +625,14 @@ struct PayStrandAllPairs_test : public beast::unit_test::suite { // Test every combination of element type pairs on a path void - testAllPairs(std::initializer_list fs) + testAllPairs(FeatureBitset features) { testcase("All pairs"); using namespace jtx; using RippleCalc = ::ripple::path::RippleCalc; ExistingElementPool eep; - Env env(*this, with_only_features(fs)); + Env env(*this, features); auto const closeTime = fix1298Time() + 100 * env.closed()->info().closeTimeResolution; @@ -847,8 +847,8 @@ struct PayStrandAllPairs_test : public beast::unit_test::suite void run() override { - testAllPairs({featureFlow, fix1373}); - testAllPairs({featureFlow, fix1373, featureFlowCross}); + testAllPairs(jtx::supported_features_except (featureFlowCross)); + testAllPairs(jtx::supported_amendments()); } }; @@ -856,15 +856,8 @@ BEAST_DEFINE_TESTSUITE_MANUAL(PayStrandAllPairs, app, ripple); struct PayStrand_test : public beast::unit_test::suite { - static bool hasFeature(uint256 const& feat, std::initializer_list args) - { - for(auto const& f : args) - if (f == feat) - return true; - return false; - } void - testToStrand(std::initializer_list fs) + testToStrand(FeatureBitset features) { testcase("To Strand"); @@ -910,7 +903,7 @@ struct PayStrand_test : public beast::unit_test::suite }; { - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, gw); env.trust(USD(1000), alice, bob); env.trust(EUR(1000), alice, bob); @@ -951,7 +944,7 @@ struct PayStrand_test : public beast::unit_test::suite }; { - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, carol, gw); test(env, USD, boost::none, STPath(), terNO_LINE); @@ -1134,7 +1127,7 @@ struct PayStrand_test : public beast::unit_test::suite // cannot have more than one offer with the same output issue using namespace jtx; - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, carol, gw); env.trust(USD(10000), alice, bob, carol); @@ -1156,7 +1149,7 @@ struct PayStrand_test : public beast::unit_test::suite } { - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, noripple(gw)); env.trust(USD(1000), alice, bob); env(pay(gw, alice, USD(100))); @@ -1165,7 +1158,7 @@ struct PayStrand_test : public beast::unit_test::suite { // check global freeze - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, gw); env.trust(USD(1000), alice, bob); env(pay(gw, alice, USD(100))); @@ -1190,7 +1183,7 @@ struct PayStrand_test : public beast::unit_test::suite } { // Freeze between gw and alice - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, gw); env.trust(USD(1000), alice, bob); env(pay(gw, alice, USD(100))); @@ -1203,7 +1196,7 @@ struct PayStrand_test : public beast::unit_test::suite // check no auth // An account may require authorization to receive IOUs from an // issuer - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, gw); env(fset(gw, asfRequireAuth)); env.trust(USD(1000), alice, bob); @@ -1231,7 +1224,7 @@ struct PayStrand_test : public beast::unit_test::suite } { // Check path with sendMax and node with correct sendMax already set - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, gw); env.trust(USD(1000), alice, bob); env.trust(EUR(1000), alice, bob); @@ -1246,7 +1239,7 @@ struct PayStrand_test : public beast::unit_test::suite { // last step xrp from offer - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, gw); env.trust(USD(1000), alice, bob); env(pay(gw, alice, USD(100))); @@ -1273,7 +1266,7 @@ struct PayStrand_test : public beast::unit_test::suite } void - testRIPD1373(std::initializer_list fs) + testRIPD1373(FeatureBitset features) { using namespace jtx; testcase("RIPD1373"); @@ -1285,9 +1278,9 @@ struct PayStrand_test : public beast::unit_test::suite auto const USD = gw["USD"]; auto const EUR = gw["EUR"]; - if (hasFeature(fix1373, fs)) + if (hasFeature(fix1373, features)) { - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, gw); env.trust(USD(1000), alice, bob); @@ -1319,7 +1312,7 @@ struct PayStrand_test : public beast::unit_test::suite } { - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, carol, gw); env.trust(USD(10000), alice, bob, carol); @@ -1337,7 +1330,7 @@ struct PayStrand_test : public beast::unit_test::suite } { - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, carol, gw); env.trust(USD(10000), alice, bob, carol); @@ -1357,7 +1350,7 @@ struct PayStrand_test : public beast::unit_test::suite } void - testLoop(std::initializer_list fs) + testLoop(FeatureBitset features) { testcase("test loop"); using namespace jtx; @@ -1371,7 +1364,7 @@ struct PayStrand_test : public beast::unit_test::suite auto const CNY = gw["CNY"]; { - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, carol, gw); env.trust(USD(10000), alice, bob, carol); @@ -1383,8 +1376,8 @@ struct PayStrand_test : public beast::unit_test::suite env(offer(bob, USD(100), XRP(100)), txflags(tfPassive)); auto const expectedResult = [&] { - if (hasFeature(featureFlow, fs) && - !hasFeature(fix1373, fs)) + if (hasFeature(featureFlow, features) && + !hasFeature(fix1373, features)) return tesSUCCESS; return temBAD_PATH_LOOP; }(); @@ -1396,7 +1389,7 @@ struct PayStrand_test : public beast::unit_test::suite ter(expectedResult)); } { - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, carol, gw); env.trust(USD(10000), alice, bob, carol); @@ -1421,7 +1414,7 @@ struct PayStrand_test : public beast::unit_test::suite } void - testNoAccount(std::initializer_list fs) + testNoAccount(FeatureBitset features) { testcase("test no account"); using namespace jtx; @@ -1431,7 +1424,7 @@ struct PayStrand_test : public beast::unit_test::suite auto const gw = Account("gw"); auto const USD = gw["USD"]; - Env env(*this, with_only_features(fs)); + Env env(*this, features); env.fund(XRP(10000), alice, bob, gw); STAmount sendMax{USD.issue(), 100, 1}; @@ -1479,17 +1472,26 @@ struct PayStrand_test : public beast::unit_test::suite void run() override { - testToStrand({featureFlow}); - testToStrand({featureFlow, fix1373}); - testToStrand({featureFlow, fix1373, featureFlowCross}); - testRIPD1373({}); - testRIPD1373({featureFlow, fix1373}); - testRIPD1373({featureFlow, fix1373, featureFlowCross}); - testLoop({}); - testLoop({featureFlow}); - testLoop({featureFlow, fix1373}); - testLoop({featureFlow, fix1373, featureFlowCross}); - testNoAccount({featureFlow, fix1373}); + using namespace jtx; + testToStrand(supported_features_except (fix1373, featureFlowCross)); + testToStrand(supported_features_except ( featureFlowCross)); + testToStrand(supported_amendments ()); + + testRIPD1373( + supported_features_except (featureFlow, fix1373, featureFlowCross)); + testRIPD1373( + supported_features_except ( featureFlowCross)); + testRIPD1373(supported_amendments ()); + + testLoop( + supported_features_except (featureFlow, fix1373, featureFlowCross)); + testLoop( + supported_features_except ( fix1373, featureFlowCross)); + testLoop( + supported_features_except ( featureFlowCross)); + testLoop(supported_amendments ()); + + testNoAccount(supported_amendments ()); } }; diff --git a/src/test/app/Regression_test.cpp b/src/test/app/Regression_test.cpp index d98654c28c..f301ab4886 100644 --- a/src/test/app/Regression_test.cpp +++ b/src/test/app/Regression_test.cpp @@ -170,8 +170,7 @@ struct Regression_test : public beast::unit_test::suite cfg->section("transaction_queue") .set("minimum_txn_in_ledger_standalone", "3"); return cfg; - }), - with_features(featureFeeEscalation, fix1513)); + })); Env_ss envs(env); auto const alice = Account("alice"); diff --git a/src/test/app/SetAuth_test.cpp b/src/test/app/SetAuth_test.cpp index 930f34ee4d..809044767e 100644 --- a/src/test/app/SetAuth_test.cpp +++ b/src/test/app/SetAuth_test.cpp @@ -46,19 +46,23 @@ struct SetAuth_test : public beast::unit_test::suite return jv; } - void testAuth(std::initializer_list fs) + void testAuth(FeatureBitset features) { + // featureTrustSetAuth should always be set by the caller. + BEAST_EXPECT (hasFeature (featureTrustSetAuth, features)); + using namespace jtx; auto const gw = Account("gw"); auto const USD = gw["USD"]; { - Env env(*this, with_only_features(fs)); + Env env(*this, features & ~with_only_features(featureTrustSetAuth)); env.fund(XRP(100000), "alice", gw); env(fset(gw, asfRequireAuth)); env(auth(gw, "alice", "USD"), ter(tecNO_LINE_REDUNDANT)); } { - Env env(*this, with_only_features(featureTrustSetAuth)); + Env env(*this, features); + env.fund(XRP(100000), "alice", "bob", gw); env(fset(gw, asfRequireAuth)); env(auth(gw, "alice", "USD")); @@ -75,10 +79,14 @@ struct SetAuth_test : public beast::unit_test::suite void run() override { - testAuth({}); - testAuth({featureFlow}); - testAuth({featureFlow, fix1373}); - testAuth({featureFlow, fix1373, featureFlowCross}); + using namespace jtx; + testAuth(supported_features_except ( + featureFlow, fix1373, featureFlowCross)); + testAuth(supported_features_except ( + fix1373, featureFlowCross)); + testAuth(supported_features_except ( + featureFlowCross)); + testAuth(supported_amendments()); } }; diff --git a/src/test/app/Ticket_test.cpp b/src/test/app/Ticket_test.cpp index 6d275103ca..65c4561d6f 100644 --- a/src/test/app/Ticket_test.cpp +++ b/src/test/app/Ticket_test.cpp @@ -126,7 +126,7 @@ class Ticket_test : public beast::unit_test::suite testcase ("Cancel Nonexistent"); using namespace test::jtx; - Env env {*this, with_only_features (featureTickets)}; + Env env {*this, supported_features_plus (featureTickets)}; env (ticket::cancel (env.master, idOne), ter (tecNO_ENTRY)); } @@ -135,7 +135,7 @@ class Ticket_test : public beast::unit_test::suite testcase ("Create/Cancel Ticket with Bad Fee, Fail Preflight"); using namespace test::jtx; - Env env {*this, with_only_features (featureTickets)}; + Env env {*this, supported_features_plus (featureTickets)}; env (ticket::create (env.master), fee (XRP (-1)), ter (temBAD_FEE)); env (ticket::cancel (env.master, idOne), fee (XRP (-1)), ter (temBAD_FEE)); @@ -146,7 +146,7 @@ class Ticket_test : public beast::unit_test::suite testcase ("Create Tickets with Nonexistent Accounts"); using namespace test::jtx; - Env env {*this, with_only_features (featureTickets)}; + Env env {*this, supported_features_plus (featureTickets)}; Account alice {"alice"}; env.memoize (alice); @@ -162,7 +162,7 @@ class Ticket_test : public beast::unit_test::suite testcase ("Create Tickets with Same Account and Target"); using namespace test::jtx; - Env env {*this, with_only_features (featureTickets)}; + Env env {*this, supported_features_plus (featureTickets)}; env (ticket::create (env.master, env.master)); auto cr = checkTicketMeta (env); @@ -183,7 +183,7 @@ class Ticket_test : public beast::unit_test::suite testcase ("Create Ticket and Then Cancel by Creator"); using namespace test::jtx; - Env env {*this, with_only_features (featureTickets)}; + Env env {*this, supported_features_plus (featureTickets)}; // create and verify env (ticket::create (env.master)); @@ -215,7 +215,7 @@ class Ticket_test : public beast::unit_test::suite testcase ("Create Ticket Insufficient Reserve"); using namespace test::jtx; - Env env {*this, with_only_features (featureTickets)}; + Env env {*this, supported_features_plus (featureTickets)}; Account alice {"alice"}; env.fund (env.current ()->fees ().accountReserve (0), alice); @@ -229,7 +229,7 @@ class Ticket_test : public beast::unit_test::suite testcase ("Create Ticket and Then Cancel by Target"); using namespace test::jtx; - Env env {*this, with_only_features (featureTickets)}; + Env env {*this, supported_features_plus (featureTickets)}; Account alice {"alice"}; env.fund (XRP (10000), alice); @@ -275,7 +275,7 @@ class Ticket_test : public beast::unit_test::suite testcase ("Create Ticket with Future Expiration"); using namespace test::jtx; - Env env {*this, with_only_features (featureTickets)}; + Env env {*this, supported_features_plus (featureTickets)}; // create and verify uint32_t expire = @@ -300,7 +300,7 @@ class Ticket_test : public beast::unit_test::suite testcase ("Create Ticket with Zero Expiration"); using namespace test::jtx; - Env env {*this, with_only_features (featureTickets)}; + Env env {*this, supported_features_plus (featureTickets)}; // create and verify env (ticket::create (env.master, 0u), ter (temBAD_EXPIRATION)); @@ -311,7 +311,7 @@ class Ticket_test : public beast::unit_test::suite testcase ("Create Ticket with Past Expiration"); using namespace test::jtx; - Env env {*this, with_only_features (featureTickets)}; + Env env {*this, supported_features_plus (featureTickets)}; env.timeKeeper ().adjustCloseTime (days {2}); env.close (); @@ -340,7 +340,7 @@ class Ticket_test : public beast::unit_test::suite testcase ("Create Ticket and Allow to Expire"); using namespace test::jtx; - Env env {*this, with_only_features (featureTickets)}; + Env env {*this, supported_features_plus (featureTickets)}; // create and verify uint32_t expire = diff --git a/src/test/app/TrustAndBalance_test.cpp b/src/test/app/TrustAndBalance_test.cpp index 4f405deb6c..47052cb5c8 100644 --- a/src/test/app/TrustAndBalance_test.cpp +++ b/src/test/app/TrustAndBalance_test.cpp @@ -46,12 +46,12 @@ class TrustAndBalance_test : public beast::unit_test::suite }; void - testPayNonexistent (std::initializer_list fs) + testPayNonexistent (FeatureBitset features) { testcase ("Payment to Nonexistent Account"); using namespace test::jtx; - Env env {*this, with_only_features(fs)}; + Env env {*this, features}; env (pay (env.master, "alice", XRP(1)), ter(tecNO_DST_INSUF_XRP)); env.close(); } @@ -162,12 +162,12 @@ class TrustAndBalance_test : public beast::unit_test::suite } void - testDirectRipple (std::initializer_list fs) + testDirectRipple (FeatureBitset features) { testcase ("Direct Payment, Ripple"); using namespace test::jtx; - Env env {*this, with_only_features(fs)}; + Env env {*this, features}; Account alice {"alice"}; Account bob {"bob"}; @@ -203,14 +203,14 @@ class TrustAndBalance_test : public beast::unit_test::suite } void - testWithTransferFee (bool subscribe, bool with_rate, std::initializer_list fs) + testWithTransferFee (bool subscribe, bool with_rate, FeatureBitset features) { testcase(std::string("Direct Payment: ") + (with_rate ? "With " : "Without ") + " Xfer Fee, " + (subscribe ? "With " : "Without ") + " Subscribe"); using namespace test::jtx; - Env env {*this, with_only_features(fs)}; + Env env {*this, features}; auto wsc = test::makeWSClient(env.app().config()); Account gw {"gateway"}; Account alice {"alice"}; @@ -283,12 +283,12 @@ class TrustAndBalance_test : public beast::unit_test::suite } void - testWithPath (std::initializer_list fs) + testWithPath (FeatureBitset features) { testcase ("Payments With Paths and Fees"); using namespace test::jtx; - Env env {*this, with_only_features(fs)}; + Env env {*this, features}; Account gw {"gateway"}; Account alice {"alice"}; Account bob {"bob"}; @@ -331,12 +331,12 @@ class TrustAndBalance_test : public beast::unit_test::suite } void - testIndirect (std::initializer_list fs) + testIndirect (FeatureBitset features) { testcase ("Indirect Payment"); using namespace test::jtx; - Env env {*this, with_only_features(fs)}; + Env env {*this, features}; Account gw {"gateway"}; Account alice {"alice"}; Account bob {"bob"}; @@ -372,13 +372,13 @@ class TrustAndBalance_test : public beast::unit_test::suite } void - testIndirectMultiPath (bool with_rate, std::initializer_list fs) + testIndirectMultiPath (bool with_rate, FeatureBitset features) { testcase (std::string("Indirect Payment, Multi Path, ") + (with_rate ? "With " : "Without ") + " Xfer Fee, "); using namespace test::jtx; - Env env {*this, with_only_features(fs)}; + Env env {*this, features}; Account gw {"gateway"}; Account amazon {"amazon"}; Account alice {"alice"}; @@ -438,12 +438,12 @@ class TrustAndBalance_test : public beast::unit_test::suite } void - testInvoiceID (std::initializer_list fs) + testInvoiceID (FeatureBitset features) { testcase ("Set Invoice ID on Payment"); using namespace test::jtx; - Env env {*this, with_only_features(fs)}; + Env env {*this, features}; Account alice {"alice"}; auto wsc = test::makeWSClient(env.app().config()); @@ -493,23 +493,28 @@ public: testTrustNonexistent (); testCreditLimit (); - auto testWithFeatures = [this](std::initializer_list fs) { - testPayNonexistent(fs); - testDirectRipple(fs); - testWithTransferFee(false, false, fs); - testWithTransferFee(false, true, fs); - testWithTransferFee(true, false, fs); - testWithTransferFee(true, true, fs); - testWithPath(fs); - testIndirect(fs); - testIndirectMultiPath(true, fs); - testIndirectMultiPath(false, fs); - testInvoiceID(fs); + auto testWithFeatures = [this](FeatureBitset features) { + testPayNonexistent(features); + testDirectRipple(features); + testWithTransferFee(false, false, features); + testWithTransferFee(false, true, features); + testWithTransferFee(true, false, features); + testWithTransferFee(true, true, features); + testWithPath(features); + testIndirect(features); + testIndirectMultiPath(true, features); + testIndirectMultiPath(false, features); + testInvoiceID(features); }; - testWithFeatures({}); - testWithFeatures({featureFlow}); - testWithFeatures({featureFlow, fix1373}); - testWithFeatures({featureFlow, fix1373, featureFlowCross}); + + using namespace test::jtx; + testWithFeatures( + supported_features_except (featureFlow, fix1373, featureFlowCross)); + testWithFeatures( + supported_features_except ( fix1373, featureFlowCross)); + testWithFeatures( + supported_features_except ( featureFlowCross)); + testWithFeatures(supported_amendments()); } }; diff --git a/src/test/app/TxQ_test.cpp b/src/test/app/TxQ_test.cpp index f1dd4c5a7e..f44bcf4def 100644 --- a/src/test/app/TxQ_test.cpp +++ b/src/test/app/TxQ_test.cpp @@ -162,8 +162,8 @@ public: using namespace jtx; using namespace std::chrono; - Env env(*this, makeConfig({ {"minimum_txn_in_ledger_standalone", "3"} }), - with_features(featureFeeEscalation, fix1513)); + Env env(*this, + makeConfig({ {"minimum_txn_in_ledger_standalone", "3"} })); auto& txq = env.app().getTxQ(); auto alice = Account("alice"); @@ -349,8 +349,8 @@ public: using namespace jtx; using namespace std::chrono; - Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }), - with_features(featureFeeEscalation, fix1513)); + Env env(*this, + makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } })); auto alice = Account("alice"); auto bob = Account("bob"); @@ -405,8 +405,8 @@ public: using namespace jtx; using namespace std::chrono; - Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }), - with_features(featureFeeEscalation, fix1513)); + Env env(*this, + makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } })); auto alice = Account("alice"); auto bob = Account("bob"); @@ -513,8 +513,8 @@ public: using namespace jtx; using namespace std::chrono; - Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }), - with_features(featureFeeEscalation, fix1513)); + Env env(*this, + makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } })); auto alice = Account("alice"); auto bob = Account("bob"); @@ -620,7 +620,7 @@ public: { using namespace jtx; - Env env(*this, makeConfig(), with_features(featureFeeEscalation, fix1513)); + Env env(*this, makeConfig()); auto alice = Account("alice"); auto bob = Account("bob"); @@ -644,8 +644,8 @@ public: { using namespace jtx; - Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }), - with_features(featureFeeEscalation, fix1513)); + Env env(*this, + makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } })); auto alice = Account("alice"); auto bob = Account("bob"); @@ -701,8 +701,7 @@ public: Env env(*this, makeConfig( {{"minimum_txn_in_ledger_standalone", "3"}}, - {{"account_reserve", "200"}, {"owner_reserve", "50"}}), - with_features(featureFeeEscalation, fix1513)); + {{"account_reserve", "200"}, {"owner_reserve", "50"}})); auto alice = Account("alice"); auto bob = Account("bob"); @@ -929,8 +928,8 @@ public: using namespace jtx; using namespace std::chrono; - Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "4" } }), - with_features(featureFeeEscalation, fix1513)); + Env env(*this, + makeConfig({ { "minimum_txn_in_ledger_standalone", "4" } })); auto alice = Account("alice"); auto bob = Account("bob"); @@ -1088,8 +1087,8 @@ public: { using namespace jtx; - Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "1" } }), - with_features(featureFeeEscalation, fix1513)); + Env env(*this, + makeConfig({ { "minimum_txn_in_ledger_standalone", "1" } })); auto alice = Account("alice"); @@ -1131,8 +1130,7 @@ public: Env env(*this, makeConfig( { {"minimum_txn_in_ledger_standalone", "2"}, {"target_txn_in_ledger", "4"}, - {"maximum_txn_in_ledger", "5"} }), - with_features(featureFeeEscalation, fix1513)); + {"maximum_txn_in_ledger", "5"} })); auto alice = Account("alice"); auto queued = ter(terQUEUED); @@ -1161,8 +1159,7 @@ public: *this, makeConfig( {{"minimum_txn_in_ledger_standalone", "3"}}, - {{"account_reserve", "200"}, {"owner_reserve", "50"}}), - with_features(featureFeeEscalation, fix1513)); + {{"account_reserve", "200"}, {"owner_reserve", "50"}})); auto alice = Account("alice"); auto bob = Account("bob"); @@ -1251,8 +1248,7 @@ public: using namespace jtx; Env env(*this, - makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }), - with_features(featureFeeEscalation, featureMultiSign, fix1513)); + makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } })); auto alice = Account("alice"); auto bob = Account("bob"); @@ -1316,8 +1312,7 @@ public: using namespace jtx; Env env(*this, - makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }), - with_features(featureFeeEscalation, featureTickets, fix1513)); + makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } })); auto alice = Account("alice"); auto charlie = Account("charlie"); @@ -1562,7 +1557,7 @@ public: { using namespace jtx; using namespace std::chrono; - Env env(*this, with_only_features(featureTickets)); + Env env(*this, supported_features_plus (featureTickets)); auto const alice = Account("alice"); env.memoize(alice); env.memoize("bob"); @@ -1630,7 +1625,7 @@ public: { using namespace jtx; { - Env env(*this, with_features(featureFeeEscalation, fix1513)); + Env env(*this); auto fee = env.rpc("fee"); @@ -1718,8 +1713,7 @@ public: using namespace jtx; Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "1" }, - {"ledgers_in_queue", "10"}, {"maximum_txn_per_account", "20"} }), - with_features(featureFeeEscalation, fix1513)); + {"ledgers_in_queue", "10"}, {"maximum_txn_per_account", "20"} })); // Alice will recreate the scenario. Bob will block. auto const alice = Account("alice"); @@ -1793,8 +1787,8 @@ public: { testcase("Autofilled sequence should account for TxQ"); using namespace jtx; - Env env(*this, makeConfig({ {"minimum_txn_in_ledger_standalone", "6"} }), - with_features(featureFeeEscalation, fix1513)); + Env env(*this, + makeConfig({ {"minimum_txn_in_ledger_standalone", "6"} })); Env_ss envs(env); auto const& txQ = env.app().getTxQ(); @@ -1923,8 +1917,8 @@ public: void testAccountInfo() { using namespace jtx; - Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }), - with_features(featureFeeEscalation, fix1513)); + Env env(*this, + makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } })); Env_ss envs(env); Account const alice{ "alice" }; @@ -2193,8 +2187,8 @@ public: void testServerInfo() { using namespace jtx; - Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }), - with_features(featureFeeEscalation, fix1513)); + Env env(*this, + makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } })); Env_ss envs(env); Account const alice{ "alice" }; @@ -2416,8 +2410,8 @@ public: { using namespace jtx; - Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }), - with_features(featureFeeEscalation, fix1513)); + Env env(*this, + makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } })); Json::Value stream; stream[jss::streams] = Json::arrayValue; @@ -2585,8 +2579,7 @@ public: using namespace jtx; Env env(*this, - makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }), - with_features(featureFeeEscalation, fix1513)); + makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } })); auto alice = Account("alice"); auto bob = Account("bob"); diff --git a/src/test/jtx/Env.h b/src/test/jtx/Env.h index 757e1c7463..8b96276822 100644 --- a/src/test/jtx/Env.h +++ b/src/test/jtx/Env.h @@ -151,6 +151,37 @@ supported_features_except (uint256 const& key, Args const&... args) std::array{{key, args...}}); } +/** + * @brief create collection of features to pass to Env ctor + * + * The resulting collection will contain *all supported amendments* plus + * the features passed as arguments. + * + * @param keys features to include in the resulting collection + */ +template +FeatureBitset +supported_features_plus (Col const& keys) +{ + return supported_amendments() | makeFeatureBitset(keys); +} + +/** + * + * @brief create collection of features to pass to Env ctor + * The resulting collection will contain *all supported amendments* plus + * the features passed as arguments. + * + * @param key+args features to include in the resulting collection + */ +template +FeatureBitset +supported_features_plus (uint256 const& key, Args const&... args) +{ + return supported_features_plus( + std::array{{key, args...}}); +} + class SuiteSink : public beast::Journal::Sink { std::string partition_; diff --git a/src/test/jtx/Env_test.cpp b/src/test/jtx/Env_test.cpp index 9408b2c2d4..10fd676057 100644 --- a/src/test/jtx/Env_test.cpp +++ b/src/test/jtx/Env_test.cpp @@ -355,7 +355,7 @@ public: { using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); env.fund(XRP(10000), "alice"); env(signers("alice", 1, { { "alice", 1 }, { "bob", 2 } }), ter(temBAD_SIGNER)); @@ -384,7 +384,7 @@ public: ticket::create("alice", 60, "bob"); { - Env env(*this, with_only_features(featureTickets)); + Env env(*this, supported_features_plus (featureTickets)); env.fund(XRP(10000), "alice"); env(noop("alice"), require(owners("alice", 0), tickets("alice", 0))); env(ticket::create("alice"), require(owners("alice", 1), tickets("alice", 1))); diff --git a/src/test/ledger/BookDirs_test.cpp b/src/test/ledger/BookDirs_test.cpp index 216322c252..7dd0df24c4 100644 --- a/src/test/ledger/BookDirs_test.cpp +++ b/src/test/ledger/BookDirs_test.cpp @@ -25,10 +25,10 @@ namespace test { struct BookDirs_test : public beast::unit_test::suite { - void test_bookdir(std::initializer_list fs) + void test_bookdir(FeatureBitset features) { using namespace jtx; - Env env(*this, with_only_features(fs)); + Env env(*this, features); auto gw = Account("gw"); auto USD = gw["USD"]; env.fund(XRP(1000000), "alice", "bob", "gw"); @@ -94,9 +94,12 @@ struct BookDirs_test : public beast::unit_test::suite void run() override { - test_bookdir({}); - test_bookdir({featureFlow, fix1373}); - test_bookdir({featureFlow, fix1373, featureFlowCross}); + using namespace jtx; + test_bookdir( + supported_features_except (featureFlow, fix1373, featureFlowCross)); + test_bookdir( + supported_features_except ( featureFlowCross)); + test_bookdir(supported_amendments ()); } }; diff --git a/src/test/ledger/Directory_test.cpp b/src/test/ledger/Directory_test.cpp index fe5b5ea13f..7c8a0221ac 100644 --- a/src/test/ledger/Directory_test.cpp +++ b/src/test/ledger/Directory_test.cpp @@ -116,7 +116,7 @@ struct Directory_test : public beast::unit_test::suite { testcase ("Directory Ordering (with 'SortedDirectories' amendment)"); - Env env(*this, with_only_features(featureSortedDirectories)); + Env env(*this); env.fund(XRP(10000000), alice, gw); for (std::size_t i = 1; i <= 400; ++i) @@ -184,8 +184,7 @@ struct Directory_test : public beast::unit_test::suite beast::xor_shift_engine eng; - Env env(*this, - with_only_features(featureSortedDirectories, featureMultiSign)); + Env env(*this); env.fund(XRP(1000000), alice, charlie, gw); env.close(); @@ -289,7 +288,7 @@ struct Directory_test : public beast::unit_test::suite testcase("RIPD-1353 Empty Offer Directories"); using namespace jtx; - Env env(*this, with_only_features(featureSortedDirectories)); + Env env(*this); auto const gw = Account{"gateway"}; auto const alice = Account{"alice"}; @@ -349,7 +348,7 @@ struct Directory_test : public beast::unit_test::suite testcase("Empty Chain on Delete"); using namespace jtx; - Env env(*this, with_only_features(featureSortedDirectories)); + Env env(*this); auto const gw = Account{"gateway"}; auto const alice = Account{"alice"}; diff --git a/src/test/ledger/PaymentSandbox_test.cpp b/src/test/ledger/PaymentSandbox_test.cpp index 49dc515e81..84614e7cb1 100644 --- a/src/test/ledger/PaymentSandbox_test.cpp +++ b/src/test/ledger/PaymentSandbox_test.cpp @@ -55,12 +55,12 @@ class PaymentSandbox_test : public beast::unit_test::suite 2) New code: Path is dry because sender does not have any GW1 to spend until the end of the transaction. */ - void testSelfFunding (std::initializer_list fs) + void testSelfFunding (FeatureBitset features) { testcase ("selfFunding"); using namespace jtx; - Env env (*this, with_only_features(fs)); + Env env (*this, features); Account const gw1 ("gw1"); Account const gw2 ("gw2"); Account const snd ("snd"); @@ -96,12 +96,12 @@ class PaymentSandbox_test : public beast::unit_test::suite env.require (balance ("rcv", USD_gw2 (2))); } - void testSubtractCredits (std::initializer_list fs) + void testSubtractCredits (FeatureBitset features) { testcase ("subtractCredits"); using namespace jtx; - Env env (*this, with_only_features(fs)); + Env env (*this, features); Account const gw1 ("gw1"); Account const gw2 ("gw2"); Account const alice ("alice"); @@ -256,7 +256,7 @@ class PaymentSandbox_test : public beast::unit_test::suite } } - void testTinyBalance (std::initializer_list fs) + void testTinyBalance (FeatureBitset features) { testcase ("Tiny balance"); @@ -266,7 +266,7 @@ class PaymentSandbox_test : public beast::unit_test::suite using namespace jtx; - Env env (*this, with_only_features(fs)); + Env env (*this, features); Account const gw ("gw"); Account const alice ("alice"); @@ -293,7 +293,7 @@ class PaymentSandbox_test : public beast::unit_test::suite } } - void testReserve(std::initializer_list fs) + void testReserve(FeatureBitset features) { testcase ("Reserve"); using namespace jtx; @@ -312,7 +312,7 @@ class PaymentSandbox_test : public beast::unit_test::suite return env.current ()->fees ().accountReserve (count); }; - Env env (*this, with_only_features(fs)); + Env env (*this, features); Account const alice ("alice"); env.fund (reserve(env, 1), alice); @@ -333,14 +333,14 @@ class PaymentSandbox_test : public beast::unit_test::suite } } - void testBalanceHook(std::initializer_list fs) + void testBalanceHook(FeatureBitset features) { // Make sure the Issue::Account returned by PAymentSandbox::balanceHook // is correct. testcase ("balanceHook"); using namespace jtx; - Env env (*this, with_only_features(fs)); + Env env (*this, features); Account const gw ("gw"); auto const USD = gw["USD"]; @@ -370,16 +370,19 @@ class PaymentSandbox_test : public beast::unit_test::suite public: void run () { - auto testAll = [this](std::initializer_list fs) { - testSelfFunding(fs); - testSubtractCredits(fs); - testTinyBalance(fs); - testReserve(fs); - testBalanceHook(fs); + auto testAll = [this](FeatureBitset features) { + testSelfFunding(features); + testSubtractCredits(features); + testTinyBalance(features); + testReserve(features); + testBalanceHook(features); }; - testAll({}); - testAll({featureFlow, fix1373}); - testAll({featureFlow, fix1373, featureFlowCross}); + using namespace jtx; + testAll( + supported_features_except (featureFlow, fix1373, featureFlowCross)); + testAll( + supported_features_except ( featureFlowCross)); + testAll(supported_amendments()); } }; diff --git a/src/test/rpc/AccountInfo_test.cpp b/src/test/rpc/AccountInfo_test.cpp index c1d83d94ca..93a59ab549 100644 --- a/src/test/rpc/AccountInfo_test.cpp +++ b/src/test/rpc/AccountInfo_test.cpp @@ -59,7 +59,7 @@ public: void testSignerLists() { using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); Account const alice {"alice"}; env.fund(XRP(1000), alice); @@ -165,7 +165,7 @@ public: void testSignerListsV2() { using namespace jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); Account const alice {"alice"}; env.fund(XRP(1000), alice); diff --git a/src/test/rpc/AccountSet_test.cpp b/src/test/rpc/AccountSet_test.cpp index 88312b767f..5728e08cf0 100644 --- a/src/test/rpc/AccountSet_test.cpp +++ b/src/test/rpc/AccountSet_test.cpp @@ -371,7 +371,7 @@ public: void testRequireAuthWithDir() { using namespace test::jtx; - Env env(*this, with_only_features(featureMultiSign)); + Env env(*this); Account const alice ("alice"); Account const bob ("bob"); diff --git a/src/test/rpc/Feature_test.cpp b/src/test/rpc/Feature_test.cpp index 61d4939a03..9df5c58151 100644 --- a/src/test/rpc/Feature_test.cpp +++ b/src/test/rpc/Feature_test.cpp @@ -117,10 +117,6 @@ class Feature_test : public beast::unit_test::suite using namespace test::jtx; Env env {*this, with_only_features(featureEscrow, featureCryptoConditions)}; - // The amendment table has to be modified - // since that is what feature RPC actually checks - env.app().getAmendmentTable().enable(featureEscrow); - env.app().getAmendmentTable().enable(featureCryptoConditions); auto jrr = env.rpc("feature") [jss::result]; if(! BEAST_EXPECT(jrr.isMember(jss::features))) @@ -221,9 +217,6 @@ class Feature_test : public beast::unit_test::suite using namespace test::jtx; Env env {*this, with_only_features(featureCryptoConditions)}; - // The amendment table has to be modified - // since that is what feature RPC actually checks - env.app().getAmendmentTable().enable(featureCryptoConditions); auto jrr = env.rpc("feature", "CryptoConditions") [jss::result]; if(! BEAST_EXPECTS(jrr[jss::status] == jss::success, "status")) diff --git a/src/test/rpc/GatewayBalances_test.cpp b/src/test/rpc/GatewayBalances_test.cpp index 500e700d4f..25bbeda642 100644 --- a/src/test/rpc/GatewayBalances_test.cpp +++ b/src/test/rpc/GatewayBalances_test.cpp @@ -30,11 +30,11 @@ class GatewayBalances_test : public beast::unit_test::suite public: void - testGWB(std::initializer_list fs) + testGWB(FeatureBitset features) { using namespace std::chrono_literals; using namespace jtx; - Env env(*this, with_only_features(fs)); + Env env(*this, features); // Gateway account and assets Account const alice {"alice"}; @@ -153,9 +153,12 @@ public: void run() override { - testGWB({}); - testGWB({featureFlow, fix1373}); - testGWB({featureFlow, fix1373, featureFlowCross}); + using namespace jtx; + testGWB( + supported_features_except (featureFlow, fix1373, featureFlowCross)); + testGWB( + supported_features_except ( featureFlowCross)); + testGWB(supported_amendments()); } }; diff --git a/src/test/rpc/JSONRPC_test.cpp b/src/test/rpc/JSONRPC_test.cpp index 807a38fcf8..f34954eade 100644 --- a/src/test/rpc/JSONRPC_test.cpp +++ b/src/test/rpc/JSONRPC_test.cpp @@ -1941,8 +1941,7 @@ public: cfg->section("transaction_queue") .set("minimum_txn_in_ledger_standalone", "3"); return cfg; - }), - with_features(featureFeeEscalation, fix1513)}; + })}; LoadFeeTrack const& feeTrack = env.app().getFeeTrack(); { @@ -2254,8 +2253,7 @@ public: // "b" (not in the ledger) is rDg53Haik2475DJx8bjMDSDPj4VX7htaMd. // "c" (phantom signer) is rPcNzota6B8YBokhYtcTNqQVCngtbnWfux. - test::jtx::Env env(*this, - test::jtx::with_only_features(featureMultiSign)); + test::jtx::Env env(*this); env.fund(test::jtx::XRP(100000), a, ed, g); env.close(); diff --git a/src/test/rpc/LedgerData_test.cpp b/src/test/rpc/LedgerData_test.cpp index 2191a642a2..1aac83ace7 100644 --- a/src/test/rpc/LedgerData_test.cpp +++ b/src/test/rpc/LedgerData_test.cpp @@ -268,8 +268,8 @@ public: using namespace test::jtx; using namespace std::chrono; Env env { *this, envconfig(validator, ""), - with_only_features(featureMultiSign, featureTickets, - featureEscrow, featurePayChan) }; + supported_features_plus(featureTickets) }; + Account const gw { "gateway" }; auto const USD = gw["USD"]; env.fund(XRP(100000), gw); diff --git a/src/test/rpc/LedgerRPC_test.cpp b/src/test/rpc/LedgerRPC_test.cpp index a1a5908dc7..4326829bc7 100644 --- a/src/test/rpc/LedgerRPC_test.cpp +++ b/src/test/rpc/LedgerRPC_test.cpp @@ -476,8 +476,7 @@ class LedgerRPC_test : public beast::unit_test::suite cfg->section("transaction_queue") .set("minimum_txn_in_ledger_standalone", "3"); return cfg; - }), - with_features(featureFeeEscalation, fix1513)}; + })}; Json::Value jv; jv[jss::ledger_index] = "current"; diff --git a/src/test/rpc/NoRipple_test.cpp b/src/test/rpc/NoRipple_test.cpp index 02bdc1a611..81dd281abe 100644 --- a/src/test/rpc/NoRipple_test.cpp +++ b/src/test/rpc/NoRipple_test.cpp @@ -67,12 +67,12 @@ public: } } - void testNegativeBalance(std::initializer_list fs) + void testNegativeBalance(FeatureBitset features) { testcase("Set noripple on a line with negative balance"); using namespace jtx; - Env env(*this, with_only_features(fs)); + Env env(*this, features); auto const gw = Account("gateway"); auto const alice = Account("alice"); @@ -113,12 +113,12 @@ public: BEAST_EXPECT(!lines[0u].isMember(jss::no_ripple)); } - void testPairwise(std::initializer_list fs) + void testPairwise(FeatureBitset features) { testcase("pairwise NoRipple"); using namespace jtx; - Env env(*this, with_only_features(fs)); + Env env(*this, features); auto const alice = Account("alice"); auto const bob = Account("bob"); @@ -150,12 +150,12 @@ public: env(pay(alice, carol, bob["USD"](50)), ter(tecPATH_DRY)); } - void testDefaultRipple(std::initializer_list fs) + void testDefaultRipple(FeatureBitset features) { testcase("Set default ripple on an account and check new trustlines"); using namespace jtx; - Env env(*this, with_only_features(fs)); + Env env(*this, features); auto const gw = Account("gateway"); auto const alice = Account("alice"); @@ -212,15 +212,19 @@ public: { testSetAndClear(); - auto withFeatsTests = [this](std::initializer_list fs) { - testNegativeBalance(fs); - testPairwise(fs); - testDefaultRipple(fs); + auto withFeatsTests = [this](FeatureBitset features) { + testNegativeBalance(features); + testPairwise(features); + testDefaultRipple(features); }; - withFeatsTests({}); - withFeatsTests({featureFlow}); - withFeatsTests({featureFlow, fix1373}); - withFeatsTests({featureFlow, fix1373, featureFlowCross}); + using namespace jtx; + withFeatsTests( + supported_features_except (featureFlow, fix1373, featureFlowCross)); + withFeatsTests( + supported_features_except ( fix1373, featureFlowCross)); + withFeatsTests( + supported_features_except ( featureFlowCross)); + withFeatsTests(supported_amendments()); } };