Minimize use of jtx::with_only_features (RIPD-1515):

In order to automatically run unit tests with newly created
amendments, prefer to start with jtx::supported_features() and
then subtract unwanted features.

These changes identified a few bugs that were hiding in
amendments.  One of those bugs, in FlowCross, is not yet fixed.
By uncommenting the test in CrossingLimits_test.cpp you can see
failures relating to that bug.  Since FlowCross is not yet
enabled on the network we can fix the bug at our convenience.
This commit is contained in:
Scott Schurr
2017-08-16 18:30:55 -07:00
committed by seelabs
parent aa76632bb3
commit 3523cee63d
30 changed files with 826 additions and 658 deletions

View File

@@ -115,6 +115,9 @@ featureToBitsetIndex(uint256 const& f);
uint256
bitsetIndexToFeature(size_t i);
bool
hasFeature (uint256 const& feat, FeatureBitset features);
template <class F>
void
foreachFeature(FeatureBitset bs, F&& f)

View File

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

View File

@@ -37,18 +37,22 @@ private:
using namespace jtx;
auto const ownerCount = env.le(account)->getFieldU32(sfOwnerCount);
for (std::size_t i = 0; i < n; i++)
{
env(offer(account, in, out));
env.close();
}
env.require (owners (account, ownerCount + n));
}
public:
void
testStepLimit(std::initializer_list<uint256> fs)
testStepLimit(FeatureBitset features)
{
testcase ("Step Limit");
using namespace jtx;
Env env(*this, with_only_features(fs));
auto const xrpMax = XRP(100000000000);
Env env(*this, features);
auto const gw = Account("gateway");
auto const USD = gw["USD"];
@@ -62,27 +66,32 @@ public:
// Alice offers to buy 1000 XRP for 1000 USD. She takes Bob's first
// offer, and removes 999 more as unfunded and hits the step limit.
env(offer("alice", USD(1000), XRP(1000)),
require (
balance("alice", USD(1)), owners("alice", 2),
balance("bob", USD(0)), owners("bob", 1001),
balance("dan", USD(1)), owners("dan", 2)));
env(offer("alice", USD(1000), XRP(1000)));
env.require (balance("alice", USD(1)));
env.require (owners("alice", 2));
env.require (balance("bob", USD(0)));
env.require (owners("bob", 1001));
env.require (balance("dan", USD(1)));
env.require (owners("dan", 2));
// Carol offers to buy 1000 XRP for 1000 USD. She removes Bob's next
// 1000 offers as unfunded and hits the step limit.
env(offer("carol", USD(1000), XRP(1000)),
require (
balance("carol", USD(none)), owners("carol", 1),
balance("bob", USD(0)), owners("bob", 1),
balance("dan", USD(1)), owners("dan", 2)));
env(offer("carol", USD(1000), XRP(1000)));
env.require (balance("carol", USD(none)));
env.require (owners("carol", 1));
env.require (balance("bob", USD(0)));
env.require (owners("bob", 1));
env.require (balance("dan", USD(1)));
env.require (owners("dan", 2));
}
void
testCrossingLimit(std::initializer_list<uint256> fs)
testCrossingLimit(FeatureBitset features)
{
testcase ("Crossing Limit");
using namespace jtx;
Env env(*this, with_only_features(fs));
auto const xrpMax = XRP(100000000000);
Env env(*this, features);
auto const gw = Account("gateway");
auto const USD = gw["USD"];
@@ -93,25 +102,26 @@ public:
// Alice offers to buy 1000 XRP for 1000 USD. She takes the first
// 850 offers, hitting the crossing limit.
env(offer("alice", USD(1000), XRP(1000)),
require (
balance("alice", USD(850)),
balance("bob", USD(150)), owners ("bob", 151)));
env(offer("alice", USD(1000), XRP(1000)));
env.require (balance("alice", USD(850)));
env.require (balance("bob", USD(150)));
env.require (owners ("bob", 151));
// Carol offers to buy 1000 XRP for 1000 USD. She takes the remaining
// 150 offers without hitting a limit.
env(offer("carol", USD(1000), XRP(1000)),
require (
balance("carol", USD(150)),
balance("bob", USD(0)), owners ("bob", 1)));
env(offer("carol", USD(1000), XRP(1000)));
env.require (balance("carol", USD(150)));
env.require (balance("bob", USD(0)));
env.require (owners ("bob", 1));
}
void
testStepAndCrossingLimit(std::initializer_list<uint256> fs)
testStepAndCrossingLimit(FeatureBitset features)
{
testcase ("Step And Crossing Limit");
using namespace jtx;
Env env(*this, with_only_features(fs));
auto const xrpMax = XRP(100000000000);
Env env(*this, features);
auto const gw = Account("gateway");
auto const USD = gw["USD"];
@@ -131,36 +141,139 @@ public:
// Bob offers to buy 1000 XRP for 1000 USD. He takes all 400 USD from
// Alice's offers, 1 USD from Carol's and then removes 599 of Carol's
// offers as unfunded, before hitting the step limit.
env(offer("bob", USD(1000), XRP(1000)),
require (
balance("bob", USD(401)),
balance("alice", USD(600)), owners("alice", 1),
balance("carol", USD(0)), owners("carol", 101),
balance("evita", USD(1000)), owners("evita", 1000)));
env(offer("bob", USD(1000), XRP(1000)));
env.require (balance("bob", USD(401)));
env.require (balance("alice", USD(600)));
env.require (owners("alice", 1));
env.require (balance("carol", USD(0)));
env.require (owners("carol", 101));
env.require (balance("evita", USD(1000)));
env.require (owners("evita", 1000));
// Dan offers to buy 900 XRP for 900 USD. He removes all 100 of Carol's
// offers as unfunded, then takes 850 USD from Evita's, hitting the
// crossing limit.
env(offer("dan", USD(900), XRP(900)),
require (
balance("dan", USD(850)),
balance("alice", USD(600)), owners("alice", 1),
balance("carol", USD(0)), owners("carol", 1),
balance("evita", USD(150)), owners("evita", 150)));
env(offer("dan", USD(900), XRP(900)));
env.require (balance("dan", USD(850)));
env.require (balance("alice", USD(600)));
env.require (owners("alice", 1));
env.require (balance("carol", USD(0)));
env.require (owners("carol", 1));
env.require (balance("evita", USD(150)));
env.require (owners("evita", 150));
}
void testAutoBridgedLimits (FeatureBitset features)
{
testcase ("Auto Bridged Limits");
using namespace jtx;
Env env(*this, features);
auto const gw = Account("gateway");
auto const USD = gw["USD"];
auto const EUR = gw["EUR"];
env.fund(XRP(100000000), gw, "alice", "bob", "carol", "dan", "evita");
env.trust(USD(2000), "alice");
env(pay(gw, "alice", USD(2000)));
env.trust(USD(1000), "carol");
env(pay(gw, "carol", USD(3)));
env.trust(USD(1000), "evita");
env(pay(gw, "evita", USD(1000)));
n_offers (env, 302, "alice", EUR(2), XRP(1));
n_offers (env, 300, "alice", XRP(1), USD(4));
n_offers (env, 497, "carol", XRP(1), USD(3));
n_offers (env, 1001, "evita", EUR(1), USD(1));
// Bob offers to buy 2000 USD for 2000 EUR, even though he only has
// 1000 EUR.
// 1. He spends 600 EUR taking Alice's auto-bridged offers and
// gets 1200 USD for that.
// 2. He spends another 2 EUR taking one of Alice's EUR->XRP and
// one of Carol's XRP-USD offers. He gets 3 USD for that.
// 3. The remainder of Carol's offers are now unfunded. We've
// consumed 602 offers so far. We now chew through 398 more
// of Carol's unfunded offers until we hit the 1000 offer limit.
// This sets have_bridge to false -- we will handle no more
// bridged offers.
// 4. However, have_direct is still true. So we go around one more
// time and take one of Evita's offers.
// 5. After taking one of Evita's offers we notice (again) that our
// offer count was exceeded. So we completely stop after taking
// one of Evita's offers.
env.trust(EUR(10000), "bob");
env.close();
env(pay(gw, "bob", EUR(1000)));
env.close();
env(offer("bob", USD(2000), EUR(2000)));
env.require (balance("bob", USD(1204)));
env.require (balance("bob", EUR( 397)));
env.require (balance("alice", USD(800)));
env.require (balance("alice", EUR(602)));
env.require (offers("alice", 1));
env.require (owners("alice", 3));
env.require (balance("carol", USD(0)));
env.require (balance("carol", EUR(none)));
env.require (offers("carol", 100));
env.require (owners("carol", 101));
env.require (balance("evita", USD(999)));
env.require (balance("evita", EUR(1)));
env.require (offers("evita", 1000));
env.require (owners("evita", 1002));
// Dan offers to buy 900 EUR for 900 USD.
// 1. He removes all 100 of Carol's remaining unfunded offers.
// 2. Then takes 850 USD from Evita's offers.
// 3. Consuming 850 of Evita's funded offers hits the crossing
// limit. So Dan's offer crossing stops even though he would
// be willing to take another 50 of Evita's offers.
env.trust(EUR(10000), "dan");
env.close();
env(pay(gw, "dan", EUR(1000)));
env.close();
env(offer("dan", USD(900), EUR(900)));
env.require (balance("dan", USD(850)));
env.require (balance("dan", EUR(150)));
env.require (balance("alice", USD(800)));
env.require (balance("alice", EUR(602)));
env.require (offers("alice", 1));
env.require (owners("alice", 3));
env.require (balance("carol", USD(0)));
env.require (balance("carol", EUR(none)));
env.require (offers("carol", 0));
env.require (owners("carol", 1));
env.require (balance("evita", USD(149)));
env.require (balance("evita", EUR(851)));
env.require (offers("evita", 150));
env.require (owners("evita", 152));
}
void
run()
{
auto testAll = [this](std::initializer_list<uint256> fs) {
testStepLimit(fs);
testCrossingLimit(fs);
testStepAndCrossingLimit(fs);
auto testAll = [this](FeatureBitset features) {
testStepLimit(features);
testCrossingLimit(features);
testStepAndCrossingLimit(features);
testAutoBridgedLimits(features);
};
testAll({});
testAll({featureFlow});
testAll({featureFlow, fix1373});
testAll({featureFlow, fix1373, featureFlowCross});
using namespace jtx;
testAll(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testAll(
supported_features_except ( fix1373, featureFlowCross));
testAll(
supported_features_except ( featureFlowCross));
// testAll(supported_amendments());// Does not pass with FlowCross enabled.
}
};

View File

@@ -29,7 +29,7 @@ class DeliverMin_test : public beast::unit_test::suite
{
public:
void
test_convert_all_of_an_asset(std::initializer_list<uint256> fs)
test_convert_all_of_an_asset(FeatureBitset features)
{
testcase("Convert all of an asset using DeliverMin");
@@ -38,7 +38,7 @@ public:
auto const USD = gw["USD"];
{
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), "alice", "bob", "carol", gw);
env.trust(USD(100), "alice", "bob", "carol");
env(pay("alice", "bob", USD(10)), delivermin(USD(10)), ter(temBAD_AMOUNT));
@@ -61,7 +61,7 @@ public:
}
{
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), "alice", "bob", gw);
env.trust(USD(1000), "alice", "bob");
env(pay(gw, "bob", USD(100)));
@@ -73,7 +73,7 @@ public:
}
{
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), "alice", "bob", "carol", gw);
env.trust(USD(1000), "bob", "carol");
env(pay(gw, "bob", USD(200)));
@@ -91,7 +91,7 @@ public:
}
{
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), "alice", "bob", "carol", "dan", gw);
env.trust(USD(1000), "bob", "carol", "dan");
env(pay(gw, "bob", USD(100)));
@@ -111,11 +111,14 @@ public:
void
run()
{
test_convert_all_of_an_asset({});
test_convert_all_of_an_asset({featureFlow});
test_convert_all_of_an_asset({featureFlow, fix1373});
using namespace jtx;
test_convert_all_of_an_asset(
{featureFlow, fix1373, featureFlowCross});
supported_features_except (featureFlow, fix1373, featureFlowCross));
test_convert_all_of_an_asset(
supported_features_except ( fix1373, featureFlowCross));
test_convert_all_of_an_asset(
supported_features_except ( featureFlowCross));
test_convert_all_of_an_asset(supported_amendments());
}
};

View File

@@ -37,11 +37,11 @@ class Discrepancy_test : public beast::unit_test::suite
// A payment with path and sendmax is made and the transaction is queried
// to verify that the net of balance changes match the fee charged.
void
testXRPDiscrepancy (std::initializer_list<uint256> fs)
testXRPDiscrepancy (FeatureBitset features)
{
testcase ("Discrepancy test : XRP Discrepancy");
using namespace test::jtx;
Env env {*this, with_only_features(fs)};
Env env {*this, features};
Account A1 {"A1"};
Account A2 {"A2"};
@@ -144,10 +144,14 @@ class Discrepancy_test : public beast::unit_test::suite
public:
void run ()
{
testXRPDiscrepancy ({});
testXRPDiscrepancy ({featureFlow});
testXRPDiscrepancy ({featureFlow, fix1373});
testXRPDiscrepancy ({featureFlow, fix1373, featureFlowCross});
using namespace test::jtx;
testXRPDiscrepancy (
supported_features_except (featureFlow, fix1373, featureFlowCross));
testXRPDiscrepancy (
supported_features_except ( fix1373, featureFlowCross));
testXRPDiscrepancy (
supported_features_except ( featureFlowCross));
testXRPDiscrepancy (supported_amendments());
}
};

View File

@@ -207,7 +207,7 @@ struct Escrow_test : public beast::unit_test::suite
using namespace std::chrono;
{ // Escrow not enabled
Env env(*this, no_features);
Env env(*this, supported_features_except (featureEscrow));
env.fund(XRP(5000), "alice", "bob");
env(lockup("alice", "bob", XRP(1000), env.now() + 1s), ter(temDISABLED));
env(finish("bob", "alice", 1), ter(temDISABLED));
@@ -215,7 +215,7 @@ struct Escrow_test : public beast::unit_test::suite
}
{ // Escrow enabled
Env env(*this, with_only_features(featureEscrow));
Env env(*this);
env.fund(XRP(5000), "alice", "bob");
env(lockup("alice", "bob", XRP(1000), env.now() + 1s));
env.close();
@@ -237,7 +237,7 @@ struct Escrow_test : public beast::unit_test::suite
using namespace jtx;
using namespace std::chrono;
Env env(*this, with_only_features(featureEscrow));
Env env(*this);
auto const alice = Account("alice");
env.fund(XRP(5000), alice, "bob");
@@ -261,7 +261,7 @@ struct Escrow_test : public beast::unit_test::suite
using namespace jtx;
using namespace std::chrono;
Env env(*this, with_only_features(featureEscrow));
Env env(*this);
env.fund(XRP(5000), "alice", "bob");
env.close();
@@ -364,7 +364,7 @@ struct Escrow_test : public beast::unit_test::suite
using namespace std::chrono;
{ // Unconditional
Env env(*this, with_only_features(featureEscrow));
Env env(*this);
env.fund(XRP(5000), "alice", "bob");
auto const seq = env.seq("alice");
env(lockup("alice", "alice", XRP(1000), env.now() + 1s));
@@ -379,7 +379,7 @@ struct Escrow_test : public beast::unit_test::suite
}
{ // Conditional
Env env(*this, with_only_features(featureEscrow));
Env env(*this);
env.fund(XRP(5000), "alice", "bob");
auto const seq = env.seq("alice");
env(lockup("alice", "alice", XRP(1000), makeSlice(cb2), env.now() + 1s));
@@ -411,8 +411,7 @@ struct Escrow_test : public beast::unit_test::suite
using S = seconds;
{ // Test cryptoconditions
Env env(*this,
with_only_features(featureEscrow));
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
@@ -459,8 +458,7 @@ struct Escrow_test : public beast::unit_test::suite
}
{ // Test cancel when condition is present
Env env(*this,
with_only_features(featureEscrow));
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
@@ -477,7 +475,7 @@ struct Escrow_test : public beast::unit_test::suite
}
{
Env env(*this, with_only_features(featureEscrow));
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
@@ -497,7 +495,7 @@ struct Escrow_test : public beast::unit_test::suite
}
{ // Test long & short conditions during creation
Env env(*this, with_only_features(featureEscrow));
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
@@ -537,8 +535,7 @@ struct Escrow_test : public beast::unit_test::suite
}
{ // Test long and short conditions & fulfillments during finish
Env env(*this,
with_only_features(featureEscrow));
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
@@ -623,7 +620,7 @@ struct Escrow_test : public beast::unit_test::suite
{ // Test empty condition during creation and
// empty condition & fulfillment during finish
Env env(*this, with_only_features(featureEscrow));
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
@@ -663,7 +660,7 @@ struct Escrow_test : public beast::unit_test::suite
{ // Test a condition other than PreimageSha256, which
// would require a separate amendment
Env env(*this, with_only_features(featureEscrow));
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
@@ -696,7 +693,7 @@ struct Escrow_test : public beast::unit_test::suite
{
testcase ("Metadata & Ownership (without fix1523)");
Env env(*this, with_only_features(featureEscrow));
Env env(*this, supported_features_except (fix1523));
env.fund(XRP(5000), alice, bruce, carol);
auto const seq = env.seq(alice);
@@ -718,7 +715,7 @@ struct Escrow_test : public beast::unit_test::suite
{
testcase ("Metadata (with fix1523, to self)");
Env env(*this, with_only_features(featureEscrow, fix1523));
Env env(*this);
env.fund(XRP(5000), alice, bruce, carol);
auto const aseq = env.seq(alice);
auto const bseq = env.seq(bruce);
@@ -777,7 +774,7 @@ struct Escrow_test : public beast::unit_test::suite
{
testcase ("Metadata (with fix1523, to other)");
Env env(*this, with_only_features(featureEscrow, fix1523));
Env env(*this);
env.fund(XRP(5000), alice, bruce, carol);
auto const aseq = env.seq(alice);
auto const bseq = env.seq(bruce);
@@ -856,7 +853,7 @@ struct Escrow_test : public beast::unit_test::suite
using namespace jtx;
using namespace std::chrono;
Env env(*this, with_only_features(featureEscrow));
Env env(*this);
env.memoize("alice");
env.memoize("bob");

View File

@@ -56,15 +56,7 @@ xrpMinusFee (jtx::Env const& env, std::int64_t xrpAmount)
struct Flow_test : public beast::unit_test::suite
{
static bool hasFeature(uint256 const& feat, std::initializer_list<uint256> args)
{
for(auto const& f : args)
if (f == feat)
return true;
return false;
}
void testDirectStep (std::initializer_list<uint256> fs)
void testDirectStep (FeatureBitset features)
{
testcase ("Direct Step");
@@ -82,7 +74,7 @@ struct Flow_test : public beast::unit_test::suite
auto const USD = gw["USD"];
{
// Pay USD, trivial path
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, gw);
env.trust (USD (1000), alice, bob);
@@ -92,7 +84,7 @@ struct Flow_test : public beast::unit_test::suite
}
{
// XRP transfer
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob);
env (pay (alice, bob, XRP (100)));
@@ -101,7 +93,7 @@ struct Flow_test : public beast::unit_test::suite
}
{
// Partial payments
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, gw);
env.trust (USD (1000), alice, bob);
@@ -115,7 +107,7 @@ struct Flow_test : public beast::unit_test::suite
}
{
// Pay by rippling through accounts, use path finder
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, carol, dan);
env.trust (USDA (10), bob);
@@ -130,7 +122,7 @@ struct Flow_test : public beast::unit_test::suite
{
// Pay by rippling through accounts, specify path
// and charge a transfer fee
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, carol, dan);
env.trust (USDA (10), bob);
@@ -148,7 +140,7 @@ struct Flow_test : public beast::unit_test::suite
{
// Pay by rippling through accounts, specify path and transfer fee
// Test that the transfer fee is not charged when alice issues
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, carol, dan);
env.trust (USDA (10), bob);
@@ -164,7 +156,7 @@ struct Flow_test : public beast::unit_test::suite
{
// test best quality path is taken
// Paths: A->B->D->E ; A->C->D->E
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, carol, dan, erin);
env.trust (USDA (10), bob, carol);
@@ -185,7 +177,7 @@ struct Flow_test : public beast::unit_test::suite
}
{
// Limit quality
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, carol);
env.trust (USDA (10), bob);
@@ -201,7 +193,7 @@ struct Flow_test : public beast::unit_test::suite
}
}
void testLineQuality (std::initializer_list<uint256> fs)
void testLineQuality (FeatureBitset features)
{
testcase ("Line Quality");
@@ -219,10 +211,10 @@ struct Flow_test : public beast::unit_test::suite
for (auto bobDanQIn : {80, 100, 120})
for (auto bobAliceQOut : {80, 100, 120})
{
if (!hasFeature(featureFlow, fs) && bobDanQIn < 100 &&
if (!hasFeature(featureFlow, features) && bobDanQIn < 100 &&
bobAliceQOut < 100)
continue; // Bug in flow v1
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, carol, dan);
env(trust(bob, USDD(100)), qualityInPercent(bobDanQIn));
env(trust(bob, USDA(100)), qualityOutPercent(bobAliceQOut));
@@ -245,7 +237,7 @@ struct Flow_test : public beast::unit_test::suite
// bob -> alice -> carol; vary carolAliceQIn
for (auto carolAliceQIn : {80, 100, 120})
{
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, carol);
env(trust(bob, USDA(10)));
env(trust(carol, USDA(10)), qualityInPercent(carolAliceQIn));
@@ -261,7 +253,7 @@ struct Flow_test : public beast::unit_test::suite
// bob -> alice -> carol; bobAliceQOut varies.
for (auto bobAliceQOut : {80, 100, 120})
{
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, carol);
env(trust(bob, USDA(10)), qualityOutPercent(bobAliceQOut));
env(trust(carol, USDA(10)));
@@ -274,7 +266,7 @@ struct Flow_test : public beast::unit_test::suite
}
}
void testBookStep (std::initializer_list<uint256> fs)
void testBookStep (FeatureBitset features)
{
testcase ("Book Step");
@@ -290,7 +282,7 @@ struct Flow_test : public beast::unit_test::suite
{
// simple IOU/IOU offer
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, carol, gw);
env.trust (USD (1000), alice, bob, carol);
@@ -311,7 +303,7 @@ struct Flow_test : public beast::unit_test::suite
}
{
// simple IOU/XRP XRP/IOU offer
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, carol, gw);
env.trust (USD (1000), alice, bob, carol);
@@ -335,7 +327,7 @@ struct Flow_test : public beast::unit_test::suite
}
{
// simple XRP -> USD through offer and sendmax
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, carol, gw);
env.trust (USD (1000), alice, bob, carol);
@@ -356,7 +348,7 @@ struct Flow_test : public beast::unit_test::suite
}
{
// simple USD -> XRP through offer and sendmax
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, carol, gw);
env.trust (USD (1000), alice, bob, carol);
@@ -377,7 +369,7 @@ struct Flow_test : public beast::unit_test::suite
}
{
// test unfunded offers are removed when payment succeeds
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, carol, gw);
env.trust (USD (1000), alice, bob, carol);
@@ -423,7 +415,7 @@ struct Flow_test : public beast::unit_test::suite
// offer. When the payment fails `flow` should return the unfunded
// offer. This test is intentionally similar to the one that removes
// unfunded offers when the payment succeeds.
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, carol, gw);
env.trust (USD (1000), alice, bob, carol);
@@ -498,7 +490,7 @@ struct Flow_test : public beast::unit_test::suite
// Without limits, the 0.4 USD would produce 1000 EUR in the forward
// pass. This test checks that the payment produces 1 EUR, as expected.
Env env (*this, with_only_features (fs));
Env env (*this, features);
auto const closeTime = STAmountSO::soTime2 +
100 * env.closed ()->info ().closeTimeResolution;
@@ -523,7 +515,7 @@ struct Flow_test : public beast::unit_test::suite
}
}
void testTransferRate (std::initializer_list<uint256> fs)
void testTransferRate (FeatureBitset features)
{
testcase ("Transfer Rate");
@@ -541,7 +533,7 @@ struct Flow_test : public beast::unit_test::suite
{
// Simple payment through a gateway with a
// transfer rate
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, carol, gw);
env(rate(gw, 1.25));
@@ -553,7 +545,7 @@ struct Flow_test : public beast::unit_test::suite
}
{
// transfer rate is not charged when issuer is src or dst
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, carol, gw);
env(rate(gw, 1.25));
@@ -565,7 +557,7 @@ struct Flow_test : public beast::unit_test::suite
}
{
// transfer fee on an offer
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, carol, gw);
env(rate(gw, 1.25));
@@ -583,7 +575,7 @@ struct Flow_test : public beast::unit_test::suite
{
// Transfer fee two consecutive offers
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, carol, gw);
env(rate(gw, 1.25));
@@ -606,7 +598,7 @@ struct Flow_test : public beast::unit_test::suite
{
// First pass through a strand redeems, second pass issues, no offers
// limiting step is not an endpoint
Env env (*this, with_only_features(fs));
Env env (*this, features);
auto const USDA = alice["USD"];
auto const USDB = bob["USD"];
@@ -626,7 +618,7 @@ struct Flow_test : public beast::unit_test::suite
{
// First pass through a strand redeems, second pass issues, through an offer
// limiting step is not an endpoint
Env env (*this, with_only_features(fs));
Env env (*this, features);
auto const USDA = alice["USD"];
auto const USDB = bob["USD"];
Account const dan ("dan");
@@ -653,7 +645,7 @@ struct Flow_test : public beast::unit_test::suite
{
// Offer where the owner is also the issuer, owner pays fee
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, gw);
env(rate(gw, 1.25));
@@ -665,10 +657,10 @@ struct Flow_test : public beast::unit_test::suite
balance (alice, xrpMinusFee(env, 10000-100)),
balance (bob, USD (100)));
}
if (!hasFeature(featureOwnerPaysFee, fs))
if (!hasFeature(featureOwnerPaysFee, features))
{
// Offer where the owner is also the issuer, sender pays fee
Env env (*this, with_only_features(fs));
Env env (*this, features);
env.fund (XRP (10000), alice, bob, gw);
env(rate(gw, 1.25));
@@ -683,7 +675,7 @@ struct Flow_test : public beast::unit_test::suite
}
void
testFalseDry(std::initializer_list<uint256> fs)
testFalseDry(FeatureBitset features)
{
testcase ("falseDryChanges");
@@ -696,7 +688,7 @@ struct Flow_test : public beast::unit_test::suite
Account const bob ("bob");
Account const carol ("carol");
Env env (*this, with_only_features (fs));
Env env (*this, features);
auto const closeTime = fix1141Time() +
100 * env.closed ()->info ().closeTimeResolution;
@@ -793,7 +785,7 @@ struct Flow_test : public beast::unit_test::suite
}
void
testSelfPayment1(std::initializer_list<uint256> fs)
testSelfPayment1(FeatureBitset features)
{
testcase ("Self-payment 1");
@@ -810,7 +802,7 @@ struct Flow_test : public beast::unit_test::suite
auto const USD = gw1["USD"];
auto const EUR = gw2["EUR"];
Env env (*this, with_only_features (fs));
Env env (*this, features);
auto const closeTime =
fix1141Time () + 100 * env.closed ()->info ().closeTimeResolution;
@@ -869,7 +861,7 @@ struct Flow_test : public beast::unit_test::suite
}
void
testSelfPayment2(std::initializer_list<uint256> fs)
testSelfPayment2(FeatureBitset features)
{
testcase ("Self-payment 2");
@@ -884,7 +876,7 @@ struct Flow_test : public beast::unit_test::suite
auto const USD = gw1["USD"];
auto const EUR = gw2["EUR"];
Env env (*this, with_only_features (fs));
Env env (*this, features);
auto const closeTime =
fix1141Time () + 100 * env.closed ()->info ().closeTimeResolution;
@@ -941,7 +933,7 @@ struct Flow_test : public beast::unit_test::suite
BEAST_EXPECT(offer[sfTakerPays] == USD (495));
}
}
void testSelfFundedXRPEndpoint (bool consumeOffer, std::initializer_list<uint256> fs)
void testSelfFundedXRPEndpoint (bool consumeOffer, FeatureBitset features)
{
// Test that the deferred credit table is not bypassed for
// XRPEndpointSteps. If the account in the first step is sending XRP and
@@ -952,7 +944,7 @@ struct Flow_test : public beast::unit_test::suite
using namespace jtx;
Env env(*this, with_only_features(fs));
Env env(*this, features);
// Need new behavior from `accountHolds`
auto const closeTime = fix1141Time() +
@@ -975,7 +967,7 @@ struct Flow_test : public beast::unit_test::suite
txflags(tfPartialPayment | tfNoRippleDirect));
}
void testUnfundedOffer (bool withFix, std::initializer_list<uint256> fs)
void testUnfundedOffer (bool withFix, FeatureBitset features)
{
testcase(std::string("Unfunded Offer ") +
(withFix ? "with fix" : "without fix"));
@@ -983,7 +975,7 @@ struct Flow_test : public beast::unit_test::suite
using namespace jtx;
{
// Test reverse
Env env(*this, with_only_features(fs));
Env env(*this, features);
auto closeTime = fix1298Time();
if (withFix)
closeTime += env.closed()->info().closeTimeResolution;
@@ -1015,7 +1007,7 @@ struct Flow_test : public beast::unit_test::suite
}
{
// Test forward
Env env(*this, with_only_features(fs));
Env env(*this, features);
auto closeTime = fix1298Time();
if (withFix)
closeTime += env.closed()->info().closeTimeResolution;
@@ -1050,12 +1042,12 @@ struct Flow_test : public beast::unit_test::suite
}
void
testReexecuteDirectStep(std::initializer_list<uint256> fs)
testReexecuteDirectStep(FeatureBitset features)
{
testcase("ReexecuteDirectStep");
using namespace jtx;
Env env(*this, with_only_features(fs));
Env env(*this, features);
auto const alice = Account("alice");
auto const bob = Account("bob");
@@ -1111,7 +1103,7 @@ struct Flow_test : public beast::unit_test::suite
testcase("ripd1443");
using namespace jtx;
Env env(*this, with_only_features(featureFlow));
Env env(*this);
auto const timeDelta = env.closed ()->info ().closeTimeResolution;
auto const d = withFix ? 100*timeDelta : -100*timeDelta;
auto closeTime = fix1443Time() + d;
@@ -1164,7 +1156,7 @@ struct Flow_test : public beast::unit_test::suite
testcase("ripd1449");
using namespace jtx;
Env env(*this, with_only_features(featureFlow));
Env env(*this);
auto const timeDelta = env.closed ()->info ().closeTimeResolution;
auto const d = withFix ? 100*timeDelta : -100*timeDelta;
auto closeTime = fix1449Time() + d;
@@ -1201,7 +1193,7 @@ struct Flow_test : public beast::unit_test::suite
}
void
testSelfPayLowQualityOffer (std::initializer_list<uint256> fs)
testSelfPayLowQualityOffer (FeatureBitset features)
{
// The new payment code used to assert if an offer was made for more
// XRP than the offering account held. This unit test reproduces
@@ -1210,7 +1202,7 @@ struct Flow_test : public beast::unit_test::suite
using namespace jtx;
Env env(*this, with_only_features (fs));
Env env(*this, features);
auto const ann = Account("ann");
auto const gw = Account("gateway");
@@ -1237,14 +1229,14 @@ struct Flow_test : public beast::unit_test::suite
}
void
testEmptyStrand(std::initializer_list<uint256> fs)
testEmptyStrand(FeatureBitset features)
{
testcase("Empty Strand");
using namespace jtx;
auto const alice = Account("alice");
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice);
@@ -1254,32 +1246,30 @@ struct Flow_test : public beast::unit_test::suite
ter(temBAD_PATH));
}
template<class... T>
void testWithFeats(bool haveFlow, T&&... fs)
void testWithFeats(FeatureBitset features)
{
testLineQuality({ fs... });
testFalseDry({ fs... });
if (!haveFlow)
return;
testDirectStep({ fs... });
testBookStep({ fs... });
testDirectStep({ featureOwnerPaysFee, fs... });
testBookStep({ featureOwnerPaysFee, fs... });
testTransferRate({ featureOwnerPaysFee, fs... });
testSelfPayment1({ fs... });
testSelfPayment2({ fs... });
testSelfFundedXRPEndpoint(false, { fs... });
testSelfFundedXRPEndpoint(true, { fs... });
testUnfundedOffer(true, { fs... });
testUnfundedOffer(false, { fs... });
testReexecuteDirectStep({ fix1368, fs... });
testSelfPayLowQualityOffer({ fs... });
}
using namespace jtx;
FeatureBitset const ownerPaysFee
{with_only_features (featureOwnerPaysFee)};
template<class... T>
void testWithFeats(T&&... fs)
{
testWithFeats(!!sizeof...(fs), fs...);
testLineQuality(features);
testFalseDry(features);
// Only do the rest of the tests if featureFlow is enabled.
if (! hasFeature (featureFlow, features))
return;
testDirectStep(features);
testBookStep(features);
testDirectStep(features | ownerPaysFee);
testBookStep(features | ownerPaysFee);
testTransferRate(features | ownerPaysFee);
testSelfPayment1(features);
testSelfPayment2(features);
testSelfFundedXRPEndpoint(false, features);
testSelfFundedXRPEndpoint(true, features);
testUnfundedOffer(true, features);
testUnfundedOffer(false, features);
testReexecuteDirectStep(features | with_only_features (fix1368));
testSelfPayLowQualityOffer(features);
}
void run() override
@@ -1290,13 +1280,16 @@ struct Flow_test : public beast::unit_test::suite
testRIPD1449(true);
testRIPD1449(false);
testWithFeats(false, featureFeeEscalation, fix1513);
testWithFeats(featureFlow, featureFeeEscalation, fix1513);
testWithFeats(featureFlow, fix1373, featureFeeEscalation, fix1513);
testWithFeats(featureFlow, fix1373, featureFlowCross,
featureFeeEscalation, fix1513);
testEmptyStrand({featureFlow, fix1373, featureFlowCross,
featureFeeEscalation, fix1513 });
using namespace jtx;
testWithFeats(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testWithFeats(
supported_features_except ( fix1373, featureFlowCross));
testWithFeats(
supported_features_except ( featureFlowCross));
testWithFeats(supported_amendments());
testEmptyStrand(supported_amendments());
}
};
@@ -1304,31 +1297,30 @@ struct Flow_manual_test : public Flow_test
{
void run() override
{
testWithFeats();
testWithFeats(false,
featureFeeEscalation);
testWithFeats(false,
featureFeeEscalation, fix1513);
testWithFeats(featureFlow);
testWithFeats(featureFlow,
featureFeeEscalation);
testWithFeats(featureFlow,
featureFeeEscalation, fix1513);
testWithFeats(featureFlow, fix1373);
testWithFeats(featureFlow, fix1373,
featureFeeEscalation);
testWithFeats(featureFlow, fix1373,
featureFeeEscalation, fix1513);
testWithFeats(featureFlow, fix1373, featureFlowCross);
testWithFeats(featureFlow, fix1373, featureFlowCross,
featureFeeEscalation);
testWithFeats(featureFlow, fix1373, featureFlowCross,
featureFeeEscalation, fix1513);
testEmptyStrand({ featureFlow, fix1373, featureFlowCross });
testEmptyStrand({ featureFlow, fix1373, featureFlowCross,
featureFeeEscalation });
testEmptyStrand({ featureFlow, fix1373, featureFlowCross,
featureFeeEscalation, fix1513 });
using namespace jtx;
auto const all = supported_amendments();
auto const feeEscalation = with_only_features (featureFeeEscalation);
auto const flow = with_only_features (featureFlow);
auto const f1373 = with_only_features (fix1373);
auto const flowCross = with_only_features (featureFlowCross);
auto const f1513 = with_only_features (fix1513);
testWithFeats(all & ~(feeEscalation | flow | f1373 | flowCross | f1513));
testWithFeats(all & ~( flow | f1373 | flowCross | f1513));
testWithFeats(all & ~( flow | f1373 | flowCross ));
testWithFeats(all & ~(feeEscalation | f1373 | flowCross | f1513));
testWithFeats(all & ~( f1373 | flowCross | f1513));
testWithFeats(all & ~( f1373 | flowCross ));
testWithFeats(all & ~(feeEscalation | flowCross | f1513));
testWithFeats(all & ~( flowCross | f1513));
testWithFeats(all & ~( flowCross ));
testWithFeats(all & ~(feeEscalation | f1513));
testWithFeats(all & ~( f1513));
testWithFeats(all );
testEmptyStrand(all & ~(feeEscalation | f1513));
testEmptyStrand(all & ~( f1513));
testEmptyStrand(all );
}
};

View File

@@ -53,12 +53,12 @@ class Freeze_test : public beast::unit_test::suite
return val.isArray() && val.size() == size;
}
void testRippleState(std::initializer_list<uint256> fs)
void testRippleState(FeatureBitset features)
{
testcase("RippleState Freeze");
using namespace test::jtx;
Env env(*this, with_only_features(fs));
Env env(*this, features);
Account G1 {"G1"};
Account alice {"alice"};
@@ -207,12 +207,12 @@ class Freeze_test : public beast::unit_test::suite
}
void
testGlobalFreeze(std::initializer_list<uint256> fs)
testGlobalFreeze(FeatureBitset features)
{
testcase("Global Freeze");
using namespace test::jtx;
Env env(*this, with_only_features(fs));
Env env(*this, features);
Account G1 {"G1"};
Account A1 {"A1"};
@@ -365,12 +365,12 @@ class Freeze_test : public beast::unit_test::suite
}
void
testNoFreeze(std::initializer_list<uint256> fs)
testNoFreeze(FeatureBitset features)
{
testcase("No Freeze");
using namespace test::jtx;
Env env(*this, with_only_features(fs));
Env env(*this, features);
Account G1 {"G1"};
Account A1 {"A1"};
@@ -419,12 +419,12 @@ class Freeze_test : public beast::unit_test::suite
}
void
testOffersWhenFrozen(std::initializer_list<uint256> fs)
testOffersWhenFrozen(FeatureBitset features)
{
testcase("Offers for Frozen Trust Lines");
using namespace test::jtx;
Env env(*this, with_only_features(fs));
Env env(*this, features);
Account G1 {"G1"};
Account A2 {"A2"};
@@ -523,21 +523,23 @@ public:
void run()
{
auto testAll = [this](std::initializer_list<uint256> fs)
auto testAll = [this](FeatureBitset features)
{
testRippleState(fs);
testGlobalFreeze(fs);
testNoFreeze(fs);
testOffersWhenFrozen(fs);
testRippleState(features);
testGlobalFreeze(features);
testNoFreeze(features);
testOffersWhenFrozen(features);
};
testAll({});
testAll({featureFlow});
testAll({featureFlow, fix1373});
testAll({featureFlow, fix1373, featureFlowCross});
using namespace test::jtx;
testAll(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testAll(
supported_features_except ( fix1373, featureFlowCross));
testAll(
supported_features_except ( featureFlowCross));
testAll(supported_amendments());
}
};
BEAST_DEFINE_TESTSUITE(Freeze, app, ripple);
} // ripple

View File

@@ -39,7 +39,7 @@ public:
void test_noReserve()
{
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
Account const alice {"alice", KeyType::secp256k1};
// Pay alice enough to meet the initial reserve, but not enough to
@@ -87,7 +87,7 @@ public:
void test_signerListSet()
{
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
Account const alice {"alice", KeyType::ed25519};
env.fund(XRP(1000), alice);
@@ -132,7 +132,7 @@ public:
void test_phantomSigners()
{
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
Account const alice {"alice", KeyType::ed25519};
env.fund(XRP(1000), alice);
env.close();
@@ -233,7 +233,7 @@ public:
void test_fee ()
{
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
Account const alice {"alice", KeyType::ed25519};
env.fund(XRP(1000), alice);
env.close();
@@ -283,7 +283,7 @@ public:
void test_misorderedSigners()
{
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
Account const alice {"alice", KeyType::ed25519};
env.fund(XRP(1000), alice);
env.close();
@@ -305,7 +305,7 @@ public:
void test_masterSigners()
{
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
Account const alice {"alice", KeyType::ed25519};
Account const becky {"becky", KeyType::secp256k1};
Account const cheri {"cheri", KeyType::ed25519};
@@ -357,7 +357,7 @@ public:
void test_regularSigners()
{
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
Account const alice {"alice", KeyType::secp256k1};
Account const becky {"becky", KeyType::ed25519};
Account const cheri {"cheri", KeyType::secp256k1};
@@ -415,7 +415,7 @@ public:
void test_regularSignersUsingSubmitMulti()
{
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
Account const alice {"alice", KeyType::secp256k1};
Account const becky {"becky", KeyType::ed25519};
Account const cheri {"cheri", KeyType::secp256k1};
@@ -618,7 +618,7 @@ public:
void test_heterogeneousSigners()
{
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
Account const alice {"alice", KeyType::secp256k1};
Account const becky {"becky", KeyType::ed25519};
Account const cheri {"cheri", KeyType::secp256k1};
@@ -733,7 +733,7 @@ public:
void test_keyDisable()
{
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
Account const alice {"alice", KeyType::ed25519};
env.fund(XRP(1000), alice);
@@ -808,7 +808,7 @@ public:
void test_regKey()
{
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
Account const alice {"alice", KeyType::secp256k1};
env.fund(XRP(1000), alice);
@@ -840,7 +840,7 @@ public:
void test_txTypes()
{
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
Account const alice {"alice", KeyType::secp256k1};
Account const becky {"becky", KeyType::ed25519};
Account const zelda {"zelda", KeyType::secp256k1};
@@ -924,7 +924,7 @@ public:
// Verify that the text returned for signature failures is correct.
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
// lambda that submits an STTx and returns the resulting JSON.
auto submitSTTx = [&env] (STTx const& stx)
@@ -1058,7 +1058,7 @@ public:
void test_noMultiSigners()
{
using namespace jtx;
Env env {*this, with_only_features(featureMultiSign)};
Env env {*this};
Account const alice {"alice", KeyType::ed25519};
Account const becky {"becky", KeyType::secp256k1};
env.fund(XRP(1000), alice, becky);

File diff suppressed because it is too large Load Diff

View File

@@ -35,7 +35,10 @@ public:
{
using namespace jtx;
for (std::size_t i = 1; i <= n; ++i)
{
env(offer("alice", XRP(i), iou(1)));
env.close();
}
}
void
@@ -47,8 +50,8 @@ public:
env.disable_sigs();
auto const gw = Account("gateway");
auto const USD = gw["USD"];
env.fund(XRP(billion), gw, "alice", "bob", "carol");
env.trust(USD(billion), "alice", "bob", "carol");
env.fund(XRP(billion), gw, "alice");
env.trust(USD(billion), "alice");
env(pay(gw, "alice", USD(billion)));
createOffers(env, USD, n);
}
@@ -88,7 +91,10 @@ public:
{
using namespace jtx;
for (std::size_t i = 1; i <= n; ++i)
{
env(offer("alice", XRP(1), iou(1)));
env.close();
}
}
void
@@ -101,8 +107,8 @@ public:
env.disable_sigs();
auto const gw = Account("gateway");
auto const USD = gw["USD"];
env.fund(XRP(billion), gw, "alice", "bob", "carol");
env.trust(USD(billion), "alice", "bob", "carol");
env.fund(XRP(billion), gw, "alice");
env.trust(USD(billion), "alice");
env(pay(gw, "alice", USD(billion)));
createOffers(env, USD, n);
env(pay("alice", gw, USD(billion)));
@@ -151,7 +157,10 @@ public:
{
using namespace jtx;
for (std::size_t i = 1; i <= n; ++i)
{
env(offer("alice", XRP(i), iou(1)));
env.close();
}
}
bool
@@ -163,8 +172,8 @@ public:
env.disable_sigs();
auto const gw = Account("gateway");
auto const USD = gw["USD"];
env.fund(XRP(billion), gw, "alice", "bob", "carol");
env.trust(USD(billion), "alice", "bob", "carol");
env.fund(XRP(billion), gw, "alice");
env.trust(USD(billion), "alice");
env(pay(gw, "alice", USD(billion)));
createOffers(env, USD, n);
env(pay("alice", gw, USD(billion)));

View File

@@ -625,14 +625,14 @@ struct PayStrandAllPairs_test : public beast::unit_test::suite
{
// Test every combination of element type pairs on a path
void
testAllPairs(std::initializer_list<uint256> fs)
testAllPairs(FeatureBitset features)
{
testcase("All pairs");
using namespace jtx;
using RippleCalc = ::ripple::path::RippleCalc;
ExistingElementPool eep;
Env env(*this, with_only_features(fs));
Env env(*this, features);
auto const closeTime = fix1298Time() +
100 * env.closed()->info().closeTimeResolution;
@@ -847,8 +847,8 @@ struct PayStrandAllPairs_test : public beast::unit_test::suite
void
run() override
{
testAllPairs({featureFlow, fix1373});
testAllPairs({featureFlow, fix1373, featureFlowCross});
testAllPairs(jtx::supported_features_except (featureFlowCross));
testAllPairs(jtx::supported_amendments());
}
};
@@ -856,15 +856,8 @@ BEAST_DEFINE_TESTSUITE_MANUAL(PayStrandAllPairs, app, ripple);
struct PayStrand_test : public beast::unit_test::suite
{
static bool hasFeature(uint256 const& feat, std::initializer_list<uint256> args)
{
for(auto const& f : args)
if (f == feat)
return true;
return false;
}
void
testToStrand(std::initializer_list<uint256> fs)
testToStrand(FeatureBitset features)
{
testcase("To Strand");
@@ -910,7 +903,7 @@ struct PayStrand_test : public beast::unit_test::suite
};
{
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, gw);
env.trust(USD(1000), alice, bob);
env.trust(EUR(1000), alice, bob);
@@ -951,7 +944,7 @@ struct PayStrand_test : public beast::unit_test::suite
};
{
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, carol, gw);
test(env, USD, boost::none, STPath(), terNO_LINE);
@@ -1134,7 +1127,7 @@ struct PayStrand_test : public beast::unit_test::suite
// cannot have more than one offer with the same output issue
using namespace jtx;
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, carol, gw);
env.trust(USD(10000), alice, bob, carol);
@@ -1156,7 +1149,7 @@ struct PayStrand_test : public beast::unit_test::suite
}
{
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, noripple(gw));
env.trust(USD(1000), alice, bob);
env(pay(gw, alice, USD(100)));
@@ -1165,7 +1158,7 @@ struct PayStrand_test : public beast::unit_test::suite
{
// check global freeze
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, gw);
env.trust(USD(1000), alice, bob);
env(pay(gw, alice, USD(100)));
@@ -1190,7 +1183,7 @@ struct PayStrand_test : public beast::unit_test::suite
}
{
// Freeze between gw and alice
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, gw);
env.trust(USD(1000), alice, bob);
env(pay(gw, alice, USD(100)));
@@ -1203,7 +1196,7 @@ struct PayStrand_test : public beast::unit_test::suite
// check no auth
// An account may require authorization to receive IOUs from an
// issuer
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, gw);
env(fset(gw, asfRequireAuth));
env.trust(USD(1000), alice, bob);
@@ -1231,7 +1224,7 @@ struct PayStrand_test : public beast::unit_test::suite
}
{
// Check path with sendMax and node with correct sendMax already set
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, gw);
env.trust(USD(1000), alice, bob);
env.trust(EUR(1000), alice, bob);
@@ -1246,7 +1239,7 @@ struct PayStrand_test : public beast::unit_test::suite
{
// last step xrp from offer
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, gw);
env.trust(USD(1000), alice, bob);
env(pay(gw, alice, USD(100)));
@@ -1273,7 +1266,7 @@ struct PayStrand_test : public beast::unit_test::suite
}
void
testRIPD1373(std::initializer_list<uint256> fs)
testRIPD1373(FeatureBitset features)
{
using namespace jtx;
testcase("RIPD1373");
@@ -1285,9 +1278,9 @@ struct PayStrand_test : public beast::unit_test::suite
auto const USD = gw["USD"];
auto const EUR = gw["EUR"];
if (hasFeature(fix1373, fs))
if (hasFeature(fix1373, features))
{
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, gw);
env.trust(USD(1000), alice, bob);
@@ -1319,7 +1312,7 @@ struct PayStrand_test : public beast::unit_test::suite
}
{
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, carol, gw);
env.trust(USD(10000), alice, bob, carol);
@@ -1337,7 +1330,7 @@ struct PayStrand_test : public beast::unit_test::suite
}
{
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, carol, gw);
env.trust(USD(10000), alice, bob, carol);
@@ -1357,7 +1350,7 @@ struct PayStrand_test : public beast::unit_test::suite
}
void
testLoop(std::initializer_list<uint256> fs)
testLoop(FeatureBitset features)
{
testcase("test loop");
using namespace jtx;
@@ -1371,7 +1364,7 @@ struct PayStrand_test : public beast::unit_test::suite
auto const CNY = gw["CNY"];
{
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, carol, gw);
env.trust(USD(10000), alice, bob, carol);
@@ -1383,8 +1376,8 @@ struct PayStrand_test : public beast::unit_test::suite
env(offer(bob, USD(100), XRP(100)), txflags(tfPassive));
auto const expectedResult = [&] {
if (hasFeature(featureFlow, fs) &&
!hasFeature(fix1373, fs))
if (hasFeature(featureFlow, features) &&
!hasFeature(fix1373, features))
return tesSUCCESS;
return temBAD_PATH_LOOP;
}();
@@ -1396,7 +1389,7 @@ struct PayStrand_test : public beast::unit_test::suite
ter(expectedResult));
}
{
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, carol, gw);
env.trust(USD(10000), alice, bob, carol);
@@ -1421,7 +1414,7 @@ struct PayStrand_test : public beast::unit_test::suite
}
void
testNoAccount(std::initializer_list<uint256> fs)
testNoAccount(FeatureBitset features)
{
testcase("test no account");
using namespace jtx;
@@ -1431,7 +1424,7 @@ struct PayStrand_test : public beast::unit_test::suite
auto const gw = Account("gw");
auto const USD = gw["USD"];
Env env(*this, with_only_features(fs));
Env env(*this, features);
env.fund(XRP(10000), alice, bob, gw);
STAmount sendMax{USD.issue(), 100, 1};
@@ -1479,17 +1472,26 @@ struct PayStrand_test : public beast::unit_test::suite
void
run() override
{
testToStrand({featureFlow});
testToStrand({featureFlow, fix1373});
testToStrand({featureFlow, fix1373, featureFlowCross});
testRIPD1373({});
testRIPD1373({featureFlow, fix1373});
testRIPD1373({featureFlow, fix1373, featureFlowCross});
testLoop({});
testLoop({featureFlow});
testLoop({featureFlow, fix1373});
testLoop({featureFlow, fix1373, featureFlowCross});
testNoAccount({featureFlow, fix1373});
using namespace jtx;
testToStrand(supported_features_except (fix1373, featureFlowCross));
testToStrand(supported_features_except ( featureFlowCross));
testToStrand(supported_amendments ());
testRIPD1373(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testRIPD1373(
supported_features_except ( featureFlowCross));
testRIPD1373(supported_amendments ());
testLoop(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testLoop(
supported_features_except ( fix1373, featureFlowCross));
testLoop(
supported_features_except ( featureFlowCross));
testLoop(supported_amendments ());
testNoAccount(supported_amendments ());
}
};

View File

@@ -170,8 +170,7 @@ struct Regression_test : public beast::unit_test::suite
cfg->section("transaction_queue")
.set("minimum_txn_in_ledger_standalone", "3");
return cfg;
}),
with_features(featureFeeEscalation, fix1513));
}));
Env_ss envs(env);
auto const alice = Account("alice");

View File

@@ -46,19 +46,23 @@ struct SetAuth_test : public beast::unit_test::suite
return jv;
}
void testAuth(std::initializer_list<uint256> fs)
void testAuth(FeatureBitset features)
{
// featureTrustSetAuth should always be set by the caller.
BEAST_EXPECT (hasFeature (featureTrustSetAuth, features));
using namespace jtx;
auto const gw = Account("gw");
auto const USD = gw["USD"];
{
Env env(*this, with_only_features(fs));
Env env(*this, features & ~with_only_features(featureTrustSetAuth));
env.fund(XRP(100000), "alice", gw);
env(fset(gw, asfRequireAuth));
env(auth(gw, "alice", "USD"), ter(tecNO_LINE_REDUNDANT));
}
{
Env env(*this, with_only_features(featureTrustSetAuth));
Env env(*this, features);
env.fund(XRP(100000), "alice", "bob", gw);
env(fset(gw, asfRequireAuth));
env(auth(gw, "alice", "USD"));
@@ -75,10 +79,14 @@ struct SetAuth_test : public beast::unit_test::suite
void run() override
{
testAuth({});
testAuth({featureFlow});
testAuth({featureFlow, fix1373});
testAuth({featureFlow, fix1373, featureFlowCross});
using namespace jtx;
testAuth(supported_features_except (
featureFlow, fix1373, featureFlowCross));
testAuth(supported_features_except (
fix1373, featureFlowCross));
testAuth(supported_features_except (
featureFlowCross));
testAuth(supported_amendments());
}
};

View File

@@ -126,7 +126,7 @@ class Ticket_test : public beast::unit_test::suite
testcase ("Cancel Nonexistent");
using namespace test::jtx;
Env env {*this, with_only_features (featureTickets)};
Env env {*this, supported_features_plus (featureTickets)};
env (ticket::cancel (env.master, idOne), ter (tecNO_ENTRY));
}
@@ -135,7 +135,7 @@ class Ticket_test : public beast::unit_test::suite
testcase ("Create/Cancel Ticket with Bad Fee, Fail Preflight");
using namespace test::jtx;
Env env {*this, with_only_features (featureTickets)};
Env env {*this, supported_features_plus (featureTickets)};
env (ticket::create (env.master), fee (XRP (-1)), ter (temBAD_FEE));
env (ticket::cancel (env.master, idOne), fee (XRP (-1)), ter (temBAD_FEE));
@@ -146,7 +146,7 @@ class Ticket_test : public beast::unit_test::suite
testcase ("Create Tickets with Nonexistent Accounts");
using namespace test::jtx;
Env env {*this, with_only_features (featureTickets)};
Env env {*this, supported_features_plus (featureTickets)};
Account alice {"alice"};
env.memoize (alice);
@@ -162,7 +162,7 @@ class Ticket_test : public beast::unit_test::suite
testcase ("Create Tickets with Same Account and Target");
using namespace test::jtx;
Env env {*this, with_only_features (featureTickets)};
Env env {*this, supported_features_plus (featureTickets)};
env (ticket::create (env.master, env.master));
auto cr = checkTicketMeta (env);
@@ -183,7 +183,7 @@ class Ticket_test : public beast::unit_test::suite
testcase ("Create Ticket and Then Cancel by Creator");
using namespace test::jtx;
Env env {*this, with_only_features (featureTickets)};
Env env {*this, supported_features_plus (featureTickets)};
// create and verify
env (ticket::create (env.master));
@@ -215,7 +215,7 @@ class Ticket_test : public beast::unit_test::suite
testcase ("Create Ticket Insufficient Reserve");
using namespace test::jtx;
Env env {*this, with_only_features (featureTickets)};
Env env {*this, supported_features_plus (featureTickets)};
Account alice {"alice"};
env.fund (env.current ()->fees ().accountReserve (0), alice);
@@ -229,7 +229,7 @@ class Ticket_test : public beast::unit_test::suite
testcase ("Create Ticket and Then Cancel by Target");
using namespace test::jtx;
Env env {*this, with_only_features (featureTickets)};
Env env {*this, supported_features_plus (featureTickets)};
Account alice {"alice"};
env.fund (XRP (10000), alice);
@@ -275,7 +275,7 @@ class Ticket_test : public beast::unit_test::suite
testcase ("Create Ticket with Future Expiration");
using namespace test::jtx;
Env env {*this, with_only_features (featureTickets)};
Env env {*this, supported_features_plus (featureTickets)};
// create and verify
uint32_t expire =
@@ -300,7 +300,7 @@ class Ticket_test : public beast::unit_test::suite
testcase ("Create Ticket with Zero Expiration");
using namespace test::jtx;
Env env {*this, with_only_features (featureTickets)};
Env env {*this, supported_features_plus (featureTickets)};
// create and verify
env (ticket::create (env.master, 0u), ter (temBAD_EXPIRATION));
@@ -311,7 +311,7 @@ class Ticket_test : public beast::unit_test::suite
testcase ("Create Ticket with Past Expiration");
using namespace test::jtx;
Env env {*this, with_only_features (featureTickets)};
Env env {*this, supported_features_plus (featureTickets)};
env.timeKeeper ().adjustCloseTime (days {2});
env.close ();
@@ -340,7 +340,7 @@ class Ticket_test : public beast::unit_test::suite
testcase ("Create Ticket and Allow to Expire");
using namespace test::jtx;
Env env {*this, with_only_features (featureTickets)};
Env env {*this, supported_features_plus (featureTickets)};
// create and verify
uint32_t expire =

View File

@@ -46,12 +46,12 @@ class TrustAndBalance_test : public beast::unit_test::suite
};
void
testPayNonexistent (std::initializer_list<uint256> fs)
testPayNonexistent (FeatureBitset features)
{
testcase ("Payment to Nonexistent Account");
using namespace test::jtx;
Env env {*this, with_only_features(fs)};
Env env {*this, features};
env (pay (env.master, "alice", XRP(1)), ter(tecNO_DST_INSUF_XRP));
env.close();
}
@@ -162,12 +162,12 @@ class TrustAndBalance_test : public beast::unit_test::suite
}
void
testDirectRipple (std::initializer_list<uint256> fs)
testDirectRipple (FeatureBitset features)
{
testcase ("Direct Payment, Ripple");
using namespace test::jtx;
Env env {*this, with_only_features(fs)};
Env env {*this, features};
Account alice {"alice"};
Account bob {"bob"};
@@ -203,14 +203,14 @@ class TrustAndBalance_test : public beast::unit_test::suite
}
void
testWithTransferFee (bool subscribe, bool with_rate, std::initializer_list<uint256> fs)
testWithTransferFee (bool subscribe, bool with_rate, FeatureBitset features)
{
testcase(std::string("Direct Payment: ") +
(with_rate ? "With " : "Without ") + " Xfer Fee, " +
(subscribe ? "With " : "Without ") + " Subscribe");
using namespace test::jtx;
Env env {*this, with_only_features(fs)};
Env env {*this, features};
auto wsc = test::makeWSClient(env.app().config());
Account gw {"gateway"};
Account alice {"alice"};
@@ -283,12 +283,12 @@ class TrustAndBalance_test : public beast::unit_test::suite
}
void
testWithPath (std::initializer_list<uint256> fs)
testWithPath (FeatureBitset features)
{
testcase ("Payments With Paths and Fees");
using namespace test::jtx;
Env env {*this, with_only_features(fs)};
Env env {*this, features};
Account gw {"gateway"};
Account alice {"alice"};
Account bob {"bob"};
@@ -331,12 +331,12 @@ class TrustAndBalance_test : public beast::unit_test::suite
}
void
testIndirect (std::initializer_list<uint256> fs)
testIndirect (FeatureBitset features)
{
testcase ("Indirect Payment");
using namespace test::jtx;
Env env {*this, with_only_features(fs)};
Env env {*this, features};
Account gw {"gateway"};
Account alice {"alice"};
Account bob {"bob"};
@@ -372,13 +372,13 @@ class TrustAndBalance_test : public beast::unit_test::suite
}
void
testIndirectMultiPath (bool with_rate, std::initializer_list<uint256> fs)
testIndirectMultiPath (bool with_rate, FeatureBitset features)
{
testcase (std::string("Indirect Payment, Multi Path, ") +
(with_rate ? "With " : "Without ") + " Xfer Fee, ");
using namespace test::jtx;
Env env {*this, with_only_features(fs)};
Env env {*this, features};
Account gw {"gateway"};
Account amazon {"amazon"};
Account alice {"alice"};
@@ -438,12 +438,12 @@ class TrustAndBalance_test : public beast::unit_test::suite
}
void
testInvoiceID (std::initializer_list<uint256> fs)
testInvoiceID (FeatureBitset features)
{
testcase ("Set Invoice ID on Payment");
using namespace test::jtx;
Env env {*this, with_only_features(fs)};
Env env {*this, features};
Account alice {"alice"};
auto wsc = test::makeWSClient(env.app().config());
@@ -493,23 +493,28 @@ public:
testTrustNonexistent ();
testCreditLimit ();
auto testWithFeatures = [this](std::initializer_list<uint256> fs) {
testPayNonexistent(fs);
testDirectRipple(fs);
testWithTransferFee(false, false, fs);
testWithTransferFee(false, true, fs);
testWithTransferFee(true, false, fs);
testWithTransferFee(true, true, fs);
testWithPath(fs);
testIndirect(fs);
testIndirectMultiPath(true, fs);
testIndirectMultiPath(false, fs);
testInvoiceID(fs);
auto testWithFeatures = [this](FeatureBitset features) {
testPayNonexistent(features);
testDirectRipple(features);
testWithTransferFee(false, false, features);
testWithTransferFee(false, true, features);
testWithTransferFee(true, false, features);
testWithTransferFee(true, true, features);
testWithPath(features);
testIndirect(features);
testIndirectMultiPath(true, features);
testIndirectMultiPath(false, features);
testInvoiceID(features);
};
testWithFeatures({});
testWithFeatures({featureFlow});
testWithFeatures({featureFlow, fix1373});
testWithFeatures({featureFlow, fix1373, featureFlowCross});
using namespace test::jtx;
testWithFeatures(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testWithFeatures(
supported_features_except ( fix1373, featureFlowCross));
testWithFeatures(
supported_features_except ( featureFlowCross));
testWithFeatures(supported_amendments());
}
};

View File

@@ -162,8 +162,8 @@ public:
using namespace jtx;
using namespace std::chrono;
Env env(*this, makeConfig({ {"minimum_txn_in_ledger_standalone", "3"} }),
with_features(featureFeeEscalation, fix1513));
Env env(*this,
makeConfig({ {"minimum_txn_in_ledger_standalone", "3"} }));
auto& txq = env.app().getTxQ();
auto alice = Account("alice");
@@ -349,8 +349,8 @@ public:
using namespace jtx;
using namespace std::chrono;
Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }),
with_features(featureFeeEscalation, fix1513));
Env env(*this,
makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }));
auto alice = Account("alice");
auto bob = Account("bob");
@@ -405,8 +405,8 @@ public:
using namespace jtx;
using namespace std::chrono;
Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }),
with_features(featureFeeEscalation, fix1513));
Env env(*this,
makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }));
auto alice = Account("alice");
auto bob = Account("bob");
@@ -513,8 +513,8 @@ public:
using namespace jtx;
using namespace std::chrono;
Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }),
with_features(featureFeeEscalation, fix1513));
Env env(*this,
makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }));
auto alice = Account("alice");
auto bob = Account("bob");
@@ -620,7 +620,7 @@ public:
{
using namespace jtx;
Env env(*this, makeConfig(), with_features(featureFeeEscalation, fix1513));
Env env(*this, makeConfig());
auto alice = Account("alice");
auto bob = Account("bob");
@@ -644,8 +644,8 @@ public:
{
using namespace jtx;
Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }),
with_features(featureFeeEscalation, fix1513));
Env env(*this,
makeConfig({ { "minimum_txn_in_ledger_standalone", "2" } }));
auto alice = Account("alice");
auto bob = Account("bob");
@@ -701,8 +701,7 @@ public:
Env env(*this,
makeConfig(
{{"minimum_txn_in_ledger_standalone", "3"}},
{{"account_reserve", "200"}, {"owner_reserve", "50"}}),
with_features(featureFeeEscalation, fix1513));
{{"account_reserve", "200"}, {"owner_reserve", "50"}}));
auto alice = Account("alice");
auto bob = Account("bob");
@@ -929,8 +928,8 @@ public:
using namespace jtx;
using namespace std::chrono;
Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "4" } }),
with_features(featureFeeEscalation, fix1513));
Env env(*this,
makeConfig({ { "minimum_txn_in_ledger_standalone", "4" } }));
auto alice = Account("alice");
auto bob = Account("bob");
@@ -1088,8 +1087,8 @@ public:
{
using namespace jtx;
Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "1" } }),
with_features(featureFeeEscalation, fix1513));
Env env(*this,
makeConfig({ { "minimum_txn_in_ledger_standalone", "1" } }));
auto alice = Account("alice");
@@ -1131,8 +1130,7 @@ public:
Env env(*this, makeConfig(
{ {"minimum_txn_in_ledger_standalone", "2"},
{"target_txn_in_ledger", "4"},
{"maximum_txn_in_ledger", "5"} }),
with_features(featureFeeEscalation, fix1513));
{"maximum_txn_in_ledger", "5"} }));
auto alice = Account("alice");
auto queued = ter(terQUEUED);
@@ -1161,8 +1159,7 @@ public:
*this,
makeConfig(
{{"minimum_txn_in_ledger_standalone", "3"}},
{{"account_reserve", "200"}, {"owner_reserve", "50"}}),
with_features(featureFeeEscalation, fix1513));
{{"account_reserve", "200"}, {"owner_reserve", "50"}}));
auto alice = Account("alice");
auto bob = Account("bob");
@@ -1251,8 +1248,7 @@ public:
using namespace jtx;
Env env(*this,
makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }),
with_features(featureFeeEscalation, featureMultiSign, fix1513));
makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }));
auto alice = Account("alice");
auto bob = Account("bob");
@@ -1316,8 +1312,7 @@ public:
using namespace jtx;
Env env(*this,
makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }),
with_features(featureFeeEscalation, featureTickets, fix1513));
makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }));
auto alice = Account("alice");
auto charlie = Account("charlie");
@@ -1562,7 +1557,7 @@ public:
{
using namespace jtx;
using namespace std::chrono;
Env env(*this, with_only_features(featureTickets));
Env env(*this, supported_features_plus (featureTickets));
auto const alice = Account("alice");
env.memoize(alice);
env.memoize("bob");
@@ -1630,7 +1625,7 @@ public:
{
using namespace jtx;
{
Env env(*this, with_features(featureFeeEscalation, fix1513));
Env env(*this);
auto fee = env.rpc("fee");
@@ -1718,8 +1713,7 @@ public:
using namespace jtx;
Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "1" },
{"ledgers_in_queue", "10"}, {"maximum_txn_per_account", "20"} }),
with_features(featureFeeEscalation, fix1513));
{"ledgers_in_queue", "10"}, {"maximum_txn_per_account", "20"} }));
// Alice will recreate the scenario. Bob will block.
auto const alice = Account("alice");
@@ -1793,8 +1787,8 @@ public:
{
testcase("Autofilled sequence should account for TxQ");
using namespace jtx;
Env env(*this, makeConfig({ {"minimum_txn_in_ledger_standalone", "6"} }),
with_features(featureFeeEscalation, fix1513));
Env env(*this,
makeConfig({ {"minimum_txn_in_ledger_standalone", "6"} }));
Env_ss envs(env);
auto const& txQ = env.app().getTxQ();
@@ -1923,8 +1917,8 @@ public:
void testAccountInfo()
{
using namespace jtx;
Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }),
with_features(featureFeeEscalation, fix1513));
Env env(*this,
makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }));
Env_ss envs(env);
Account const alice{ "alice" };
@@ -2193,8 +2187,8 @@ public:
void testServerInfo()
{
using namespace jtx;
Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }),
with_features(featureFeeEscalation, fix1513));
Env env(*this,
makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }));
Env_ss envs(env);
Account const alice{ "alice" };
@@ -2416,8 +2410,8 @@ public:
{
using namespace jtx;
Env env(*this, makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }),
with_features(featureFeeEscalation, fix1513));
Env env(*this,
makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }));
Json::Value stream;
stream[jss::streams] = Json::arrayValue;
@@ -2585,8 +2579,7 @@ public:
using namespace jtx;
Env env(*this,
makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }),
with_features(featureFeeEscalation, fix1513));
makeConfig({ { "minimum_txn_in_ledger_standalone", "3" } }));
auto alice = Account("alice");
auto bob = Account("bob");

View File

@@ -151,6 +151,37 @@ supported_features_except (uint256 const& key, Args const&... args)
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

@@ -355,7 +355,7 @@ public:
{
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
env.fund(XRP(10000), "alice");
env(signers("alice", 1,
{ { "alice", 1 }, { "bob", 2 } }), ter(temBAD_SIGNER));
@@ -384,7 +384,7 @@ public:
ticket::create("alice", 60, "bob");
{
Env env(*this, with_only_features(featureTickets));
Env env(*this, supported_features_plus (featureTickets));
env.fund(XRP(10000), "alice");
env(noop("alice"), require(owners("alice", 0), tickets("alice", 0)));
env(ticket::create("alice"), require(owners("alice", 1), tickets("alice", 1)));

View File

@@ -25,10 +25,10 @@ namespace test {
struct BookDirs_test : public beast::unit_test::suite
{
void test_bookdir(std::initializer_list<uint256> fs)
void test_bookdir(FeatureBitset features)
{
using namespace jtx;
Env env(*this, with_only_features(fs));
Env env(*this, features);
auto gw = Account("gw");
auto USD = gw["USD"];
env.fund(XRP(1000000), "alice", "bob", "gw");
@@ -94,9 +94,12 @@ struct BookDirs_test : public beast::unit_test::suite
void run() override
{
test_bookdir({});
test_bookdir({featureFlow, fix1373});
test_bookdir({featureFlow, fix1373, featureFlowCross});
using namespace jtx;
test_bookdir(
supported_features_except (featureFlow, fix1373, featureFlowCross));
test_bookdir(
supported_features_except ( featureFlowCross));
test_bookdir(supported_amendments ());
}
};

View File

@@ -116,7 +116,7 @@ struct Directory_test : public beast::unit_test::suite
{
testcase ("Directory Ordering (with 'SortedDirectories' amendment)");
Env env(*this, with_only_features(featureSortedDirectories));
Env env(*this);
env.fund(XRP(10000000), alice, gw);
for (std::size_t i = 1; i <= 400; ++i)
@@ -184,8 +184,7 @@ struct Directory_test : public beast::unit_test::suite
beast::xor_shift_engine eng;
Env env(*this,
with_only_features(featureSortedDirectories, featureMultiSign));
Env env(*this);
env.fund(XRP(1000000), alice, charlie, gw);
env.close();
@@ -289,7 +288,7 @@ struct Directory_test : public beast::unit_test::suite
testcase("RIPD-1353 Empty Offer Directories");
using namespace jtx;
Env env(*this, with_only_features(featureSortedDirectories));
Env env(*this);
auto const gw = Account{"gateway"};
auto const alice = Account{"alice"};
@@ -349,7 +348,7 @@ struct Directory_test : public beast::unit_test::suite
testcase("Empty Chain on Delete");
using namespace jtx;
Env env(*this, with_only_features(featureSortedDirectories));
Env env(*this);
auto const gw = Account{"gateway"};
auto const alice = Account{"alice"};

View File

@@ -55,12 +55,12 @@ class PaymentSandbox_test : public beast::unit_test::suite
2) New code: Path is dry because sender does not have any
GW1 to spend until the end of the transaction.
*/
void testSelfFunding (std::initializer_list<uint256> fs)
void testSelfFunding (FeatureBitset features)
{
testcase ("selfFunding");
using namespace jtx;
Env env (*this, with_only_features(fs));
Env env (*this, features);
Account const gw1 ("gw1");
Account const gw2 ("gw2");
Account const snd ("snd");
@@ -96,12 +96,12 @@ class PaymentSandbox_test : public beast::unit_test::suite
env.require (balance ("rcv", USD_gw2 (2)));
}
void testSubtractCredits (std::initializer_list<uint256> fs)
void testSubtractCredits (FeatureBitset features)
{
testcase ("subtractCredits");
using namespace jtx;
Env env (*this, with_only_features(fs));
Env env (*this, features);
Account const gw1 ("gw1");
Account const gw2 ("gw2");
Account const alice ("alice");
@@ -256,7 +256,7 @@ class PaymentSandbox_test : public beast::unit_test::suite
}
}
void testTinyBalance (std::initializer_list<uint256> fs)
void testTinyBalance (FeatureBitset features)
{
testcase ("Tiny balance");
@@ -266,7 +266,7 @@ class PaymentSandbox_test : public beast::unit_test::suite
using namespace jtx;
Env env (*this, with_only_features(fs));
Env env (*this, features);
Account const gw ("gw");
Account const alice ("alice");
@@ -293,7 +293,7 @@ class PaymentSandbox_test : public beast::unit_test::suite
}
}
void testReserve(std::initializer_list<uint256> fs)
void testReserve(FeatureBitset features)
{
testcase ("Reserve");
using namespace jtx;
@@ -312,7 +312,7 @@ class PaymentSandbox_test : public beast::unit_test::suite
return env.current ()->fees ().accountReserve (count);
};
Env env (*this, with_only_features(fs));
Env env (*this, features);
Account const alice ("alice");
env.fund (reserve(env, 1), alice);
@@ -333,14 +333,14 @@ class PaymentSandbox_test : public beast::unit_test::suite
}
}
void testBalanceHook(std::initializer_list<uint256> fs)
void testBalanceHook(FeatureBitset features)
{
// Make sure the Issue::Account returned by PAymentSandbox::balanceHook
// is correct.
testcase ("balanceHook");
using namespace jtx;
Env env (*this, with_only_features(fs));
Env env (*this, features);
Account const gw ("gw");
auto const USD = gw["USD"];
@@ -370,16 +370,19 @@ class PaymentSandbox_test : public beast::unit_test::suite
public:
void run ()
{
auto testAll = [this](std::initializer_list<uint256> fs) {
testSelfFunding(fs);
testSubtractCredits(fs);
testTinyBalance(fs);
testReserve(fs);
testBalanceHook(fs);
auto testAll = [this](FeatureBitset features) {
testSelfFunding(features);
testSubtractCredits(features);
testTinyBalance(features);
testReserve(features);
testBalanceHook(features);
};
testAll({});
testAll({featureFlow, fix1373});
testAll({featureFlow, fix1373, featureFlowCross});
using namespace jtx;
testAll(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testAll(
supported_features_except ( featureFlowCross));
testAll(supported_amendments());
}
};

View File

@@ -59,7 +59,7 @@ public:
void testSignerLists()
{
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
Account const alice {"alice"};
env.fund(XRP(1000), alice);
@@ -165,7 +165,7 @@ public:
void testSignerListsV2()
{
using namespace jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
Account const alice {"alice"};
env.fund(XRP(1000), alice);

View File

@@ -371,7 +371,7 @@ public:
void testRequireAuthWithDir()
{
using namespace test::jtx;
Env env(*this, with_only_features(featureMultiSign));
Env env(*this);
Account const alice ("alice");
Account const bob ("bob");

View File

@@ -117,10 +117,6 @@ class Feature_test : public beast::unit_test::suite
using namespace test::jtx;
Env env {*this,
with_only_features(featureEscrow, featureCryptoConditions)};
// The amendment table has to be modified
// since that is what feature RPC actually checks
env.app().getAmendmentTable().enable(featureEscrow);
env.app().getAmendmentTable().enable(featureCryptoConditions);
auto jrr = env.rpc("feature") [jss::result];
if(! BEAST_EXPECT(jrr.isMember(jss::features)))
@@ -221,9 +217,6 @@ class Feature_test : public beast::unit_test::suite
using namespace test::jtx;
Env env {*this,
with_only_features(featureCryptoConditions)};
// The amendment table has to be modified
// since that is what feature RPC actually checks
env.app().getAmendmentTable().enable(featureCryptoConditions);
auto jrr = env.rpc("feature", "CryptoConditions") [jss::result];
if(! BEAST_EXPECTS(jrr[jss::status] == jss::success, "status"))

View File

@@ -30,11 +30,11 @@ class GatewayBalances_test : public beast::unit_test::suite
public:
void
testGWB(std::initializer_list<uint256> fs)
testGWB(FeatureBitset features)
{
using namespace std::chrono_literals;
using namespace jtx;
Env env(*this, with_only_features(fs));
Env env(*this, features);
// Gateway account and assets
Account const alice {"alice"};
@@ -153,9 +153,12 @@ public:
void
run() override
{
testGWB({});
testGWB({featureFlow, fix1373});
testGWB({featureFlow, fix1373, featureFlowCross});
using namespace jtx;
testGWB(
supported_features_except (featureFlow, fix1373, featureFlowCross));
testGWB(
supported_features_except ( featureFlowCross));
testGWB(supported_amendments());
}
};

View File

@@ -1941,8 +1941,7 @@ public:
cfg->section("transaction_queue")
.set("minimum_txn_in_ledger_standalone", "3");
return cfg;
}),
with_features(featureFeeEscalation, fix1513)};
})};
LoadFeeTrack const& feeTrack = env.app().getFeeTrack();
{
@@ -2254,8 +2253,7 @@ public:
// "b" (not in the ledger) is rDg53Haik2475DJx8bjMDSDPj4VX7htaMd.
// "c" (phantom signer) is rPcNzota6B8YBokhYtcTNqQVCngtbnWfux.
test::jtx::Env env(*this,
test::jtx::with_only_features(featureMultiSign));
test::jtx::Env env(*this);
env.fund(test::jtx::XRP(100000), a, ed, g);
env.close();

View File

@@ -268,8 +268,8 @@ public:
using namespace test::jtx;
using namespace std::chrono;
Env env { *this, envconfig(validator, ""),
with_only_features(featureMultiSign, featureTickets,
featureEscrow, featurePayChan) };
supported_features_plus(featureTickets) };
Account const gw { "gateway" };
auto const USD = gw["USD"];
env.fund(XRP(100000), gw);

View File

@@ -476,8 +476,7 @@ class LedgerRPC_test : public beast::unit_test::suite
cfg->section("transaction_queue")
.set("minimum_txn_in_ledger_standalone", "3");
return cfg;
}),
with_features(featureFeeEscalation, fix1513)};
})};
Json::Value jv;
jv[jss::ledger_index] = "current";

View File

@@ -67,12 +67,12 @@ public:
}
}
void testNegativeBalance(std::initializer_list<uint256> fs)
void testNegativeBalance(FeatureBitset features)
{
testcase("Set noripple on a line with negative balance");
using namespace jtx;
Env env(*this, with_only_features(fs));
Env env(*this, features);
auto const gw = Account("gateway");
auto const alice = Account("alice");
@@ -113,12 +113,12 @@ public:
BEAST_EXPECT(!lines[0u].isMember(jss::no_ripple));
}
void testPairwise(std::initializer_list<uint256> fs)
void testPairwise(FeatureBitset features)
{
testcase("pairwise NoRipple");
using namespace jtx;
Env env(*this, with_only_features(fs));
Env env(*this, features);
auto const alice = Account("alice");
auto const bob = Account("bob");
@@ -150,12 +150,12 @@ public:
env(pay(alice, carol, bob["USD"](50)), ter(tecPATH_DRY));
}
void testDefaultRipple(std::initializer_list<uint256> fs)
void testDefaultRipple(FeatureBitset features)
{
testcase("Set default ripple on an account and check new trustlines");
using namespace jtx;
Env env(*this, with_only_features(fs));
Env env(*this, features);
auto const gw = Account("gateway");
auto const alice = Account("alice");
@@ -212,15 +212,19 @@ public:
{
testSetAndClear();
auto withFeatsTests = [this](std::initializer_list<uint256> fs) {
testNegativeBalance(fs);
testPairwise(fs);
testDefaultRipple(fs);
auto withFeatsTests = [this](FeatureBitset features) {
testNegativeBalance(features);
testPairwise(features);
testDefaultRipple(features);
};
withFeatsTests({});
withFeatsTests({featureFlow});
withFeatsTests({featureFlow, fix1373});
withFeatsTests({featureFlow, fix1373, featureFlowCross});
using namespace jtx;
withFeatsTests(
supported_features_except (featureFlow, fix1373, featureFlowCross));
withFeatsTests(
supported_features_except ( fix1373, featureFlowCross));
withFeatsTests(
supported_features_except ( featureFlowCross));
withFeatsTests(supported_amendments());
}
};