Refactor FeatureBitset:

* Remove composite helper functions
* Add set difference and Bitset/uint256 operators
* Convert tests to use new feature bitset set difference operator
This commit is contained in:
seelabs
2017-11-28 13:34:11 -05:00
parent 3523cee63d
commit e8d02c1333
29 changed files with 400 additions and 354 deletions

View File

@@ -107,16 +107,218 @@ supportedAmendments ();
boost::optional<uint256>
getRegisteredFeature (std::string const& name);
using FeatureBitset = std::bitset<detail::FeatureCollections::numFeatures()>;
size_t
featureToBitsetIndex(uint256 const& f);
uint256
bitsetIndexToFeature(size_t i);
bool
hasFeature (uint256 const& feat, FeatureBitset features);
class FeatureBitset
: private std::bitset<detail::FeatureCollections::numFeatures()>
{
using base = std::bitset<detail::FeatureCollections::numFeatures()>;
void initFromFeatures()
{
}
template<class... Fs>
void initFromFeatures(uint256 const& f, Fs&&... fs)
{
set(f);
initFromFeatures(std::forward<Fs>(fs)...);
}
public:
using base::bitset;
using base::operator==;
using base::operator!=;
using base::test;
using base::all;
using base::any;
using base::none;
using base::count;
using base::size;
using base::set;
using base::reset;
using base::flip;
using base::operator[];
using base::to_string;
using base::to_ulong;
using base::to_ullong;
FeatureBitset() = default;
explicit
FeatureBitset(base const& b)
: base(b)
{
}
template<class... Fs>
explicit
FeatureBitset(uint256 const& f, Fs&&... fs)
{
initFromFeatures(f, std::forward<Fs>(fs)...);
}
template <class Col>
explicit
FeatureBitset(Col const& fs)
{
for (auto const& f : fs)
set(featureToBitsetIndex(f));
}
auto operator[](uint256 const& f)
{
return base::operator[](featureToBitsetIndex(f));
}
auto operator[](uint256 const& f) const
{
return base::operator[](featureToBitsetIndex(f));
}
FeatureBitset&
set(uint256 const& f, bool value = true)
{
base::set(featureToBitsetIndex(f), value);
return *this;
}
FeatureBitset&
reset(uint256 const& f)
{
base::reset(featureToBitsetIndex(f));
return *this;
}
FeatureBitset&
flip(uint256 const& f)
{
base::flip(featureToBitsetIndex(f));
return *this;
}
FeatureBitset& operator&=(FeatureBitset const& rhs)
{
base::operator&=(rhs);
return *this;
}
FeatureBitset& operator|=(FeatureBitset const& rhs)
{
base::operator|=(rhs);
return *this;
}
FeatureBitset operator~() const
{
return FeatureBitset{base::operator~()};
}
friend
FeatureBitset operator&(
FeatureBitset const& lhs,
FeatureBitset const& rhs)
{
return FeatureBitset{static_cast<base const&>(lhs) &
static_cast<base const&>(rhs)};
}
friend
FeatureBitset operator&(
FeatureBitset const& lhs,
uint256 const& rhs)
{
return lhs & FeatureBitset{rhs};
}
friend
FeatureBitset operator&(
uint256 const& lhs,
FeatureBitset const& rhs)
{
return FeatureBitset{lhs} & rhs;
}
friend
FeatureBitset operator|(
FeatureBitset const& lhs,
FeatureBitset const& rhs)
{
return FeatureBitset{static_cast<base const&>(lhs) |
static_cast<base const&>(rhs)};
}
friend
FeatureBitset operator|(
FeatureBitset const& lhs,
uint256 const& rhs)
{
return lhs | FeatureBitset{rhs};
}
friend
FeatureBitset operator|(
uint256 const& lhs,
FeatureBitset const& rhs)
{
return FeatureBitset{lhs} | rhs;
}
friend
FeatureBitset operator^(
FeatureBitset const& lhs,
FeatureBitset const& rhs)
{
return FeatureBitset{static_cast<base const&>(lhs) ^
static_cast<base const&>(rhs)};
}
friend
FeatureBitset operator^(
FeatureBitset const& lhs,
uint256 const& rhs)
{
return lhs ^ FeatureBitset{rhs};
}
friend
FeatureBitset operator^(
uint256 const& lhs,
FeatureBitset const& rhs)
{
return FeatureBitset{lhs} ^ rhs;
}
// set difference
friend
FeatureBitset operator-(
FeatureBitset const& lhs,
FeatureBitset const& rhs)
{
return lhs & ~rhs;
}
friend
FeatureBitset operator-(
FeatureBitset const& lhs,
uint256 const& rhs)
{
return lhs - FeatureBitset{rhs};
}
friend
FeatureBitset operator-(
uint256 const& lhs,
FeatureBitset const& rhs)
{
return FeatureBitset{lhs} - rhs;
}
};
template <class F>
void
@@ -127,34 +329,6 @@ foreachFeature(FeatureBitset bs, F&& f)
f(bitsetIndexToFeature(i));
}
template <class Col>
FeatureBitset
makeFeatureBitset(Col&& fs)
{
FeatureBitset result;
for (auto const& f : fs)
result.set(featureToBitsetIndex(f));
return result;
}
template <class Col>
FeatureBitset
addFeatures(FeatureBitset bs, Col&& fs)
{
for (auto const& f : fs)
bs.set(featureToBitsetIndex(f));
return bs;
}
template <class Col>
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;
extern uint256 const featureTrustSetAuth;

View File

@@ -129,11 +129,6 @@ uint256 bitsetIndexToFeature(size_t i)
return featureCollections.bitsetIndexToFeature(i);
}
bool hasFeature(uint256 const& feat, FeatureBitset features)
{
return features[featureToBitsetIndex(feat)];
}
uint256 const featureMultiSign = *getRegisteredFeature("MultiSign");
uint256 const featureTickets = *getRegisteredFeature("Tickets");

View File

@@ -267,13 +267,11 @@ public:
testAutoBridgedLimits(features);
};
using namespace jtx;
testAll(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testAll(
supported_features_except ( fix1373, featureFlowCross));
testAll(
supported_features_except ( featureFlowCross));
// testAll(supported_amendments());// Does not pass with FlowCross enabled.
auto const sa = supported_amendments();
testAll(sa - featureFlow - fix1373 - featureFlowCross);
testAll(sa - fix1373 - featureFlowCross);
testAll(sa - featureFlowCross);
// testAll(sa);// Does not pass with FlowCross enabled.
}
};

View File

@@ -112,13 +112,11 @@ public:
run()
{
using namespace jtx;
test_convert_all_of_an_asset(
supported_features_except (featureFlow, fix1373, featureFlowCross));
test_convert_all_of_an_asset(
supported_features_except ( fix1373, featureFlowCross));
test_convert_all_of_an_asset(
supported_features_except ( featureFlowCross));
test_convert_all_of_an_asset(supported_amendments());
auto const sa = supported_amendments();
test_convert_all_of_an_asset(sa - featureFlow - fix1373 - featureFlowCross);
test_convert_all_of_an_asset(sa - fix1373 - featureFlowCross);
test_convert_all_of_an_asset(sa - featureFlowCross);
test_convert_all_of_an_asset(sa);
}
};

View File

@@ -145,13 +145,11 @@ public:
void run ()
{
using namespace test::jtx;
testXRPDiscrepancy (
supported_features_except (featureFlow, fix1373, featureFlowCross));
testXRPDiscrepancy (
supported_features_except ( fix1373, featureFlowCross));
testXRPDiscrepancy (
supported_features_except ( featureFlowCross));
testXRPDiscrepancy (supported_amendments());
auto const sa = supported_amendments();
testXRPDiscrepancy (sa - featureFlow - fix1373 - featureFlowCross);
testXRPDiscrepancy (sa - fix1373 - featureFlowCross);
testXRPDiscrepancy (sa - featureFlowCross);
testXRPDiscrepancy (sa);
}
};

View File

@@ -207,7 +207,7 @@ struct Escrow_test : public beast::unit_test::suite
using namespace std::chrono;
{ // Escrow not enabled
Env env(*this, supported_features_except (featureEscrow));
Env env(*this, supported_amendments() - featureEscrow);
env.fund(XRP(5000), "alice", "bob");
env(lockup("alice", "bob", XRP(1000), env.now() + 1s), ter(temDISABLED));
env(finish("bob", "alice", 1), ter(temDISABLED));
@@ -693,7 +693,7 @@ struct Escrow_test : public beast::unit_test::suite
{
testcase ("Metadata & Ownership (without fix1523)");
Env env(*this, supported_features_except (fix1523));
Env env(*this, supported_amendments() - fix1523);
env.fund(XRP(5000), alice, bruce, carol);
auto const seq = env.seq(alice);

View File

@@ -211,7 +211,7 @@ struct Flow_test : public beast::unit_test::suite
for (auto bobDanQIn : {80, 100, 120})
for (auto bobAliceQOut : {80, 100, 120})
{
if (!hasFeature(featureFlow, features) && bobDanQIn < 100 &&
if (!features[featureFlow] && bobDanQIn < 100 &&
bobAliceQOut < 100)
continue; // Bug in flow v1
Env env(*this, features);
@@ -657,7 +657,7 @@ struct Flow_test : public beast::unit_test::suite
balance (alice, xrpMinusFee(env, 10000-100)),
balance (bob, USD (100)));
}
if (!hasFeature(featureOwnerPaysFee, features))
if (!features[featureOwnerPaysFee])
{
// Offer where the owner is also the issuer, sender pays fee
Env env (*this, features);
@@ -742,7 +742,7 @@ struct Flow_test : public beast::unit_test::suite
for (auto const& d : {-100 * timeDelta, +100 * timeDelta})
{
auto const closeTime = fix1141Time () + d ;
Env env (*this, no_features);
Env env (*this, FeatureBitset{});
env.close (closeTime);
env.fund (XRP(10000), alice, bob, carol, gw);
@@ -1249,13 +1249,12 @@ struct Flow_test : public beast::unit_test::suite
void testWithFeats(FeatureBitset features)
{
using namespace jtx;
FeatureBitset const ownerPaysFee
{with_only_features (featureOwnerPaysFee)};
FeatureBitset const ownerPaysFee{featureOwnerPaysFee};
testLineQuality(features);
testFalseDry(features);
// Only do the rest of the tests if featureFlow is enabled.
if (! hasFeature (featureFlow, features))
if (!features[featureFlow])
return;
testDirectStep(features);
testBookStep(features);
@@ -1268,7 +1267,7 @@ struct Flow_test : public beast::unit_test::suite
testSelfFundedXRPEndpoint(true, features);
testUnfundedOffer(true, features);
testUnfundedOffer(false, features);
testReexecuteDirectStep(features | with_only_features (fix1368));
testReexecuteDirectStep(features | fix1368);
testSelfPayLowQualityOffer(features);
}
@@ -1281,15 +1280,12 @@ struct Flow_test : public beast::unit_test::suite
testRIPD1449(false);
using namespace jtx;
testWithFeats(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testWithFeats(
supported_features_except ( fix1373, featureFlowCross));
testWithFeats(
supported_features_except ( featureFlowCross));
testWithFeats(supported_amendments());
testEmptyStrand(supported_amendments());
auto const sa = supported_amendments();
testWithFeats(sa - featureFlow - fix1373 - featureFlowCross);
testWithFeats(sa - fix1373 - featureFlowCross);
testWithFeats(sa - featureFlowCross);
testWithFeats(sa);
testEmptyStrand(sa);
}
};
@@ -1298,29 +1294,29 @@ struct Flow_manual_test : public Flow_test
void run() override
{
using namespace jtx;
auto const all = supported_amendments();
auto const feeEscalation = with_only_features (featureFeeEscalation);
auto const flow = with_only_features (featureFlow);
auto const f1373 = with_only_features (fix1373);
auto const flowCross = with_only_features (featureFlowCross);
auto const f1513 = with_only_features (fix1513);
auto const all = supported_amendments();
FeatureBitset const feeEscalation{featureFeeEscalation};
FeatureBitset const flow{featureFlow};
FeatureBitset const f1373{fix1373};
FeatureBitset const flowCross{featureFlowCross};
FeatureBitset const f1513{fix1513};
testWithFeats(all & ~(feeEscalation | flow | f1373 | flowCross | f1513));
testWithFeats(all & ~( flow | f1373 | flowCross | f1513));
testWithFeats(all & ~( flow | f1373 | flowCross ));
testWithFeats(all & ~(feeEscalation | f1373 | flowCross | f1513));
testWithFeats(all & ~( f1373 | flowCross | f1513));
testWithFeats(all & ~( f1373 | flowCross ));
testWithFeats(all & ~(feeEscalation | flowCross | f1513));
testWithFeats(all & ~( flowCross | f1513));
testWithFeats(all & ~( flowCross ));
testWithFeats(all & ~(feeEscalation | f1513));
testWithFeats(all & ~( f1513));
testWithFeats(all - feeEscalation - flow - f1373 - flowCross - f1513);
testWithFeats(all - flow - f1373 - flowCross - f1513);
testWithFeats(all - flow - f1373 - flowCross );
testWithFeats(all - feeEscalation - f1373 - flowCross - f1513);
testWithFeats(all - f1373 - flowCross - f1513);
testWithFeats(all - f1373 - flowCross );
testWithFeats(all - feeEscalation - flowCross - f1513);
testWithFeats(all - flowCross - f1513);
testWithFeats(all - flowCross );
testWithFeats(all - feeEscalation - f1513);
testWithFeats(all - f1513);
testWithFeats(all );
testEmptyStrand(all & ~(feeEscalation | f1513));
testEmptyStrand(all & ~( f1513));
testEmptyStrand(all );
testEmptyStrand(all - feeEscalation - f1513);
testEmptyStrand(all - f1513);
testEmptyStrand(all );
}
};

View File

@@ -531,13 +531,11 @@ public:
testOffersWhenFrozen(features);
};
using namespace test::jtx;
testAll(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testAll(
supported_features_except ( fix1373, featureFlowCross));
testAll(
supported_features_except ( featureFlowCross));
testAll(supported_amendments());
auto const sa = supported_amendments();
testAll(sa - featureFlow - fix1373 - featureFlowCross);
testAll(sa - fix1373 - featureFlowCross);
testAll(sa - featureFlowCross);
testAll(sa);
}
};

View File

@@ -191,7 +191,7 @@ public:
test_enablement()
{
using namespace jtx;
Env env(*this, no_features);
Env env(*this, FeatureBitset{});
Account const alice {"alice", KeyType::ed25519};
env.fund(XRP(1000), alice);
env.close();

View File

@@ -297,12 +297,10 @@ public:
auto const USD = gw["USD"];
FeatureBitset const feeEscAndFlow =
with_only_features (featureFeeEscalation, featureFlow);
for (auto withFix : {false, true})
{
if (!withFix && ((features & feeEscAndFlow) != FeatureBitset{}))
if (!withFix &&
features[featureFlow] && features[featureFeeEscalation])
continue;
Env env {*this, features};
@@ -1105,8 +1103,7 @@ public:
// behavior.
{
auto acctOffers = offersOnAccount (env, account_to_test);
BEAST_EXPECT(acctOffers.size() ==
(hasFeature (featureFlowCross, features) ? 0 : 1));
BEAST_EXPECT(acctOffers.size() == (features[featureFlowCross] ? 0 : 1));
for (auto const& offerPtr : acctOffers)
{
auto const& offer = *offerPtr;
@@ -1223,8 +1220,7 @@ public:
// algorithms becomes apparent. The old offer crossing would consume
// small_amount and transfer no XRP. The new offer crossing transfers
// a single drop, rather than no drops.
auto const crossingDelta =
(hasFeature (featureFlowCross, features) ? drops (1) : drops (0));
auto const crossingDelta = features[featureFlowCross] ? drops (1) : drops (0);
jrr = ledgerEntryState (env, alice, gw, "USD");
BEAST_EXPECT(jrr[jss::node][sfBalance.fieldName][jss::value] == "50");
@@ -3344,7 +3340,7 @@ public:
// The problem was identified when featureOwnerPaysFee was enabled,
// so make sure that gets included.
Env env {*this, features | with_only_features(featureOwnerPaysFee)};
Env env {*this, features | featureOwnerPaysFee};
auto const closeTime =
fix1449Time () +
100 * env.closed ()->info ().closeTimeResolution;
@@ -3394,7 +3390,7 @@ public:
// Determine which TEC code we expect.
TER const tecExpect =
hasFeature(featureFlow, features) ? temBAD_PATH : tecPATH_DRY;
features[featureFlow] ? temBAD_PATH : tecPATH_DRY;
// This payment caused the assert.
env (pay (ann, ann, D_BUX(30)),
@@ -3968,8 +3964,7 @@ public:
};
// Pick the right tests.
auto const& tests =
hasFeature(featureFlowCross, features) ? flowTests : takerTests;
auto const& tests = features[featureFlowCross] ? flowTests : takerTests;
for (auto const& t : tests)
{
@@ -4158,7 +4153,7 @@ public:
env.close();
std::uint32_t const bobOfferSeq = env.seq (bob) - 1;
bool const flowCross = hasFeature (featureFlowCross, features);
bool const flowCross = features[featureFlowCross];
env.require (offers (alice, 0));
if (flowCross)
@@ -4364,7 +4359,7 @@ public:
env.close();
// The test behaves differently with or without FlowCross.
bool const flowCross = hasFeature (featureFlowCross, features);
bool const flowCross = features[featureFlowCross];
// Before FlowCross an account with lsfRequireAuth set could not
// create an offer to buy their own currency. After FlowCross
@@ -4406,11 +4401,11 @@ public:
using namespace jtx;
// Should be called with TickSize enabled.
BEAST_EXPECT (hasFeature (featureTickSize, features));
BEAST_EXPECT(features[featureTickSize]);
// Try to set tick size without enabling feature
{
Env env {*this, features & ~with_only_features(featureTickSize)};
Env env{*this, features - featureTickSize};
auto const gw = Account {"gateway"};
env.fund (XRP(10000), gw);
@@ -4575,26 +4570,26 @@ public:
testMissingAuth (features);
testRCSmoketest (features);
testSelfAuth (features);
testTickSize (features);
testTickSize (features | featureTickSize);
}
void run () override
{
using namespace jtx;
auto const all = supported_amendments();
auto const flow = with_only_features (featureFlow);
auto const f1373 = with_only_features (fix1373);
auto const flowCross = with_only_features (featureFlowCross);
FeatureBitset const flow{featureFlow};
FeatureBitset const f1373{fix1373};
FeatureBitset const flowCross{featureFlowCross};
(void) flow;
// The first three test variants below passed at one time in the past
// (and should still pass) but are commented out to conserve test time.
// testAll(all & ~(flow | f1373 | flowCross));
// testAll(all & ~(flow | f1373 ));
// testAll(all & ~( f1373 | flowCross));
testAll(all & ~( f1373 ));
testAll(all & ~( flowCross));
testAll(all );
// testAll(all - flow - f1373 - flowCross);
// testAll(all - flow - f1373 );
// testAll(all - f1373 - flowCross);
testAll(all - f1373 );
testAll(all - flowCross);
testAll(all );
}
};
@@ -4603,31 +4598,31 @@ class Offer_manual_test : public Offer_test
void run() override
{
using namespace jtx;
auto const all = supported_amendments();
auto const feeEscalation = with_only_features (featureFeeEscalation);
auto const flow = with_only_features (featureFlow);
auto const f1373 = with_only_features (fix1373);
auto const flowCross = with_only_features (featureFlowCross);
auto const f1513 = with_only_features (fix1513);
auto const all = supported_amendments();
FeatureBitset const feeEscalation{featureFeeEscalation};
FeatureBitset const flow{featureFlow};
FeatureBitset const f1373{fix1373};
FeatureBitset const flowCross{featureFlowCross};
FeatureBitset const f1513{fix1513};
testAll(all & ~(feeEscalation | flow | f1373 | flowCross | f1513));
testAll(all & ~( flow | f1373 | flowCross | f1513));
testAll(all & ~( flow | f1373 | flowCross ));
testAll(all & ~(feeEscalation | flow | f1373 | f1513));
testAll(all & ~( flow | f1373 | f1513));
testAll(all & ~( flow | f1373 ));
testAll(all & ~(feeEscalation | f1373 | flowCross | f1513));
testAll(all & ~( f1373 | flowCross | f1513));
testAll(all & ~( f1373 | flowCross ));
testAll(all & ~(feeEscalation | f1373 | f1513));
testAll(all & ~( f1373 | f1513));
testAll(all & ~( f1373 ));
testAll(all & ~(feeEscalation | flowCross | f1513));
testAll(all & ~( flowCross | f1513));
testAll(all & ~( flowCross ));
testAll(all & ~(feeEscalation | f1513));
testAll(all & ~( f1513));
testAll(all );
testAll(all -feeEscalation - flow - f1373 - flowCross - f1513);
testAll(all - flow - f1373 - flowCross - f1513);
testAll(all - flow - f1373 - flowCross );
testAll(all -feeEscalation - flow - f1373 - f1513);
testAll(all - flow - f1373 - f1513);
testAll(all - flow - f1373 );
testAll(all -feeEscalation - f1373 - flowCross - f1513);
testAll(all - f1373 - flowCross - f1513);
testAll(all - f1373 - flowCross );
testAll(all -feeEscalation - f1373 - f1513);
testAll(all - f1373 - f1513);
testAll(all - f1373 );
testAll(all -feeEscalation - flowCross - f1513);
testAll(all - flowCross - f1513);
testAll(all - flowCross );
testAll(all -feeEscalation - f1513);
testAll(all - f1513);
testAll(all );
}
};

View File

@@ -1025,7 +1025,8 @@ public:
{
testcase("Path Find: CNY");
using namespace jtx;
Env env{*this, supported_features_except(featureFlow)};
Env env{*this,
supported_amendments().reset(featureFlow)};
Account A1 {"A1"};
Account A2 {"A2"};

View File

@@ -847,8 +847,9 @@ struct PayStrandAllPairs_test : public beast::unit_test::suite
void
run() override
{
testAllPairs(jtx::supported_features_except (featureFlowCross));
testAllPairs(jtx::supported_amendments());
auto const sa = jtx::supported_amendments();
testAllPairs(sa - featureFlowCross);
testAllPairs(sa);
}
};
@@ -1278,7 +1279,7 @@ struct PayStrand_test : public beast::unit_test::suite
auto const USD = gw["USD"];
auto const EUR = gw["EUR"];
if (hasFeature(fix1373, features))
if (features[fix1373])
{
Env env(*this, features);
env.fund(XRP(10000), alice, bob, gw);
@@ -1376,8 +1377,7 @@ struct PayStrand_test : public beast::unit_test::suite
env(offer(bob, USD(100), XRP(100)), txflags(tfPassive));
auto const expectedResult = [&] {
if (hasFeature(featureFlow, features) &&
!hasFeature(fix1373, features))
if (features[featureFlow] && !features[fix1373])
return tesSUCCESS;
return temBAD_PATH_LOOP;
}();
@@ -1473,25 +1473,21 @@ struct PayStrand_test : public beast::unit_test::suite
run() override
{
using namespace jtx;
testToStrand(supported_features_except (fix1373, featureFlowCross));
testToStrand(supported_features_except ( featureFlowCross));
testToStrand(supported_amendments ());
auto const sa = supported_amendments();
testToStrand(sa - fix1373 - featureFlowCross);
testToStrand(sa - featureFlowCross);
testToStrand(sa);
testRIPD1373(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testRIPD1373(
supported_features_except ( featureFlowCross));
testRIPD1373(supported_amendments ());
testRIPD1373(sa - featureFlow - fix1373 - featureFlowCross);
testRIPD1373(sa - featureFlowCross);
testRIPD1373(sa);
testLoop(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testLoop(
supported_features_except ( fix1373, featureFlowCross));
testLoop(
supported_features_except ( featureFlowCross));
testLoop(supported_amendments ());
testLoop(sa - featureFlow - fix1373 - featureFlowCross);
testLoop(sa - fix1373 - featureFlowCross);
testLoop(sa - featureFlowCross);
testLoop(sa);
testNoAccount(supported_amendments ());
testNoAccount(sa);
}
};

View File

@@ -48,20 +48,20 @@ struct SetAuth_test : public beast::unit_test::suite
void testAuth(FeatureBitset features)
{
// featureTrustSetAuth should always be set by the caller.
BEAST_EXPECT (hasFeature (featureTrustSetAuth, features));
// featureTrustSetAuth should always be reset by the caller.
BEAST_EXPECT(!features[featureTrustSetAuth]);
using namespace jtx;
auto const gw = Account("gw");
auto const USD = gw["USD"];
{
Env env(*this, features & ~with_only_features(featureTrustSetAuth));
Env env(*this, features);
env.fund(XRP(100000), "alice", gw);
env(fset(gw, asfRequireAuth));
env(auth(gw, "alice", "USD"), ter(tecNO_LINE_REDUNDANT));
}
{
Env env(*this, features);
Env env(*this, features | featureTrustSetAuth);
env.fund(XRP(100000), "alice", "bob", gw);
env(fset(gw, asfRequireAuth));
@@ -80,13 +80,11 @@ struct SetAuth_test : public beast::unit_test::suite
void run() override
{
using namespace jtx;
testAuth(supported_features_except (
featureFlow, fix1373, featureFlowCross));
testAuth(supported_features_except (
fix1373, featureFlowCross));
testAuth(supported_features_except (
featureFlowCross));
testAuth(supported_amendments());
auto const sa = supported_amendments();
testAuth(sa - featureTrustSetAuth - featureFlow - fix1373 - featureFlowCross);
testAuth(sa - featureTrustSetAuth - fix1373 - featureFlowCross);
testAuth(sa - featureTrustSetAuth - featureFlowCross);
testAuth(sa - featureTrustSetAuth);
}
};

View File

@@ -115,7 +115,7 @@ class Ticket_test : public beast::unit_test::suite
testcase ("Feature Not Enabled");
using namespace test::jtx;
Env env {*this, no_features};
Env env {*this, FeatureBitset{}};
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, supported_features_plus (featureTickets)};
Env env {*this, supported_amendments().set(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, supported_features_plus (featureTickets)};
Env env {*this, supported_amendments().set(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, supported_features_plus (featureTickets)};
Env env {*this, supported_amendments().set(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, supported_features_plus (featureTickets)};
Env env {*this, supported_amendments().set(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, supported_features_plus (featureTickets)};
Env env {*this, supported_amendments().set(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, supported_features_plus (featureTickets)};
Env env {*this, supported_amendments().set(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, supported_features_plus (featureTickets)};
Env env {*this, supported_amendments().set(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, supported_features_plus (featureTickets)};
Env env {*this, supported_amendments().set(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, supported_features_plus (featureTickets)};
Env env {*this, supported_amendments().set(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, supported_features_plus (featureTickets)};
Env env {*this, supported_amendments().set(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, supported_features_plus (featureTickets)};
Env env {*this, supported_amendments().set(featureTickets)};
// create and verify
uint32_t expire =

View File

@@ -508,13 +508,11 @@ public:
};
using namespace test::jtx;
testWithFeatures(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testWithFeatures(
supported_features_except ( fix1373, featureFlowCross));
testWithFeatures(
supported_features_except ( featureFlowCross));
testWithFeatures(supported_amendments());
auto const sa = supported_amendments();
testWithFeatures(sa - featureFlow - fix1373 - featureFlowCross);
testWithFeatures(sa - fix1373 - featureFlowCross);
testWithFeatures(sa -featureFlowCross);
testWithFeatures(sa);
}
};

View File

@@ -1065,7 +1065,7 @@ public:
{
using namespace jtx;
Env env(*this, no_features);
Env env(*this, FeatureBitset{});
auto alice = Account("alice");
@@ -1557,7 +1557,7 @@ public:
{
using namespace jtx;
using namespace std::chrono;
Env env(*this, supported_features_plus (featureTickets));
Env env(*this, supported_amendments().set(featureTickets));
auto const alice = Account("alice");
env.memoize(alice);
env.memoize("bob");
@@ -1682,7 +1682,7 @@ public:
}
{
Env env(*this, no_features);
Env env(*this, FeatureBitset{});
auto fee = env.rpc("fee");

View File

@@ -67,39 +67,6 @@ noripple (Account const& account, Args const&... args)
return {{account, args...}};
}
/**
* @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 <class... Args>
FeatureBitset
with_only_features (uint256 const& key, Args const&... args)
{
return makeFeatureBitset(
std::array<uint256, 1 + sizeof...(args)>{{key, args...}});
}
/**
* @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<class Col>
FeatureBitset
with_only_features (Col&& keys)
{
return makeFeatureBitset(std::forward<Col>(keys));
}
constexpr FeatureBitset no_features = {};
inline
FeatureBitset
supported_amendments()
@@ -115,73 +82,11 @@ supported_amendments()
else
Throw<std::runtime_error> ("Unknown feature: " + s + " in supportedAmendments.");
}
return makeFeatureBitset(feats);
return FeatureBitset(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<class Col>
FeatureBitset
supported_features_except (Col const& keys)
{
return supported_amendments() & ~makeFeatureBitset(keys);
}
/**
*
* @brief create collection of features to pass to Env ctor
* The resulting collection will contain *all supported amendments* minus
* the features passed as arguments.
*
* @param key+args features to exclude from the resulting collection
*/
template <class... Args>
FeatureBitset
supported_features_except (uint256 const& key, Args const&... args)
{
return supported_features_except(
std::array<uint256, 1 + sizeof...(args)>{{key, args...}});
}
/**
* @brief create collection of features to pass to Env ctor
*
* The resulting collection will contain *all supported amendments* plus
* the features passed as arguments.
*
* @param keys features to include in the resulting collection
*/
template<class Col>
FeatureBitset
supported_features_plus (Col const& keys)
{
return supported_amendments() | makeFeatureBitset(keys);
}
/**
*
* @brief create collection of features to pass to Env ctor
* The resulting collection will contain *all supported amendments* plus
* the features passed as arguments.
*
* @param key+args features to include in the resulting collection
*/
template <class... Args>
FeatureBitset
supported_features_plus (uint256 const& key, Args const&... args)
{
return supported_features_plus(
std::array<uint256, 1 + sizeof...(args)>{{key, args...}});
}
class SuiteSink : public beast::Journal::Sink
{
std::string partition_;

View File

@@ -384,7 +384,7 @@ public:
ticket::create("alice", 60, "bob");
{
Env env(*this, supported_features_plus (featureTickets));
Env env(*this, supported_amendments().set(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)));
@@ -655,8 +655,6 @@ public:
return;
}
auto const neverSupported = with_only_features(*neverSupportedFeat);
auto hasFeature = [](Env& env, uint256 const& f)
{
return (env.app().config().features.find (f) !=
@@ -674,8 +672,8 @@ public:
}
{
// a Env with_only_features has *only* those features
Env env{*this, with_only_features(featureEscrow, featureFlow)};
// a Env FeatureBitset has *only* those features
Env env{*this, FeatureBitset(featureEscrow, featureFlow)};
BEAST_EXPECT(env.app().config().features.size() == 2);
foreachFeature(supported, [&](uint256 const& f) {
bool const has = (f == featureEscrow || f == featureFlow);
@@ -683,10 +681,11 @@ public:
});
}
auto const noFlowOrEscrow =
supported_amendments() - featureEscrow - featureFlow;
{
// a Env supported_features_except is missing *only* those features
Env env{*this,
supported_features_except(featureEscrow, featureFlow)};
Env env{*this, noFlowOrEscrow};
BEAST_EXPECT(
env.app().config().features.size() == (supported.count() - 2));
foreachFeature(supported, [&](uint256 const& f) {
@@ -702,8 +701,7 @@ public:
// the two supported ones
Env env{
*this,
with_only_features(
featureEscrow, featureFlow) | neverSupported};
FeatureBitset(featureEscrow, featureFlow, *neverSupportedFeat)};
// this app will have just 2 supported amendments and
// one additional never supported feature flag
@@ -721,8 +719,7 @@ public:
// and omit a few standard amendments
// the unsupported features should be enabled
Env env{*this,
supported_features_except(featureEscrow, featureFlow) |
neverSupported};
noFlowOrEscrow | FeatureBitset{*neverSupportedFeat}};
// this app will have all supported amendments minus 2 and then the
// one additional never supported feature flag
@@ -740,7 +737,7 @@ public:
// 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, supported_amendments() | neverSupported};
Env env{*this, supported_amendments().set(*neverSupportedFeat)};
// this app will have all supported amendments and then the
// one additional never supported feature flag

View File

@@ -95,11 +95,10 @@ struct BookDirs_test : public beast::unit_test::suite
void run() override
{
using namespace jtx;
test_bookdir(
supported_features_except (featureFlow, fix1373, featureFlowCross));
test_bookdir(
supported_features_except ( featureFlowCross));
test_bookdir(supported_amendments ());
auto const sa = supported_amendments();
test_bookdir(sa - featureFlow - fix1373 - featureFlowCross);
test_bookdir(sa - featureFlowCross);
test_bookdir(sa);
}
};

View File

@@ -88,7 +88,9 @@ struct Directory_test : public beast::unit_test::suite
{
testcase ("Directory Ordering (without 'SortedDirectories' amendment");
Env env(*this, supported_features_except(featureSortedDirectories));
Env env(
*this,
supported_amendments().reset(featureSortedDirectories));
env.fund(XRP(10000000), alice, bob, gw);
// Insert 400 offers from Alice, then one from Bob:

View File

@@ -378,11 +378,10 @@ public:
testBalanceHook(features);
};
using namespace jtx;
testAll(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testAll(
supported_features_except ( featureFlowCross));
testAll(supported_amendments());
auto const sa = supported_amendments();
testAll(sa - featureFlow - fix1373 - featureFlowCross);
testAll(sa - featureFlowCross);
testAll(sa);
}
};

View File

@@ -237,7 +237,7 @@ public:
{
testcase ("Setting transfer rate (without fix1201)");
doTests (supported_features_except(fix1201),
doTests (supported_amendments().reset(fix1201),
{
{ 1.0, tesSUCCESS, 1.0 },
{ 1.1, tesSUCCESS, 1.1 },
@@ -290,16 +290,17 @@ public:
};
// Test gateway with allowed transfer rates
runTest (Env{*this, supported_features_except(fix1201)}, 1.02);
runTest (Env{*this, supported_features_except(fix1201)}, 1);
runTest (Env{*this, supported_features_except(fix1201)}, 2);
runTest (Env{*this, supported_features_except(fix1201)}, 2.1);
auto const noFix1201 = supported_amendments().reset(fix1201);
runTest (Env{*this, noFix1201}, 1.02);
runTest (Env{*this, noFix1201}, 1);
runTest (Env{*this, noFix1201}, 2);
runTest (Env{*this, noFix1201}, 2.1);
runTest (Env{*this, supported_amendments()}, 1.02);
runTest (Env{*this, supported_amendments()}, 2);
// Test gateway when amendment is set after transfer rate
{
Env env (*this, supported_features_except(fix1201));
Env env (*this, noFix1201);
Account const alice ("alice");
Account const bob ("bob");
Account const gw ("gateway");
@@ -330,7 +331,7 @@ public:
{
using namespace test::jtx;
std::unique_ptr<Env> penv {
withFeatures ? new Env(*this) : new Env(*this, no_features)};
withFeatures ? new Env(*this) : new Env(*this, FeatureBitset{})};
Env& env = *penv;
Account const alice ("alice");
env.fund(XRP(10000), alice);

View File

@@ -116,7 +116,7 @@ class Feature_test : public beast::unit_test::suite
using namespace test::jtx;
Env env {*this,
with_only_features(featureEscrow, featureCryptoConditions)};
FeatureBitset(featureEscrow, featureCryptoConditions)};
auto jrr = env.rpc("feature") [jss::result];
if(! BEAST_EXPECT(jrr.isMember(jss::features)))
@@ -216,7 +216,7 @@ class Feature_test : public beast::unit_test::suite
using namespace test::jtx;
Env env {*this,
with_only_features(featureCryptoConditions)};
FeatureBitset(featureCryptoConditions)};
auto jrr = env.rpc("feature", "CryptoConditions") [jss::result];
if(! BEAST_EXPECTS(jrr[jss::status] == jss::success, "status"))

View File

@@ -154,11 +154,10 @@ public:
run() override
{
using namespace jtx;
testGWB(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testGWB(
supported_features_except ( featureFlowCross));
testGWB(supported_amendments());
auto const sa = supported_amendments();
testGWB(sa - featureFlow - fix1373 - featureFlowCross);
testGWB(sa - featureFlowCross);
testGWB(sa);
}
};

View File

@@ -30,7 +30,7 @@ public:
void testMonitorRoot()
{
using namespace test::jtx;
Env env {*this, no_features};
Env env {*this, FeatureBitset{}};
Account const alice {"alice"};
env.fund(XRP(10000), alice);

View File

@@ -267,8 +267,9 @@ public:
// Put a bunch of different LedgerEntryTypes into a ledger
using namespace test::jtx;
using namespace std::chrono;
Env env { *this, envconfig(validator, ""),
supported_features_plus(featureTickets) };
Env env{*this,
envconfig(validator, ""),
supported_amendments().set(featureTickets)};
Account const gw { "gateway" };
auto const USD = gw["USD"];

View File

@@ -286,7 +286,7 @@ class LedgerRPC_test : public beast::unit_test::suite
void testLookupLedger()
{
using namespace test::jtx;
Env env {*this, no_features}; // hashes requested below assume
Env env {*this, FeatureBitset{}}; // hashes requested below assume
//no amendments
env.fund(XRP(10000), "alice");
env.close();

View File

@@ -150,7 +150,7 @@ public:
void testEvolution()
{
using namespace test::jtx;
Env env {*this, no_features}; //the hashes being checked below assume
Env env {*this, FeatureBitset{}}; //the hashes being checked below assume
//no amendments
Account const gw { "gateway" };
auto const USD = gw["USD"];

View File

@@ -218,13 +218,11 @@ public:
testDefaultRipple(features);
};
using namespace jtx;
withFeatsTests(
supported_features_except (featureFlow, fix1373, featureFlowCross));
withFeatsTests(
supported_features_except ( fix1373, featureFlowCross));
withFeatsTests(
supported_features_except ( featureFlowCross));
withFeatsTests(supported_amendments());
auto const sa = supported_amendments();
withFeatsTests(sa - featureFlow - fix1373 - featureFlowCross);
withFeatsTests(sa - fix1373 - featureFlowCross);
withFeatsTests(sa - featureFlowCross);
withFeatsTests(sa);
}
};