diff --git a/src/ripple/app/main/Amendments.cpp b/src/ripple/app/main/Amendments.cpp index e42add8d05..7a3d9653c6 100644 --- a/src/ripple/app/main/Amendments.cpp +++ b/src/ripple/app/main/Amendments.cpp @@ -44,7 +44,8 @@ supportedAmendments () { "C1B8D934087225F509BEB5A8EC24447854713EE447D277F69545ABFA0E0FD490 Tickets" }, { "6781F8368C4771B83E8B821D88F580202BCB4228075297B19E4FDC5233F1EFDC TrustSetAuth" }, { "42426C4D4F1009EE67080A9B7965B44656D7714D104A72F9B4369F97ABF044EE FeeEscalation" }, - { "9178256A980A86CF3D70D0260A7DA6402AAFE43632FDBCB88037978404188871 OwnerPaysFee" }, + // The following will be supported in a future release (and uncommented at that time) + //{ "9178256A980A86CF3D70D0260A7DA6402AAFE43632FDBCB88037978404188871 OwnerPaysFee" }, { "08DE7D96082187F6E6578530258C77FAABABE4C20474BDB82F04B021F1A68647 PayChan" }, { "740352F2412A9909880C23A559FCECEDA3BE2126FED62FC7660D628A06927F11 Flow" }, { "1562511F573A19AE9BD103B5D6B9E01B3B46805AEC5D3C4805C902B514399146 CryptoConditions" }, diff --git a/src/ripple/core/impl/Config.cpp b/src/ripple/core/impl/Config.cpp index 24cd49857c..43599a88e0 100644 --- a/src/ripple/core/impl/Config.cpp +++ b/src/ripple/core/impl/Config.cpp @@ -534,7 +534,13 @@ void Config::loadFromString (std::string const& fileContents) { auto const part = section("features"); for(auto const& s : part.values()) - features.insert(feature(s)); + { + if (auto const f = getRegisteredFeature(s)) + features.insert(*f); + else + Throw( + "Unknown feature: " + s + " in config file."); + } } } diff --git a/src/ripple/protocol/Feature.h b/src/ripple/protocol/Feature.h index c783f1f995..74206cf310 100644 --- a/src/ripple/protocol/Feature.h +++ b/src/ripple/protocol/Feature.h @@ -21,18 +21,124 @@ #define RIPPLE_PROTOCOL_FEATURE_H_INCLUDED #include +#include +#include +#include +#include #include +/** + * @page Feature How to add new features + * + * Steps required to add new features to the code: + * + * 1) add the new feature name to the featureNames array below + * 2) add a uint256 declaration for the feature to the bottom of this file + * 3) add a uint256 definition for the feature to the corresponding source + * file (Feature.cpp) + * 4) if the feature is going to be supported in the near future, add its + * sha512half value and name (matching exactly the featureName here) to the + * supportedAmendments in Amendments.cpp. + * + */ + namespace ripple { -/** Convert feature description to feature id. */ -/** @{ */ -uint256 -feature (std::string const& name); +namespace detail { + +class FeatureCollections +{ + static constexpr char const* const featureNames[] = + {"MultiSign", + "Tickets", + "TrustSetAuth", + "FeeEscalation", + "OwnerPaysFee", + "CompareFlowV1V2", + "SHAMapV2", + "PayChan", + "Flow", + "CompareTakerFlowCross", + "FlowCross", + "CryptoConditions", + "TickSize", + "fix1368", + "Escrow", + "CryptoConditionsSuite", + "fix1373", + "EnforceInvariants"}; + + std::vector features; + boost::container::flat_map featureToIndex; + boost::container::flat_map nameToFeature; + +public: + FeatureCollections(); + + static constexpr std::size_t numFeatures() + { + return sizeof (featureNames) / sizeof (featureNames[0]); + } + + boost::optional + getRegisteredFeature(std::string const& name) const; + + std::size_t + featureToBitsetIndex(uint256 const& f) const; + + uint256 const& + bitsetIndexToFeature(size_t i) const; +}; + +} // detail + +boost::optional +getRegisteredFeature (std::string const& name); + +using FeatureBitset = std::bitset; + +size_t +featureToBitsetIndex(uint256 const& f); uint256 -feature (const char* name); -/** @} */ +bitsetIndexToFeature(size_t i); + +template +void +foreachFeature(FeatureBitset bs, F&& f) +{ + for (size_t i = 0; i < bs.size(); ++i) + if (bs[i]) + f(bitsetIndexToFeature(i)); +} + +template +FeatureBitset +makeFeatureBitset(Col&& fs) +{ + FeatureBitset result; + for (auto const& f : fs) + result.set(featureToBitsetIndex(f)); + return result; +} + +template +FeatureBitset +addFeatures(FeatureBitset bs, Col&& fs) +{ + for (auto const& f : fs) + bs.set(featureToBitsetIndex(f)); + return bs; +} + +template +FeatureBitset +removeFeatures(FeatureBitset bs, Col&& fs) +{ + for (auto const& f : fs) + bs.reset(featureToBitsetIndex(f)); + return bs; +} extern uint256 const featureMultiSign; extern uint256 const featureTickets; diff --git a/src/ripple/protocol/impl/Feature.cpp b/src/ripple/protocol/impl/Feature.cpp index a2a2959da4..db21c32534 100644 --- a/src/ripple/protocol/impl/Feature.cpp +++ b/src/ripple/protocol/impl/Feature.cpp @@ -18,50 +18,100 @@ //============================================================================== #include -#include #include +#include +#include + #include namespace ripple { -static -uint256 -feature (char const* s, std::size_t n) +//------------------------------------------------------------------------------ + +constexpr char const* const detail::FeatureCollections::featureNames[]; + +detail::FeatureCollections::FeatureCollections() { - sha512_half_hasher h; - h(s, n); - return static_cast(h); + features.reserve(numFeatures()); + featureToIndex.reserve(numFeatures()); + nameToFeature.reserve(numFeatures()); + + for (std::size_t i = 0; i < numFeatures(); ++i) + { + auto const name = featureNames[i]; + sha512_half_hasher h; + h (name, std::strlen (name)); + auto const f = static_cast(h); + + features.push_back(f); + featureToIndex[f] = i; + nameToFeature[name] = f; + } } -uint256 -feature (std::string const& name) +boost::optional +detail::FeatureCollections::getRegisteredFeature(std::string const& name) const { - return feature(name.c_str(), name.size()); + auto const i = nameToFeature.find(name); + if (i == nameToFeature.end()) + return boost::none; + return i->second; } -uint256 -feature (const char* name) +size_t +detail::FeatureCollections::featureToBitsetIndex(uint256 const& f) const { - return feature(name, std::strlen(name)); + auto const i = featureToIndex.find(f); + if (i == featureToIndex.end()) + LogicError("Invalid Feature ID"); + return i->second; } -uint256 const featureMultiSign = feature("MultiSign"); -uint256 const featureTickets = feature("Tickets"); -uint256 const featureTrustSetAuth = feature("TrustSetAuth"); -uint256 const featureFeeEscalation = feature("FeeEscalation"); -uint256 const featureOwnerPaysFee = feature("OwnerPaysFee"); -uint256 const featureCompareFlowV1V2 = feature("CompareFlowV1V2"); -uint256 const featureSHAMapV2 = feature("SHAMapV2"); -uint256 const featurePayChan = feature("PayChan"); -uint256 const featureFlow = feature("Flow"); -uint256 const featureCompareTakerFlowCross = feature("CompareTakerFlowCross"); -uint256 const featureFlowCross = feature("FlowCross"); -uint256 const featureCryptoConditions = feature("CryptoConditions"); -uint256 const featureTickSize = feature("TickSize"); -uint256 const fix1368 = feature("fix1368"); -uint256 const featureEscrow = feature("Escrow"); -uint256 const featureCryptoConditionsSuite = feature("CryptoConditionsSuite"); -uint256 const fix1373 = feature("fix1373"); -uint256 const featureEnforceInvariants = feature("EnforceInvariants"); +uint256 const& +detail::FeatureCollections::bitsetIndexToFeature(size_t i) const +{ + if (i >= features.size()) + LogicError("Invalid FeatureBitset index"); + return features[i]; +} + +static detail::FeatureCollections const featureCollections; + +//------------------------------------------------------------------------------ + +boost::optional +getRegisteredFeature (std::string const& name) +{ + return featureCollections.getRegisteredFeature(name); +} + +size_t featureToBitsetIndex(uint256 const& f) +{ + return featureCollections.featureToBitsetIndex(f); +} + +uint256 bitsetIndexToFeature(size_t i) +{ + return featureCollections.bitsetIndexToFeature(i); +} + +uint256 const featureMultiSign = *getRegisteredFeature("MultiSign"); +uint256 const featureTickets = *getRegisteredFeature("Tickets"); +uint256 const featureTrustSetAuth = *getRegisteredFeature("TrustSetAuth"); +uint256 const featureFeeEscalation = *getRegisteredFeature("FeeEscalation"); +uint256 const featureOwnerPaysFee = *getRegisteredFeature("OwnerPaysFee"); +uint256 const featureCompareFlowV1V2 = *getRegisteredFeature("CompareFlowV1V2"); +uint256 const featureSHAMapV2 = *getRegisteredFeature("SHAMapV2"); +uint256 const featurePayChan = *getRegisteredFeature("PayChan"); +uint256 const featureFlow = *getRegisteredFeature("Flow"); +uint256 const featureCompareTakerFlowCross = *getRegisteredFeature("CompareTakerFlowCross"); +uint256 const featureFlowCross = *getRegisteredFeature("FlowCross"); +uint256 const featureCryptoConditions = *getRegisteredFeature("CryptoConditions"); +uint256 const featureTickSize = *getRegisteredFeature("TickSize"); +uint256 const fix1368 = *getRegisteredFeature("fix1368"); +uint256 const featureEscrow = *getRegisteredFeature("Escrow"); +uint256 const featureCryptoConditionsSuite = *getRegisteredFeature("CryptoConditionsSuite"); +uint256 const fix1373 = *getRegisteredFeature("fix1373"); +uint256 const featureEnforceInvariants = *getRegisteredFeature("EnforceInvariants"); } // ripple diff --git a/src/test/app/AmendmentTable_test.cpp b/src/test/app/AmendmentTable_test.cpp index b2301cd338..d61a7fa633 100644 --- a/src/test/app/AmendmentTable_test.cpp +++ b/src/test/app/AmendmentTable_test.cpp @@ -739,8 +739,10 @@ public: testSupportedAmendments () { for (auto const& amend : detail::supportedAmendments ()) - BEAST_EXPECT(amend.substr (0, 64) == - to_string (feature (amend.substr (65)))); + { + auto const f = getRegisteredFeature(amend.substr (65)); + BEAST_EXPECT(f && amend.substr (0, 64) == to_string (*f)); + } } void run () diff --git a/src/test/app/CrossingLimits_test.cpp b/src/test/app/CrossingLimits_test.cpp index a79cd9f15b..e0085ffff0 100644 --- a/src/test/app/CrossingLimits_test.cpp +++ b/src/test/app/CrossingLimits_test.cpp @@ -47,7 +47,7 @@ public: testStepLimit(std::initializer_list fs) { using namespace jtx; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); auto const xrpMax = XRP(100000000000); auto const gw = Account("gateway"); auto const USD = gw["USD"]; @@ -81,7 +81,7 @@ public: testCrossingLimit(std::initializer_list fs) { using namespace jtx; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); auto const xrpMax = XRP(100000000000); auto const gw = Account("gateway"); auto const USD = gw["USD"]; @@ -110,7 +110,7 @@ public: testStepAndCrossingLimit(std::initializer_list fs) { using namespace jtx; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); auto const xrpMax = XRP(100000000000); auto const gw = Account("gateway"); auto const USD = gw["USD"]; diff --git a/src/test/app/DeliverMin_test.cpp b/src/test/app/DeliverMin_test.cpp index 11e3531165..29ca1225ca 100644 --- a/src/test/app/DeliverMin_test.cpp +++ b/src/test/app/DeliverMin_test.cpp @@ -38,7 +38,7 @@ public: auto const USD = gw["USD"]; { - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); 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, features(fs)); + Env env(*this, with_features(fs)); 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, features(fs)); + Env env(*this, with_features(fs)); 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, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), "alice", "bob", "carol", "dan", gw); env.trust(USD(1000), "bob", "carol", "dan"); env(pay(gw, "bob", USD(100))); diff --git a/src/test/app/Discrepancy_test.cpp b/src/test/app/Discrepancy_test.cpp index ee1d7d429e..54927dfc0f 100644 --- a/src/test/app/Discrepancy_test.cpp +++ b/src/test/app/Discrepancy_test.cpp @@ -41,7 +41,7 @@ class Discrepancy_test : public beast::unit_test::suite { testcase ("Discrepancy test : XRP Discrepancy"); using namespace test::jtx; - Env env {*this, features(fs)}; + Env env {*this, with_features(fs)}; Account A1 {"A1"}; Account A2 {"A2"}; diff --git a/src/test/app/Escrow_test.cpp b/src/test/app/Escrow_test.cpp index 2693baba68..adb861a771 100644 --- a/src/test/app/Escrow_test.cpp +++ b/src/test/app/Escrow_test.cpp @@ -193,7 +193,7 @@ struct Escrow_test : public beast::unit_test::suite using namespace std::chrono; { // Escrow not enabled - Env env(*this); + Env env(*this, no_features); env.fund(XRP(5000), "alice", "bob"); env(lockup("alice", "bob", XRP(1000), env.now() + 1s), ter(temDISABLED)); env(finish("bob", "alice", 1), ter(temDISABLED)); @@ -201,7 +201,7 @@ struct Escrow_test : public beast::unit_test::suite } { // Escrow enabled - Env env(*this, features(featureEscrow)); + Env env(*this, with_features(featureEscrow)); env.fund(XRP(5000), "alice", "bob"); env(lockup("alice", "bob", XRP(1000), env.now() + 1s)); env.close(); @@ -223,7 +223,7 @@ struct Escrow_test : public beast::unit_test::suite using namespace jtx; using namespace std::chrono; - Env env(*this, features(featureEscrow)); + Env env(*this, with_features(featureEscrow)); auto const alice = Account("alice"); env.fund(XRP(5000), alice, "bob"); @@ -247,7 +247,7 @@ struct Escrow_test : public beast::unit_test::suite using namespace jtx; using namespace std::chrono; - Env env(*this, features(featureEscrow)); + Env env(*this, with_features(featureEscrow)); env.fund(XRP(5000), "alice", "bob"); env.close(); @@ -350,7 +350,7 @@ struct Escrow_test : public beast::unit_test::suite using namespace std::chrono; { // Unconditional - Env env(*this, features(featureEscrow)); + Env env(*this, with_features(featureEscrow)); env.fund(XRP(5000), "alice", "bob"); auto const seq = env.seq("alice"); env(lockup("alice", "alice", XRP(1000), env.now() + 1s)); @@ -365,7 +365,7 @@ struct Escrow_test : public beast::unit_test::suite } { // Conditional - Env env(*this, features(featureEscrow)); + Env env(*this, with_features(featureEscrow)); env.fund(XRP(5000), "alice", "bob"); auto const seq = env.seq("alice"); env(lockup("alice", "alice", XRP(1000), makeSlice(cb2), env.now() + 1s)); @@ -398,7 +398,7 @@ struct Escrow_test : public beast::unit_test::suite { // Test cryptoconditions Env env(*this, - features(featureEscrow)); + with_features(featureEscrow)); auto T = [&env](NetClock::duration const& d) { return env.now() + d; }; env.fund(XRP(5000), "alice", "bob", "carol"); @@ -446,7 +446,7 @@ struct Escrow_test : public beast::unit_test::suite { // Test cancel when condition is present Env env(*this, - features(featureEscrow)); + with_features(featureEscrow)); auto T = [&env](NetClock::duration const& d) { return env.now() + d; }; env.fund(XRP(5000), "alice", "bob", "carol"); @@ -463,7 +463,7 @@ struct Escrow_test : public beast::unit_test::suite } { - Env env(*this, features(featureEscrow)); + Env env(*this, with_features(featureEscrow)); auto T = [&env](NetClock::duration const& d) { return env.now() + d; }; env.fund(XRP(5000), "alice", "bob", "carol"); @@ -483,7 +483,7 @@ struct Escrow_test : public beast::unit_test::suite } { // Test long & short conditions during creation - Env env(*this, features(featureEscrow)); + Env env(*this, with_features(featureEscrow)); auto T = [&env](NetClock::duration const& d) { return env.now() + d; }; env.fund(XRP(5000), "alice", "bob", "carol"); @@ -524,7 +524,7 @@ struct Escrow_test : public beast::unit_test::suite { // Test long and short conditions & fulfillments during finish Env env(*this, - features(featureEscrow)); + with_features(featureEscrow)); auto T = [&env](NetClock::duration const& d) { return env.now() + d; }; env.fund(XRP(5000), "alice", "bob", "carol"); @@ -609,7 +609,7 @@ struct Escrow_test : public beast::unit_test::suite { // Test empty condition during creation and // empty condition & fulfillment during finish - Env env(*this, features(featureEscrow)); + Env env(*this, with_features(featureEscrow)); auto T = [&env](NetClock::duration const& d) { return env.now() + d; }; env.fund(XRP(5000), "alice", "bob", "carol"); @@ -649,7 +649,7 @@ struct Escrow_test : public beast::unit_test::suite { // Test a condition other than PreimageSha256, which // would require a separate amendment - Env env(*this, features(featureEscrow)); + Env env(*this, with_features(featureEscrow)); auto T = [&env](NetClock::duration const& d) { return env.now() + d; }; env.fund(XRP(5000), "alice", "bob", "carol"); @@ -677,7 +677,7 @@ struct Escrow_test : public beast::unit_test::suite using namespace jtx; using namespace std::chrono; - Env env(*this, features(featureEscrow)); + Env env(*this, with_features(featureEscrow)); env.fund(XRP(5000), "alice", "bob", "carol"); env(condpay("alice", "carol", XRP(1000), makeSlice(cb1), env.now() + 1s)); @@ -691,7 +691,7 @@ struct Escrow_test : public beast::unit_test::suite using namespace jtx; using namespace std::chrono; - Env env(*this, features(featureEscrow)); + Env env(*this, with_features(featureEscrow)); env.memoize("alice"); env.memoize("bob"); diff --git a/src/test/app/Flow_test.cpp b/src/test/app/Flow_test.cpp index 22f6109625..5b04ec087d 100644 --- a/src/test/app/Flow_test.cpp +++ b/src/test/app/Flow_test.cpp @@ -82,7 +82,7 @@ struct Flow_test : public beast::unit_test::suite auto const USD = gw["USD"]; { // Pay USD, trivial path - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, gw); env.trust (USD (1000), alice, bob); @@ -92,7 +92,7 @@ struct Flow_test : public beast::unit_test::suite } { // XRP transfer - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob); env (pay (alice, bob, XRP (100))); @@ -101,7 +101,7 @@ struct Flow_test : public beast::unit_test::suite } { // Partial payments - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, gw); env.trust (USD (1000), alice, bob); @@ -115,7 +115,7 @@ struct Flow_test : public beast::unit_test::suite } { // Pay by rippling through accounts, use path finder - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, carol, dan); env.trust (USDA (10), bob); @@ -130,7 +130,7 @@ struct Flow_test : public beast::unit_test::suite { // Pay by rippling through accounts, specify path // and charge a transfer fee - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, carol, dan); env.trust (USDA (10), bob); @@ -148,7 +148,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, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, carol, dan); env.trust (USDA (10), bob); @@ -164,7 +164,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, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, carol, dan, erin); env.trust (USDA (10), bob, carol); @@ -185,7 +185,7 @@ struct Flow_test : public beast::unit_test::suite } { // Limit quality - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, carol); env.trust (USDA (10), bob); @@ -222,7 +222,7 @@ struct Flow_test : public beast::unit_test::suite if (!hasFeature(featureFlow, fs) && bobDanQIn < 100 && bobAliceQOut < 100) continue; // Bug in flow v1 - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, carol, dan); env(trust(bob, USDD(100)), qualityInPercent(bobDanQIn)); env(trust(bob, USDA(100)), qualityOutPercent(bobAliceQOut)); @@ -245,7 +245,7 @@ struct Flow_test : public beast::unit_test::suite // bob -> alice -> carol; vary carolAliceQIn for (auto carolAliceQIn : {80, 100, 120}) { - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, carol); env(trust(bob, USDA(10))); env(trust(carol, USDA(10)), qualityInPercent(carolAliceQIn)); @@ -261,7 +261,7 @@ struct Flow_test : public beast::unit_test::suite // bob -> alice -> carol; bobAliceQOut varies. for (auto bobAliceQOut : {80, 100, 120}) { - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, carol); env(trust(bob, USDA(10)), qualityOutPercent(bobAliceQOut)); env(trust(carol, USDA(10))); @@ -290,7 +290,7 @@ struct Flow_test : public beast::unit_test::suite { // simple IOU/IOU offer - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, carol, gw); env.trust (USD (1000), alice, bob, carol); @@ -311,7 +311,7 @@ struct Flow_test : public beast::unit_test::suite } { // simple IOU/XRP XRP/IOU offer - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, carol, gw); env.trust (USD (1000), alice, bob, carol); @@ -335,7 +335,7 @@ struct Flow_test : public beast::unit_test::suite } { // simple XRP -> USD through offer and sendmax - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, carol, gw); env.trust (USD (1000), alice, bob, carol); @@ -356,7 +356,7 @@ struct Flow_test : public beast::unit_test::suite } { // simple USD -> XRP through offer and sendmax - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, carol, gw); env.trust (USD (1000), alice, bob, carol); @@ -377,7 +377,7 @@ struct Flow_test : public beast::unit_test::suite } { // test unfunded offers are removed when payment succeeds - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, carol, gw); env.trust (USD (1000), alice, bob, carol); @@ -423,7 +423,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, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, carol, gw); env.trust (USD (1000), alice, bob, carol); @@ -498,7 +498,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, features (fs)); + Env env (*this, with_features (fs)); auto const closeTime = STAmountSO::soTime2 + 100 * env.closed ()->info ().closeTimeResolution; @@ -541,7 +541,7 @@ struct Flow_test : public beast::unit_test::suite { // Simple payment through a gateway with a // transfer rate - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, carol, gw); env(rate(gw, 1.25)); @@ -553,7 +553,7 @@ struct Flow_test : public beast::unit_test::suite } { // transfer rate is not charged when issuer is src or dst - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, carol, gw); env(rate(gw, 1.25)); @@ -565,7 +565,7 @@ struct Flow_test : public beast::unit_test::suite } { // transfer fee on an offer - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, carol, gw); env(rate(gw, 1.25)); @@ -583,7 +583,7 @@ struct Flow_test : public beast::unit_test::suite { // Transfer fee two consecutive offers - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, carol, gw); env(rate(gw, 1.25)); @@ -606,7 +606,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, features(fs)); + Env env (*this, with_features(fs)); auto const USDA = alice["USD"]; auto const USDB = bob["USD"]; @@ -626,7 +626,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, features(fs)); + Env env (*this, with_features(fs)); auto const USDA = alice["USD"]; auto const USDB = bob["USD"]; Account const dan ("dan"); @@ -653,7 +653,7 @@ struct Flow_test : public beast::unit_test::suite { // Offer where the owner is also the issuer, owner pays fee - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, gw); env(rate(gw, 1.25)); @@ -668,7 +668,7 @@ struct Flow_test : public beast::unit_test::suite if (!hasFeature(featureOwnerPaysFee, fs)) { // Offer where the owner is also the issuer, sender pays fee - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); env.fund (XRP (10000), alice, bob, gw); env(rate(gw, 1.25)); @@ -696,7 +696,7 @@ struct Flow_test : public beast::unit_test::suite Account const bob ("bob"); Account const carol ("carol"); - Env env (*this, features (fs)); + Env env (*this, with_features (fs)); auto const closeTime = fix1141Time() + 100 * env.closed ()->info ().closeTimeResolution; @@ -749,7 +749,7 @@ struct Flow_test : public beast::unit_test::suite for(auto const& d: {-timeDelta*100, +timeDelta*100}){ auto const closeTime = fix1141Time () + d; - Env env (*this); + Env env (*this, no_features); env.close (closeTime); env.fund (XRP(10000), alice, bob, carol, gw); @@ -809,7 +809,7 @@ struct Flow_test : public beast::unit_test::suite auto const USD = gw1["USD"]; auto const EUR = gw2["EUR"]; - Env env (*this, features (fs)); + Env env (*this, with_features (fs)); auto const closeTime = fix1141Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -883,7 +883,7 @@ struct Flow_test : public beast::unit_test::suite auto const USD = gw1["USD"]; auto const EUR = gw2["EUR"]; - Env env (*this, features (fs)); + Env env (*this, with_features (fs)); auto const closeTime = fix1141Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -951,7 +951,7 @@ struct Flow_test : public beast::unit_test::suite using namespace jtx; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); // Need new behavior from `accountHolds` auto const closeTime = fix1141Time() + @@ -982,7 +982,7 @@ struct Flow_test : public beast::unit_test::suite using namespace jtx; { // Test reverse - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); auto closeTime = fix1298Time(); if (withFix) closeTime += env.closed()->info().closeTimeResolution; @@ -1014,7 +1014,7 @@ struct Flow_test : public beast::unit_test::suite } { // Test forward - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); auto closeTime = fix1298Time(); if (withFix) closeTime += env.closed()->info().closeTimeResolution; @@ -1054,7 +1054,7 @@ struct Flow_test : public beast::unit_test::suite testcase("ReexecuteDirectStep"); using namespace jtx; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); auto const alice = Account("alice"); auto const bob = Account("bob"); @@ -1110,7 +1110,7 @@ struct Flow_test : public beast::unit_test::suite testcase("ripd1443"); using namespace jtx; - Env env(*this, features(featureFlow)); + Env env(*this, with_features(featureFlow)); auto const timeDelta = env.closed ()->info ().closeTimeResolution; auto const d = withFix ? timeDelta*100 : -timeDelta*100; auto closeTime = fix1443Time() + d; @@ -1163,7 +1163,7 @@ struct Flow_test : public beast::unit_test::suite testcase("ripd1449"); using namespace jtx; - Env env(*this, features(featureFlow)); + Env env(*this, with_features(featureFlow)); auto const timeDelta = env.closed ()->info ().closeTimeResolution; auto const d = withFix ? timeDelta*100 : -timeDelta*100; auto closeTime = fix1449Time() + d; @@ -1209,7 +1209,7 @@ struct Flow_test : public beast::unit_test::suite using namespace jtx; - Env env(*this, features (fs)); + Env env(*this, with_features (fs)); auto const ann = Account("ann"); auto const gw = Account("gateway"); @@ -1243,7 +1243,7 @@ struct Flow_test : public beast::unit_test::suite auto const alice = Account("alice"); - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice); diff --git a/src/test/app/Freeze_test.cpp b/src/test/app/Freeze_test.cpp index 4aa07b89ed..c79816c0fd 100644 --- a/src/test/app/Freeze_test.cpp +++ b/src/test/app/Freeze_test.cpp @@ -58,7 +58,7 @@ class Freeze_test : public beast::unit_test::suite testcase("RippleState Freeze"); using namespace test::jtx; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); Account G1 {"G1"}; Account alice {"alice"}; @@ -212,7 +212,7 @@ class Freeze_test : public beast::unit_test::suite testcase("Global Freeze"); using namespace test::jtx; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); Account G1 {"G1"}; Account A1 {"A1"}; @@ -370,7 +370,7 @@ class Freeze_test : public beast::unit_test::suite testcase("No Freeze"); using namespace test::jtx; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); Account G1 {"G1"}; Account A1 {"A1"}; @@ -424,7 +424,7 @@ class Freeze_test : public beast::unit_test::suite testcase("Offers for Frozen Trust Lines"); using namespace test::jtx; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); Account G1 {"G1"}; Account A2 {"A2"}; diff --git a/src/test/app/MultiSign_test.cpp b/src/test/app/MultiSign_test.cpp index ef3649cbe8..23fdebaf69 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, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); 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, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); 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, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); Account const alice {"alice", KeyType::ed25519}; env.fund(XRP(1000), alice); env.close(); @@ -191,7 +191,7 @@ public: test_enablement() { using namespace jtx; - Env env(*this); + Env env(*this, no_features); 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, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); 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, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); 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, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); 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, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); 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, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); 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, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); 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, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); 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, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); 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, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); 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, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); // 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, features(featureMultiSign)}; + Env env {*this, with_features(featureMultiSign)}; 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 d0d676d184..76ea0845b1 100644 --- a/src/test/app/Offer_test.cpp +++ b/src/test/app/Offer_test.cpp @@ -30,6 +30,14 @@ 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); @@ -112,7 +120,7 @@ public: // not used for the payment. using namespace jtx; - Env env {*this, features(fs)}; + Env env {*this, with_features(fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -163,7 +171,7 @@ public: testcase ("Removing Canceled Offers"); using namespace jtx; - Env env {*this, features(fs)}; + Env env {*this, with_features(fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -233,7 +241,7 @@ public: auto const USD = gw["USD"]; auto const EUR = gw["EUR"]; - Env env {*this, features(fs)}; + Env env {*this, with_features(fs)}; env.fund (XRP (10000), alice, bob, carol, gw); env.trust (USD (1000), alice, bob, carol); @@ -295,7 +303,7 @@ public: if (!withFix && fs.size()) continue; - Env env {*this, features(fs)}; + Env env {*this, with_features(fs)}; auto closeTime = [&] { @@ -376,7 +384,7 @@ public: { // No ripple with an implied account step after an offer - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -405,7 +413,7 @@ public: } { // Make sure payment works with default flags - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -460,7 +468,7 @@ public: // No crossing: { - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -485,7 +493,7 @@ public: // Partial cross: { - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -519,7 +527,7 @@ public: // if an offer were added. Attempt to sell IOUs to // buy XRP. If it fully crosses, we succeed. { - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -585,7 +593,7 @@ public: // Fill or Kill - unless we fully cross, just charge // a fee and not place the offer on the books: { - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -630,7 +638,7 @@ public: // Immediate or Cancel - cross as much as possible // and add nothing on the books: { - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -686,7 +694,7 @@ public: // tfPassive -- place the offer without crossing it. { - Env env (*this, features (fs)); + Env env (*this, with_features (fs)); auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -743,7 +751,7 @@ public: // tfPassive -- cross only offers of better quality. { - Env env (*this, features (fs)); + Env env (*this, with_features (fs)); auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -795,7 +803,7 @@ public: auto const alice = Account {"alice"}; auto const USD = gw["USD"]; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -899,7 +907,7 @@ public: Json::StaticString const key ("Expiration"); - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -972,7 +980,7 @@ public: auto const usdOffer = USD (1000); auto const xrpOffer = XRP (1000); - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1038,7 +1046,7 @@ public: auto const USD = gw["USD"]; auto const BTC = gw["BTC"]; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1096,8 +1104,7 @@ public: { auto acctOffers = offersOnAccount (env, account_to_test); BEAST_EXPECT(acctOffers.size() == - (std::find (fs.begin(), fs.end(), featureFlowCross) == - fs.end() ? 1 : 0)); + (hasFeature (featureFlowCross, fs) ? 0 : 1)); for (auto const& offerPtr : acctOffers) { auto const& offer = *offerPtr; @@ -1154,7 +1161,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1215,8 +1222,7 @@ public: // small_amount and transfer no XRP. The new offer crossing transfers // a single drop, rather than no drops. auto const crossingDelta = - std::find (fs.begin(), fs.end(), featureFlowCross) == - fs.end() ? drops (0) : drops (1); + (hasFeature (featureFlowCross, fs) ? drops (1) : drops (0)); jrr = ledgerEntryState (env, alice, gw, "USD"); BEAST_EXPECT(jrr[jss::node][sfBalance.fieldName][jss::value] == "50"); @@ -1242,7 +1248,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1302,7 +1308,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1352,7 +1358,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1385,7 +1391,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1419,7 +1425,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1484,7 +1490,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1517,7 +1523,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1609,7 +1615,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1653,7 +1659,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1705,7 +1711,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1775,7 +1781,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1833,7 +1839,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1873,7 +1879,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1919,7 +1925,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -1967,7 +1973,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -2076,7 +2082,7 @@ public: auto const gw = Account("gateway"); auto const USD = gw["USD"]; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -2238,7 +2244,7 @@ public: auto const usdOffer = USD(1000); auto const xrpOffer = XRP(1000); - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -2323,7 +2329,7 @@ public: auto const usdOffer = USD(1000); auto const eurOffer = EUR(1000); - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -2420,7 +2426,7 @@ public: auto const usdOffer = USD(1000); auto const eurOffer = EUR(1000); - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -2518,7 +2524,7 @@ public: auto const gw = Account("gateway"); auto const USD = gw["USD"]; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -2695,7 +2701,7 @@ public: auto const bob = Account("bob"); auto const USD = gw["USD"]; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -2775,7 +2781,7 @@ public: auto const gw1 = Account("gateway1"); auto const USD = gw1["USD"]; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3100,7 +3106,7 @@ public: auto const gw = Account("gateway"); auto const USD = gw["USD"]; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3163,7 +3169,7 @@ public: auto const USD = gw1["USD"]; auto const EUR = gw2["EUR"]; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3284,7 +3290,7 @@ public: // correctly now. using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3336,9 +3342,7 @@ public: // The problem was identified when featureOwnerPaysFee was enabled, // so make sure that gets included. - std::vector fsPlus (fs); - fsPlus.push_back (featureOwnerPaysFee); - Env env {*this, features (fsPlus)}; + Env env {*this, with_features(fs) | with_features(featureOwnerPaysFee)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3388,8 +3392,7 @@ public: // Determine which TEC code we expect. TER const tecExpect = - std::find (fs.begin(), fs.end(), featureFlow) == fs.end() - ? tecPATH_DRY : temBAD_PATH; + hasFeature(featureFlow, fs) ? temBAD_PATH : tecPATH_DRY; // This payment caused the assert. env (pay (ann, ann, D_BUX(30)), @@ -3417,7 +3420,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3472,7 +3475,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3512,7 +3515,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3561,7 +3564,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3615,7 +3618,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time () + 100 * env.closed ()->info ().closeTimeResolution; @@ -3674,7 +3677,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time() + 100 * env.closed()->info().closeTimeResolution; @@ -3757,7 +3760,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time() + 100 * env.closed()->info().closeTimeResolution; @@ -3909,7 +3912,7 @@ public: using namespace jtx; - Env env {*this, features (fs)}; + Env env {*this, with_features (fs)}; auto const closeTime = fix1449Time() + 100 * env.closed()->info().closeTimeResolution; @@ -3964,8 +3967,7 @@ public: // Pick the right tests. auto const& tests = - std::find (fs.begin(), fs.end(), featureFlowCross) == - fs.end() ? takerTests : flowTests; + hasFeature(featureFlowCross, fs) ? flowTests : takerTests; for (auto const& t : tests) { @@ -4036,7 +4038,7 @@ public: void testRequireAuth (std::initializer_list fs) { // Only test FlowCross. Results are different with Taker. - if (std::find (fs.begin(), fs.end(), featureFlowCross) == fs.end()) + if (!hasFeature(featureFlowCross, fs)) return; testcase ("lsfRequireAuth"); @@ -4056,7 +4058,7 @@ public: using namespace jtx; - Env env {*this, fs}; + Env env {*this, with_features(fs)}; auto const closeTime = fix1449Time() + 100 * env.closed()->info().closeTimeResolution; @@ -4137,7 +4139,7 @@ public: // Try to set tick size without enabling feature { - Env env {*this, features(fs)}; + Env env {*this, with_features(fs)}; auto const gw = Account {"gateway"}; env.fund (XRP(10000), gw); @@ -4146,9 +4148,11 @@ public: env(txn, ter(temDISABLED)); } + auto const fsPlus = with_features(fs) | with_features(featureTickSize); + // Try to set tick size out of range { - Env env {*this, features(fs), features (featureTickSize)}; + Env env {*this, fsPlus}; auto const gw = Account {"gateway"}; env.fund (XRP(10000), gw); @@ -4181,7 +4185,7 @@ public: BEAST_EXPECT (! env.le(gw)->isFieldPresent (sfTickSize)); } - Env env {*this, features(fs), features (featureTickSize)}; + Env env {*this, fsPlus}; auto const gw = Account {"gateway"}; auto const alice = Account {"alice"}; auto const XTS = gw["XTS"]; @@ -4302,14 +4306,14 @@ public: testRequireAuth (fs); testTickSize (fs); }; -// The following test variants passed at one time in the past (and should -// still pass) but are commented out to conserve test time. -// testAll({ }); -// testAll({ featureFlowCross}); -// testAll({featureFlow }); - testAll({featureFlow, featureFlowCross}); - testAll({featureFlow, fix1373 }); - testAll({featureFlow, fix1373, featureFlowCross}); +// 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 }); + testAll({featureFlow, fix1373 }); + testAll({featureFlow, fix1373, featureFlowCross }); } }; diff --git a/src/test/app/Path_test.cpp b/src/test/app/Path_test.cpp index fd6be84cb9..c119fa3b42 100644 --- a/src/test/app/Path_test.cpp +++ b/src/test/app/Path_test.cpp @@ -1025,7 +1025,8 @@ public: { testcase("Path Find: CNY"); using namespace jtx; - Env env(*this); + Env env{*this, all_features_except(featureFlow)}; + Account A1 {"A1"}; Account A2 {"A2"}; Account A3 {"A3"}; diff --git a/src/test/app/PayChan_test.cpp b/src/test/app/PayChan_test.cpp index cb2b7f70bb..7cca6a4573 100644 --- a/src/test/app/PayChan_test.cpp +++ b/src/test/app/PayChan_test.cpp @@ -175,7 +175,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("simple"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, features (featurePayChan)); + Env env (*this, with_features (featurePayChan)); auto const alice = Account ("alice"); auto const bob = Account ("bob"); auto USDA = alice["USD"]; @@ -347,7 +347,7 @@ struct PayChan_test : public beast::unit_test::suite auto const carol = Account ("carol"); { // If dst claims after cancel after, channel closes - Env env (*this, features (featurePayChan)); + Env env (*this, with_features (featurePayChan)); env.fund (XRP (10000), alice, bob); auto const pk = alice.pk (); auto const settleDelay = 100s; @@ -386,7 +386,7 @@ struct PayChan_test : public beast::unit_test::suite } { // Third party can close after cancel after - Env env (*this, features (featurePayChan)); + Env env (*this, with_features (featurePayChan)); env.fund (XRP (10000), alice, bob, carol); auto const pk = alice.pk (); auto const settleDelay = 100s; @@ -416,7 +416,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("expiration"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, features (featurePayChan)); + Env env (*this, with_features (featurePayChan)); auto const alice = Account ("alice"); auto const bob = Account ("bob"); auto const carol = Account ("carol"); @@ -477,7 +477,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("settle delay"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, features (featurePayChan)); + Env env (*this, with_features (featurePayChan)); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -537,7 +537,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("close dry"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, features (featurePayChan)); + Env env (*this, with_features (featurePayChan)); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -573,7 +573,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("default amount"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, features (featurePayChan)); + Env env (*this, with_features (featurePayChan)); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -632,7 +632,7 @@ struct PayChan_test : public beast::unit_test::suite using namespace std::literals::chrono_literals; { // Create a channel where dst disallows XRP - Env env (*this, features (featurePayChan)); + Env env (*this, with_features (featurePayChan)); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -648,7 +648,7 @@ struct PayChan_test : public beast::unit_test::suite { // Claim to a channel where dst disallows XRP // (channel is created before disallow xrp is set) - Env env (*this, features (featurePayChan)); + Env env (*this, with_features (featurePayChan)); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -674,7 +674,7 @@ struct PayChan_test : public beast::unit_test::suite using namespace jtx; using namespace std::literals::chrono_literals; // Create a channel where dst disallows XRP - Env env (*this, features (featurePayChan)); + Env env (*this, with_features (featurePayChan)); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -699,7 +699,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("Multiple channels to the same account"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, features (featurePayChan)); + Env env (*this, with_features (featurePayChan)); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -721,7 +721,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("RPC"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, features (featurePayChan)); + Env env (*this, with_features (featurePayChan)); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -791,7 +791,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("Optional Fields"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, features (featurePayChan)); + Env env (*this, with_features (featurePayChan)); auto const alice = Account ("alice"); auto const bob = Account ("bob"); auto const carol = Account ("carol"); @@ -831,7 +831,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("malformed pk"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, features (featurePayChan)); + Env env (*this, with_features (featurePayChan)); auto const alice = Account ("alice"); auto const bob = Account ("bob"); auto USDA = alice["USD"]; diff --git a/src/test/app/PayStrand_test.cpp b/src/test/app/PayStrand_test.cpp index 3eefff6286..083a700918 100644 --- a/src/test/app/PayStrand_test.cpp +++ b/src/test/app/PayStrand_test.cpp @@ -632,7 +632,7 @@ struct PayStrandAllPairs_test : public beast::unit_test::suite using RippleCalc = ::ripple::path::RippleCalc; ExistingElementPool eep; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); auto const closeTime = fix1298Time() + 100 * env.closed()->info().closeTimeResolution; @@ -910,7 +910,7 @@ struct PayStrand_test : public beast::unit_test::suite }; { - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, gw); env.trust(USD(1000), alice, bob); env.trust(EUR(1000), alice, bob); @@ -951,7 +951,7 @@ struct PayStrand_test : public beast::unit_test::suite }; { - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, carol, gw); test(env, USD, boost::none, STPath(), terNO_LINE); @@ -1134,7 +1134,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, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, carol, gw); env.trust(USD(10000), alice, bob, carol); @@ -1156,7 +1156,7 @@ struct PayStrand_test : public beast::unit_test::suite } { - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, noripple(gw)); env.trust(USD(1000), alice, bob); env(pay(gw, alice, USD(100))); @@ -1165,7 +1165,7 @@ struct PayStrand_test : public beast::unit_test::suite { // check global freeze - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, gw); env.trust(USD(1000), alice, bob); env(pay(gw, alice, USD(100))); @@ -1190,7 +1190,7 @@ struct PayStrand_test : public beast::unit_test::suite } { // Freeze between gw and alice - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, gw); env.trust(USD(1000), alice, bob); env(pay(gw, alice, USD(100))); @@ -1203,7 +1203,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, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, gw); env(fset(gw, asfRequireAuth)); env.trust(USD(1000), alice, bob); @@ -1231,7 +1231,7 @@ struct PayStrand_test : public beast::unit_test::suite } { // Check path with sendMax and node with correct sendMax already set - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, gw); env.trust(USD(1000), alice, bob); env.trust(EUR(1000), alice, bob); @@ -1246,7 +1246,7 @@ struct PayStrand_test : public beast::unit_test::suite { // last step xrp from offer - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, gw); env.trust(USD(1000), alice, bob); env(pay(gw, alice, USD(100))); @@ -1287,7 +1287,7 @@ struct PayStrand_test : public beast::unit_test::suite if (hasFeature(fix1373, fs)) { - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, gw); env.trust(USD(1000), alice, bob); @@ -1319,7 +1319,7 @@ struct PayStrand_test : public beast::unit_test::suite } { - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, carol, gw); env.trust(USD(10000), alice, bob, carol); @@ -1337,7 +1337,7 @@ struct PayStrand_test : public beast::unit_test::suite } { - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, carol, gw); env.trust(USD(10000), alice, bob, carol); @@ -1371,7 +1371,7 @@ struct PayStrand_test : public beast::unit_test::suite auto const CNY = gw["CNY"]; { - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, carol, gw); env.trust(USD(10000), alice, bob, carol); @@ -1396,7 +1396,7 @@ struct PayStrand_test : public beast::unit_test::suite ter(expectedResult)); } { - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, carol, gw); env.trust(USD(10000), alice, bob, carol); @@ -1431,7 +1431,7 @@ struct PayStrand_test : public beast::unit_test::suite auto const gw = Account("gw"); auto const USD = gw["USD"]; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(10000), alice, bob, gw); STAmount sendMax{USD.issue(), 100, 1}; diff --git a/src/test/app/Regression_test.cpp b/src/test/app/Regression_test.cpp index debf65c509..7cd62d01fd 100644 --- a/src/test/app/Regression_test.cpp +++ b/src/test/app/Regression_test.cpp @@ -171,7 +171,7 @@ struct Regression_test : public beast::unit_test::suite .set("minimum_txn_in_ledger_standalone", "3"); return cfg; }), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); 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 e9f49c92b6..25f8b149e9 100644 --- a/src/test/app/SetAuth_test.cpp +++ b/src/test/app/SetAuth_test.cpp @@ -52,13 +52,13 @@ struct SetAuth_test : public beast::unit_test::suite auto const gw = Account("gw"); auto const USD = gw["USD"]; { - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); env.fund(XRP(100000), "alice", gw); env(fset(gw, asfRequireAuth)); env(auth(gw, "alice", "USD"), ter(tecNO_LINE_REDUNDANT)); } { - Env env(*this, features(featureTrustSetAuth)); + Env env(*this, with_features(featureTrustSetAuth)); env.fund(XRP(100000), "alice", "bob", gw); env(fset(gw, asfRequireAuth)); env(auth(gw, "alice", "USD")); diff --git a/src/test/app/Ticket_test.cpp b/src/test/app/Ticket_test.cpp index 0b4104236f..3af7db0d7d 100644 --- a/src/test/app/Ticket_test.cpp +++ b/src/test/app/Ticket_test.cpp @@ -115,7 +115,7 @@ class Ticket_test : public beast::unit_test::suite testcase ("Feature Not Enabled"); using namespace test::jtx; - Env env {*this}; + Env env {*this, no_features}; env (ticket::create (env.master), ter(temDISABLED)); env (ticket::cancel (env.master, idOne), ter (temDISABLED)); @@ -126,7 +126,7 @@ class Ticket_test : public beast::unit_test::suite testcase ("Cancel Nonexistent"); using namespace test::jtx; - Env env {*this, features (featureTickets)}; + Env env {*this, with_features (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, features (featureTickets)}; + Env env {*this, with_features (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, features (featureTickets)}; + Env env {*this, with_features (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, features (featureTickets)}; + Env env {*this, with_features (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, features (featureTickets)}; + Env env {*this, with_features (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, features (featureTickets)}; + Env env {*this, with_features (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, features (featureTickets)}; + Env env {*this, with_features (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, features (featureTickets)}; + Env env {*this, with_features (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, features (featureTickets)}; + Env env {*this, with_features (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, features (featureTickets)}; + Env env {*this, with_features (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, features (featureTickets)}; + Env env {*this, with_features (featureTickets)}; // create and verify uint32_t expire = diff --git a/src/test/app/TrustAndBalance_test.cpp b/src/test/app/TrustAndBalance_test.cpp index 57a5d85c01..7e81c3b350 100644 --- a/src/test/app/TrustAndBalance_test.cpp +++ b/src/test/app/TrustAndBalance_test.cpp @@ -51,7 +51,7 @@ class TrustAndBalance_test : public beast::unit_test::suite testcase ("Payment to Nonexistent Account"); using namespace test::jtx; - Env env {*this, features(fs)}; + Env env {*this, with_features(fs)}; env (pay (env.master, "alice", XRP(1)), ter(tecNO_DST_INSUF_XRP)); env.close(); } @@ -167,7 +167,7 @@ class TrustAndBalance_test : public beast::unit_test::suite testcase ("Direct Payment, Ripple"); using namespace test::jtx; - Env env {*this, features(fs)}; + Env env {*this, with_features(fs)}; Account alice {"alice"}; Account bob {"bob"}; @@ -210,7 +210,7 @@ class TrustAndBalance_test : public beast::unit_test::suite (subscribe ? "With " : "Without ") + " Subscribe"); using namespace test::jtx; - Env env {*this, features(fs)}; + Env env {*this, with_features(fs)}; auto wsc = test::makeWSClient(env.app().config()); Account gw {"gateway"}; Account alice {"alice"}; @@ -288,7 +288,7 @@ class TrustAndBalance_test : public beast::unit_test::suite testcase ("Payments With Paths and Fees"); using namespace test::jtx; - Env env {*this, features(fs)}; + Env env {*this, with_features(fs)}; Account gw {"gateway"}; Account alice {"alice"}; Account bob {"bob"}; @@ -336,7 +336,7 @@ class TrustAndBalance_test : public beast::unit_test::suite testcase ("Indirect Payment"); using namespace test::jtx; - Env env {*this, features(fs)}; + Env env {*this, with_features(fs)}; Account gw {"gateway"}; Account alice {"alice"}; Account bob {"bob"}; @@ -378,7 +378,7 @@ class TrustAndBalance_test : public beast::unit_test::suite (with_rate ? "With " : "Without ") + " Xfer Fee, "); using namespace test::jtx; - Env env {*this, features(fs)}; + Env env {*this, with_features(fs)}; Account gw {"gateway"}; Account amazon {"amazon"}; Account alice {"alice"}; @@ -443,7 +443,7 @@ class TrustAndBalance_test : public beast::unit_test::suite testcase ("Set Invoice ID on Payment"); using namespace test::jtx; - Env env {*this, features(fs)}; + Env env {*this, with_features(fs)}; Account alice {"alice"}; auto wsc = test::makeWSClient(env.app().config()); diff --git a/src/test/app/TxQ_test.cpp b/src/test/app/TxQ_test.cpp index 8adb6cca61..903e9d230a 100644 --- a/src/test/app/TxQ_test.cpp +++ b/src/test/app/TxQ_test.cpp @@ -168,7 +168,7 @@ public: using namespace std::chrono; Env env(*this, makeConfig({ {"minimum_txn_in_ledger_standalone", "3"} }), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); auto& txq = env.app().getTxQ(); auto alice = Account("alice"); @@ -355,7 +355,7 @@ public: using namespace std::chrono; Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); auto alice = Account("alice"); auto bob = Account("bob"); @@ -411,7 +411,7 @@ public: using namespace std::chrono; Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); auto alice = Account("alice"); auto bob = Account("bob"); @@ -519,7 +519,7 @@ public: using namespace std::chrono; Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); auto alice = Account("alice"); auto bob = Account("bob"); @@ -625,7 +625,7 @@ public: { using namespace jtx; - Env env(*this, makeConfig(), features(featureFeeEscalation)); + Env env(*this, makeConfig(), with_features(featureFeeEscalation)); auto alice = Account("alice"); auto bob = Account("bob"); @@ -650,7 +650,7 @@ public: using namespace jtx; Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); auto alice = Account("alice"); auto bob = Account("bob"); @@ -703,12 +703,11 @@ public: { using namespace jtx; - Env env( - *this, + Env env(*this, makeConfig( {{"minimum_txn_in_ledger_standalone", "3"}}, {{"account_reserve", "200"}, {"owner_reserve", "50"}}), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); auto alice = Account("alice"); auto bob = Account("bob"); @@ -936,7 +935,7 @@ public: using namespace std::chrono; Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "4" } }), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); auto alice = Account("alice"); auto bob = Account("bob"); @@ -1072,7 +1071,7 @@ public: { using namespace jtx; - Env env(*this); + Env env(*this, no_features); auto alice = Account("alice"); @@ -1095,7 +1094,7 @@ public: using namespace jtx; Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "1" } }), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); auto alice = Account("alice"); @@ -1138,7 +1137,7 @@ public: { {"minimum_txn_in_ledger_standalone", "2"}, {"target_txn_in_ledger", "4"}, {"maximum_txn_in_ledger", "5"} }), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); auto alice = Account("alice"); auto queued = ter(terQUEUED); @@ -1168,7 +1167,7 @@ public: makeConfig( {{"minimum_txn_in_ledger_standalone", "3"}}, {{"account_reserve", "200"}, {"owner_reserve", "50"}}), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); auto alice = Account("alice"); auto bob = Account("bob"); @@ -1258,7 +1257,7 @@ public: Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }), - features(featureFeeEscalation), features(featureMultiSign)); + with_features(featureFeeEscalation, featureMultiSign)); auto alice = Account("alice"); auto bob = Account("bob"); @@ -1323,7 +1322,7 @@ public: Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }), - features(featureFeeEscalation), features(featureTickets)); + with_features(featureFeeEscalation, featureTickets)); auto alice = Account("alice"); auto charlie = Account("charlie"); @@ -1568,7 +1567,7 @@ public: { using namespace jtx; using namespace std::chrono; - Env env(*this, features(featureTickets)); + Env env(*this, with_features(featureTickets)); auto const alice = Account("alice"); env.memoize(alice); env.memoize("bob"); @@ -1636,7 +1635,7 @@ public: { using namespace jtx; { - Env env(*this, features(featureFeeEscalation)); + Env env(*this, with_features(featureFeeEscalation)); auto fee = env.rpc("fee"); @@ -1693,7 +1692,7 @@ public: } { - Env env(*this); + Env env(*this, no_features); auto fee = env.rpc("fee"); @@ -1725,7 +1724,7 @@ public: Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "1" }, {"ledgers_in_queue", "10"}, {"maximum_txn_per_account", "20"} }), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); // Alice will recreate the scenario. Bob will block. auto const alice = Account("alice"); @@ -1800,7 +1799,7 @@ public: testcase("Autofilled sequence should account for TxQ"); using namespace jtx; Env env(*this, makeConfig({ {"minimum_txn_in_ledger_standalone", "6"} }), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); Env_ss envs(env); auto const& txQ = env.app().getTxQ(); @@ -1930,7 +1929,7 @@ public: { using namespace jtx; Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); Env_ss envs(env); Account const alice{ "alice" }; @@ -2200,7 +2199,7 @@ public: { using namespace jtx; Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); Env_ss envs(env); Account const alice{ "alice" }; @@ -2423,7 +2422,7 @@ public: using namespace jtx; Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); Json::Value stream; stream[jss::streams] = Json::arrayValue; @@ -2592,7 +2591,7 @@ public: Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }), - features(featureFeeEscalation)); + with_features(featureFeeEscalation)); auto alice = Account("alice"); auto bob = Account("bob"); diff --git a/src/test/jtx/Env.h b/src/test/jtx/Env.h index 9dbbe95976..086175ea40 100644 --- a/src/test/jtx/Env.h +++ b/src/test/jtx/Env.h @@ -56,6 +56,13 @@ namespace ripple { + +namespace detail { +extern +std::vector +supportedAmendments (); +} + namespace test { namespace jtx { @@ -67,28 +74,88 @@ noripple (Account const& account, Args const&... args) return {{account, args...}}; } -/** Activate features in the Env ctor */ +/** + * @brief create collection of features to pass to Env ctor + * + * The resulting collection will contain *only* the features + * passed as arguments. + * + * @param key+args features to include in resulting collection + */ template -std::array -features (uint256 const& key, Args const&... args) +FeatureBitset +with_features (uint256 const& key, Args const&... args) { - return {{key, args...}}; + return makeFeatureBitset( + std::array{{key, args...}}); } -/** Activate features in the Env ctor */ -inline -auto -features (std::initializer_list keys) +/** + * @brief create collection of features to pass to Env ctor + * + * The resulting collection will contain *only* the features + * passed as arguments. + * + * @param keys features to include in resulting collection + */ +template +FeatureBitset +with_features (Col&& keys) { - return keys; + return makeFeatureBitset(std::forward(keys)); } -/** Activate features in the Env ctor */ +constexpr FeatureBitset no_features = {}; + inline -auto -features (std::vector keys) +FeatureBitset +all_amendments() { - return keys; + static const FeatureBitset ids = []{ + auto const& sa = ripple::detail::supportedAmendments(); + std::vector feats; + feats.reserve(sa.size()); + for (auto const& s : sa) + { + if (auto const f = getRegisteredFeature(s.substr(65))) + feats.push_back(*f); + else + Throw ("Unknown feature: " + s + " in supportedAmendments."); + } + return makeFeatureBitset(feats); + }(); + return ids; +} + +/** + * @brief create collection of features to pass to Env ctor + * + * The resulting collection will contain *all supported amendments* minus + * the features passed as arguments. + * + * @param keys features to exclude from the resulting collection + */ +template +FeatureBitset +all_features_except (Col const& keys) +{ + return all_amendments() & ~makeFeatureBitset(keys); +} + +/** + * + * @brief create collection of features to pass to Env ctor + * The resulting collection will contain *all supported amendments* minus + * the features passed as arguments. + * + * @param key+args features to exclude from the resulting collection + */ +template +FeatureBitset +all_features_except (uint256 const& key, Args const&... args) +{ + return all_features_except( + std::array{{key, args...}}); } //------------------------------------------------------------------------------ @@ -120,70 +187,86 @@ private: AppBundle bundle_; - inline - void - construct() - { - } - - template - void - construct (Arg&& arg, Args&&... args) - { - construct_arg(std::forward(arg)); - construct(std::forward(args)...); - } - - template - void - construct_arg ( - std::array const& list) - { - for(auto const& key : list) - app().config().features.insert(key); - } - - void - construct_arg ( - std::initializer_list list) - { - for(auto const& key : list) - app().config().features.insert(key); - } - - void - construct_arg ( - std::vector const& list) - { - for(auto const& key : list) - app().config().features.insert(key); - } - public: Env() = delete; - Env (Env const&) = delete; Env& operator= (Env const&) = delete; + Env (Env const&) = delete; + /** + * @brief Create Env using suite, Config pointer, and explicit features. + * + * This constructor will create an Env with the specified configuration + * and takes ownership the passed Config pointer. Features will be enabled + * according to rules described below (see next constructor). + * + * @param suite_ the current unit_test::suite + * @param config The desired Config - ownership will be taken by moving + * the pointer. See envconfig and related functions for common config tweaks. + * @param args with_features() to explicitly enable or all_features_except() to + * enable all and disable specific features + */ // VFALCO Could wrap the suite::log in a Journal here - template Env (beast::unit_test::suite& suite_, - std::unique_ptr config, - Args&&... args) + std::unique_ptr config, + FeatureBitset features) : test (suite_) , bundle_ (suite_, std::move(config)) { memoize(Account::master); Pathfinder::initPathTable(); - // enable the the invariant enforcement amendment by default. - construct( - features(featureEnforceInvariants), - std::forward(args)...); + foreachFeature( + features, [& appFeats = app().config().features](uint256 const& f) { + appFeats.insert(f); + }); } - template + /** + * @brief Create Env with default config and specified + * features. + * + * This constructor will create an Env with the standard Env configuration + * (from envconfig()) and features explicitly specified. Use with_features(...) + * or all_features_except(...) to create a collection of features appropriate + * for passing here. + * + * @param suite_ the current unit_test::suite + * @param args collection of features + * + */ Env (beast::unit_test::suite& suite_, - Args&&... args) - : Env(suite_, envconfig(), std::forward(args)...) + FeatureBitset features) + : Env(suite_, envconfig(), features) + { + } + + /** + * @brief Create Env using suite and Config pointer. + * + * This constructor will create an Env with the specified configuration + * and takes ownership the passed Config pointer. All supported amendments + * are enabled by this version of the constructor. + * + * @param suite_ the current unit_test::suite + * @param config The desired Config - ownership will be taken by moving + * the pointer. See envconfig and related functions for common config tweaks. + */ + Env (beast::unit_test::suite& suite_, + std::unique_ptr config) + : Env(suite_, std::move(config), all_amendments()) + { + } + + /** + * @brief Create Env with only the current test suite + * + * This constructor will create an Env with the standard + * test Env configuration (from envconfig()) and all supported + * amendments enabled. + * + * @param suite_ the current unit_test::suite + */ + Env (beast::unit_test::suite& suite_) + : Env(suite_, envconfig()) { } diff --git a/src/test/jtx/Env_test.cpp b/src/test/jtx/Env_test.cpp index 18a4419cf8..407d8d110d 100644 --- a/src/test/jtx/Env_test.cpp +++ b/src/test/jtx/Env_test.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include namespace ripple { @@ -354,7 +355,7 @@ public: { using namespace jtx; - Env env(*this, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); env.fund(XRP(10000), "alice"); env(signers("alice", 1, { { "alice", 1 }, { "bob", 2 } }), ter(temBAD_SIGNER)); @@ -383,7 +384,7 @@ public: ticket::create("alice", 60, "bob"); { - Env env(*this, features(featureTickets)); + Env env(*this, with_features(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))); @@ -627,6 +628,129 @@ public: } } + void testFeatures() + { + testcase("Env features"); + using namespace jtx; + auto const supported = all_amendments(); + + // this finds a feature that is not in + // the supported amendments list and tests that it can be + // enabled explicitly + + auto const neverSupportedFeat = [&]() -> boost::optional + { + auto const n = supported.size(); + for(size_t i = 0; i < n; ++i) + if (!supported[i]) + return bitsetIndexToFeature(i); + + return boost::none; + }(); + + if (!neverSupportedFeat) + { + log << "No unsupported features found - skipping test." << std::endl; + pass(); + return; + } + + auto const neverSupported = with_features(*neverSupportedFeat); + + auto hasFeature = [](Env& env, uint256 const& f) + { + return (env.app().config().features.find (f) != + env.app().config().features.end()); + }; + + { + // default Env has all supported features + Env env{*this}; + BEAST_EXPECT( + supported.count() == env.app().config().features.size()); + foreachFeature(supported, [&](uint256 const& f) { + this->BEAST_EXPECT(hasFeature(env, f)); + }); + } + + { + // a Env with_features has *only* those features + Env env{*this, with_features(featureEscrow, featureTickets)}; + BEAST_EXPECT(env.app().config().features.size() == 2); + foreachFeature(supported, [&](uint256 const& f) { + bool const has = (f == featureEscrow || f == featureTickets); + this->BEAST_EXPECT(has == hasFeature(env, f)); + }); + } + + { + // a Env all_features_except is missing *only* those features + Env env{*this, all_features_except(featureEscrow, featureTickets)}; + BEAST_EXPECT( + env.app().config().features.size() == (supported.count() - 2)); + foreachFeature(supported, [&](uint256 const& f) { + bool hasnot = (f == featureEscrow || f == featureTickets); + this->BEAST_EXPECT(hasnot != hasFeature(env, f)); + }); + } + + { + // add a feature that is NOT in the supported amendments list + // along with a list of explicit amendments + // the unsupported feature should be enabled along with + // the two supported ones + Env env{ + *this, + with_features(featureEscrow, featureTickets) | neverSupported}; + + // this app will have just 2 supported amendments and + // one additional never supported feature flag + BEAST_EXPECT(env.app().config().features.size() == (2 + 1)); + BEAST_EXPECT(hasFeature(env, *neverSupportedFeat)); + + foreachFeature(supported, [&](uint256 const& f) { + bool has = (f == featureEscrow || f == featureTickets); + this->BEAST_EXPECT(has == hasFeature(env, f)); + }); + } + + { + // add a feature that is NOT in the supported amendments list + // and omit a few standard amendments + // the unsupported features should be enabled + Env env{*this, + all_features_except(featureEscrow, featureTickets) | + neverSupported}; + + // this app will have all supported amendments minus 2 and then the + // one additional never supported feature flag + BEAST_EXPECT( + env.app().config().features.size() == + (supported.count() - 2 + 1)); + BEAST_EXPECT(hasFeature(env, *neverSupportedFeat)); + foreachFeature(supported, [&](uint256 const& f) { + bool hasnot = (f == featureEscrow || f == featureTickets); + this->BEAST_EXPECT(hasnot != hasFeature(env, f)); + }); + } + + { + // add a feature that is NOT in the supported amendments list + // along with all supported amendments + // the unsupported features should be enabled + Env env{*this, all_amendments() | neverSupported}; + + // this app will have all supported amendments and then the + // one additional never supported feature flag + BEAST_EXPECT( + env.app().config().features.size() == (supported.count() + 1)); + BEAST_EXPECT(hasFeature(env, *neverSupportedFeat)); + foreachFeature(supported, [&](uint256 const& f) { + this->BEAST_EXPECT(hasFeature(env, f)); + }); + } + } + void run() { @@ -648,6 +772,7 @@ public: testPath(); testResignSigned(); testSignAndSubmit(); + testFeatures(); } }; diff --git a/src/test/ledger/BookDirs_test.cpp b/src/test/ledger/BookDirs_test.cpp index 1418641e7a..933f24d742 100644 --- a/src/test/ledger/BookDirs_test.cpp +++ b/src/test/ledger/BookDirs_test.cpp @@ -28,7 +28,7 @@ struct BookDirs_test : public beast::unit_test::suite void test_bookdir(std::initializer_list fs) { using namespace jtx; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); auto gw = Account("gw"); auto USD = gw["USD"]; env.fund(XRP(1000000), "alice", "bob", "gw"); diff --git a/src/test/ledger/PaymentSandbox_test.cpp b/src/test/ledger/PaymentSandbox_test.cpp index ebed1ee0ff..7cee87c662 100644 --- a/src/test/ledger/PaymentSandbox_test.cpp +++ b/src/test/ledger/PaymentSandbox_test.cpp @@ -60,7 +60,7 @@ class PaymentSandbox_test : public beast::unit_test::suite testcase ("selfFunding"); using namespace jtx; - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); Account const gw1 ("gw1"); Account const gw2 ("gw2"); Account const snd ("snd"); @@ -101,7 +101,7 @@ class PaymentSandbox_test : public beast::unit_test::suite testcase ("subtractCredits"); using namespace jtx; - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); Account const gw1 ("gw1"); Account const gw2 ("gw2"); Account const alice ("alice"); @@ -266,7 +266,7 @@ class PaymentSandbox_test : public beast::unit_test::suite using namespace jtx; - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); Account const gw ("gw"); Account const alice ("alice"); @@ -312,7 +312,7 @@ class PaymentSandbox_test : public beast::unit_test::suite return env.current ()->fees ().accountReserve (count); }; - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); Account const alice ("alice"); env.fund (reserve(env, 1), alice); @@ -340,7 +340,7 @@ class PaymentSandbox_test : public beast::unit_test::suite testcase ("balanceHook"); using namespace jtx; - Env env (*this, features(fs)); + Env env (*this, with_features(fs)); Account const gw ("gw"); auto const USD = gw["USD"]; diff --git a/src/test/ledger/View_test.cpp b/src/test/ledger/View_test.cpp index 4c698a1460..d974cbcfa6 100644 --- a/src/test/ledger/View_test.cpp +++ b/src/test/ledger/View_test.cpp @@ -844,7 +844,7 @@ class DirIsEmpty_test auto const alice = Account("alice"); auto const bogie = Account("bogie"); - Env env(*this, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); env.fund(XRP(10000), alice); env.close(); diff --git a/src/test/rpc/AccountInfo_test.cpp b/src/test/rpc/AccountInfo_test.cpp index 31904ef9fe..1dc29004d9 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, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); Account const alice {"alice"}; env.fund(XRP(1000), alice); @@ -165,7 +165,7 @@ public: void testSignerListsV2() { using namespace jtx; - Env env(*this, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); 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 248fb05680..b5c33ec023 100644 --- a/src/test/rpc/AccountSet_test.cpp +++ b/src/test/rpc/AccountSet_test.cpp @@ -223,10 +223,12 @@ public: env(jt, ter(temBAD_TRANSFER_RATE)); } - void testBadInputs() + void testBadInputs(bool withFeatures) { using namespace test::jtx; - Env env(*this); + std::unique_ptr penv { + withFeatures ? new Env(*this) : new Env(*this, no_features)}; + Env& env = *penv; Account const alice ("alice"); env.fund(XRP(10000), alice); @@ -259,13 +261,14 @@ public: env(jt, ter(temINVALID_FLAG)); env(fset (alice, asfDisableMaster), - sig(alice), ter(tecNO_REGULAR_KEY)); + sig(alice), + ter(withFeatures ? tecNO_ALTERNATIVE_KEY : tecNO_REGULAR_KEY)); } void testRequireAuthWithDir() { using namespace test::jtx; - Env env(*this, features(featureMultiSign)); + Env env(*this, with_features(featureMultiSign)); Account const alice ("alice"); Account const bob ("bob"); @@ -303,7 +306,8 @@ public: testMessageKey(); testWalletID(); testEmailHash(); - testBadInputs(); + testBadInputs(true); + testBadInputs(false); testRequireAuthWithDir(); testTransferRate(); } diff --git a/src/test/rpc/Feature_test.cpp b/src/test/rpc/Feature_test.cpp index a375adf877..7fa2aa12a6 100644 --- a/src/test/rpc/Feature_test.cpp +++ b/src/test/rpc/Feature_test.cpp @@ -116,8 +116,7 @@ class Feature_test : public beast::unit_test::suite using namespace test::jtx; Env env {*this, - features(featureEscrow), - features(featureCryptoConditions)}; + with_features(featureEscrow, featureCryptoConditions)}; // The amendment table has to be modified // since that is what feature RPC actually checks env.app().getAmendmentTable().enable(featureEscrow); @@ -221,7 +220,7 @@ class Feature_test : public beast::unit_test::suite using namespace test::jtx; Env env {*this, - features(featureCryptoConditions)}; + with_features(featureCryptoConditions)}; // The amendment table has to be modified // since that is what feature RPC actually checks env.app().getAmendmentTable().enable(featureCryptoConditions); diff --git a/src/test/rpc/GatewayBalances_test.cpp b/src/test/rpc/GatewayBalances_test.cpp index 6f76e0e7cc..73bfa6db76 100644 --- a/src/test/rpc/GatewayBalances_test.cpp +++ b/src/test/rpc/GatewayBalances_test.cpp @@ -34,7 +34,7 @@ public: { using namespace std::chrono_literals; using namespace jtx; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); // Gateway account and assets Account const alice {"alice"}; diff --git a/src/test/rpc/JSONRPC_test.cpp b/src/test/rpc/JSONRPC_test.cpp index d828c44067..4f31b953b3 100644 --- a/src/test/rpc/JSONRPC_test.cpp +++ b/src/test/rpc/JSONRPC_test.cpp @@ -1942,7 +1942,7 @@ public: .set("minimum_txn_in_ledger_standalone", "3"); return cfg; }), - test::jtx::features(featureFeeEscalation)}; + with_features(featureFeeEscalation)}; LoadFeeTrack const& feeTrack = env.app().getFeeTrack(); { @@ -2254,7 +2254,7 @@ public: // "b" (not in the ledger) is rDg53Haik2475DJx8bjMDSDPj4VX7htaMd. // "c" (phantom signer) is rPcNzota6B8YBokhYtcTNqQVCngtbnWfux. - test::jtx::Env env(*this, test::jtx::features(featureMultiSign)); + test::jtx::Env env(*this, test::jtx::with_features(featureMultiSign)); env.fund(test::jtx::XRP(100000), a, ed, g); env.close(); diff --git a/src/test/rpc/LedgerClosed_test.cpp b/src/test/rpc/LedgerClosed_test.cpp index f987658f4c..5bb1cdd5ac 100644 --- a/src/test/rpc/LedgerClosed_test.cpp +++ b/src/test/rpc/LedgerClosed_test.cpp @@ -30,7 +30,7 @@ public: void testMonitorRoot() { using namespace test::jtx; - Env env {*this}; + Env env {*this, no_features}; Account const alice {"alice"}; env.fund(XRP(10000), alice); diff --git a/src/test/rpc/LedgerData_test.cpp b/src/test/rpc/LedgerData_test.cpp index 384c3ec7f7..dbede8d2e5 100644 --- a/src/test/rpc/LedgerData_test.cpp +++ b/src/test/rpc/LedgerData_test.cpp @@ -268,7 +268,7 @@ public: using namespace test::jtx; using namespace std::chrono; Env env { *this, envconfig(validator, ""), - features(featureMultiSign, featureTickets, + with_features(featureMultiSign, featureTickets, featureEscrow, featurePayChan) }; Account const gw { "gateway" }; auto const USD = gw["USD"]; diff --git a/src/test/rpc/LedgerRPC_test.cpp b/src/test/rpc/LedgerRPC_test.cpp index 596e463e25..3828dc8e7f 100644 --- a/src/test/rpc/LedgerRPC_test.cpp +++ b/src/test/rpc/LedgerRPC_test.cpp @@ -286,7 +286,8 @@ class LedgerRPC_test : public beast::unit_test::suite void testLookupLedger() { using namespace test::jtx; - Env env { *this }; + Env env {*this, no_features}; // hashes requested below assume + //no amendments env.fund(XRP(10000), "alice"); env.close(); env.fund(XRP(10000), "bob"); @@ -476,7 +477,7 @@ class LedgerRPC_test : public beast::unit_test::suite .set("minimum_txn_in_ledger_standalone", "3"); return cfg; }), - features(featureFeeEscalation)}; + with_features(featureFeeEscalation)}; Json::Value jv; jv[jss::ledger_index] = "current"; diff --git a/src/test/rpc/LedgerRequestRPC_test.cpp b/src/test/rpc/LedgerRequestRPC_test.cpp index d6212fbc00..ae71d647e2 100644 --- a/src/test/rpc/LedgerRequestRPC_test.cpp +++ b/src/test/rpc/LedgerRequestRPC_test.cpp @@ -150,7 +150,8 @@ public: void testEvolution() { using namespace test::jtx; - Env env { *this }; + Env env {*this, no_features}; //the hashes being checked below assume + //no amendments Account const gw { "gateway" }; auto const USD = gw["USD"]; env.fund(XRP(100000), gw); diff --git a/src/test/rpc/NoRipple_test.cpp b/src/test/rpc/NoRipple_test.cpp index fe2dbe6074..cbd7067e12 100644 --- a/src/test/rpc/NoRipple_test.cpp +++ b/src/test/rpc/NoRipple_test.cpp @@ -72,7 +72,7 @@ public: testcase("Set noripple on a line with negative balance"); using namespace jtx; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); auto const gw = Account("gateway"); auto const alice = Account("alice"); @@ -118,7 +118,7 @@ public: testcase("pairwise NoRipple"); using namespace jtx; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); auto const alice = Account("alice"); auto const bob = Account("bob"); @@ -155,7 +155,7 @@ public: testcase("Set default ripple on an account and check new trustlines"); using namespace jtx; - Env env(*this, features(fs)); + Env env(*this, with_features(fs)); auto const gw = Account("gateway"); auto const alice = Account("alice");