New rules for payment paths:

* Sanity check on newly created strands
* Better loop detection
* Better tests (test every combination of path element pairs)
* Disallow any root issuer (even for xrp)
* Disallow compount element typs in path
* Issue was not reset when currency was XRP
* Add amendment
This commit is contained in:
seelabs
2017-02-08 13:24:36 -05:00
committed by Scott Schurr
parent 80d9b0464a
commit 846723d771
27 changed files with 2172 additions and 646 deletions

View File

@@ -92,7 +92,7 @@ class Offer_test : public beast::unit_test::suite
}
public:
void testRmFundedOffer ()
void testRmFundedOffer (std::initializer_list<uint256> fs)
{
testcase ("Incorrect Removal of Funded Offers");
@@ -105,7 +105,7 @@ public:
// still funded and not used for the payment.
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
// ledger close times have a dynamic resolution depending on network
// conditions it appears the resolution in test is 10 seconds
@@ -151,12 +151,12 @@ public:
isOffer (env, carol, BTC (49), XRP (49)));
}
void testCanceledOffer ()
void testCanceledOffer (std::initializer_list<uint256> fs)
{
testcase ("Removing Canceled Offers");
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const gw = Account {"gateway"};
auto const alice = Account {"alice"};
auto const USD = gw["USD"];
@@ -206,7 +206,7 @@ public:
BEAST_EXPECT(!isOffer (env, alice, XRP (222), USD (111)));
}
void testTinyPayment ()
void testTinyPayment (std::initializer_list<uint256> fs)
{
testcase ("Tiny payments");
@@ -221,7 +221,7 @@ public:
auto const USD = gw["USD"];
auto const EUR = gw["EUR"];
Env env {*this};
Env env {*this, features(fs)};
env.fund (XRP (10000), alice, bob, carol, gw);
env.trust (USD (1000), alice, bob, carol);
@@ -248,7 +248,7 @@ public:
}
}
void testXRPTinyPayment ()
void testXRPTinyPayment (std::initializer_list<uint256> fs)
{
testcase ("XRP Tiny payments");
@@ -279,7 +279,10 @@ public:
for (auto withFix : {false, true})
{
Env env {*this};
if (!withFix && fs.size())
continue;
Env env {*this, features(fs)};
auto closeTime = [&]
{
@@ -352,7 +355,7 @@ public:
}
}
void testEnforceNoRipple ()
void testEnforceNoRipple (std::initializer_list<uint256> fs)
{
testcase ("Enforce No Ripple");
@@ -369,7 +372,7 @@ public:
{
// No ripple with an implied account step after an offer
Env env {*this};
Env env {*this, features(fs)};
auto const gw1 = Account {"gw1"};
auto const USD1 = gw1["USD"];
auto const gw2 = Account {"gw2"};
@@ -419,7 +422,7 @@ public:
}
void
testInsufficientReserve ()
testInsufficientReserve (std::initializer_list<uint256> fs)
{
testcase ("Insufficient Reserve");
@@ -442,7 +445,7 @@ public:
// No crossing:
{
Env env {*this};
Env env {*this, features(fs)};
env.fund (XRP (1000000), gw);
auto const f = env.current ()->fees ().base;
@@ -490,7 +493,7 @@ public:
// if an offer were added. Attempt to sell IOUs to
// buy XRP. If it fully crosses, we succeed.
{
Env env {*this};
Env env {*this, features(fs)};
env.fund (XRP (1000000), gw);
auto const f = env.current ()->fees ().base;
@@ -522,7 +525,7 @@ public:
}
void
testFillModes ()
testFillModes (std::initializer_list<uint256> fs)
{
testcase ("Fill Modes");
@@ -537,7 +540,7 @@ public:
// Fill or Kill - unless we fully cross, just charge
// a fee and not place the offer on the books:
{
Env env {*this};
Env env {*this, features(fs)};
env.fund (startBalance, gw);
auto const f = env.current ()->fees ().base;
@@ -579,7 +582,7 @@ public:
// Immediate or Cancel - cross as much as possible
// and add nothing on the books:
{
Env env {*this};
Env env {*this, features(fs)};
env.fund (startBalance, gw);
auto const f = env.current ()->fees ().base;
@@ -632,7 +635,7 @@ public:
}
void
testMalformed()
testMalformed(std::initializer_list<uint256> fs)
{
testcase ("Malformed Detection");
@@ -643,7 +646,7 @@ public:
auto const alice = Account {"alice"};
auto const USD = gw["USD"];
Env env {*this};
Env env {*this, features(fs)};
env.fund (startBalance, gw);
env.fund (startBalance, alice);
@@ -726,7 +729,7 @@ public:
}
void
testExpiration()
testExpiration(std::initializer_list<uint256> fs)
{
testcase ("Offer Expiration");
@@ -799,7 +802,7 @@ public:
}
void
testUnfundedCross()
testUnfundedCross(std::initializer_list<uint256> fs)
{
testcase ("Unfunded Crossing");
@@ -860,7 +863,7 @@ public:
}
void
testSelfCross(bool use_partner)
testSelfCross(bool use_partner, std::initializer_list<uint256> fs)
{
testcase (std::string("Self-crossing") +
(use_partner ? ", with partner account" : ""));
@@ -872,7 +875,7 @@ public:
auto const USD = gw["USD"];
auto const BTC = gw["BTC"];
Env env {*this};
Env env {*this, features(fs)};
env.fund (XRP (10000), gw);
if (use_partner)
{
@@ -964,7 +967,7 @@ public:
}
void
testNegativeBalance()
testNegativeBalance(std::initializer_list<uint256> fs)
{
// This test creates an offer test for negative balance
// with transfer fees and miniscule funds.
@@ -972,7 +975,7 @@ public:
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const gw = Account {"gateway"};
auto const alice = Account {"alice"};
auto const bob = Account {"bob"};
@@ -1041,7 +1044,7 @@ public:
}
void
testOfferCrossWithXRP(bool reverse_order)
testOfferCrossWithXRP(bool reverse_order, std::initializer_list<uint256> fs)
{
testcase (std::string("Offer Crossing with XRP, ") +
(reverse_order ? "Reverse" : "Normal") +
@@ -1049,7 +1052,7 @@ public:
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const gw = Account {"gateway"};
auto const alice = Account {"alice"};
auto const bob = Account {"bob"};
@@ -1098,13 +1101,13 @@ public:
}
void
testOfferCrossWithLimitOverride()
testOfferCrossWithLimitOverride(std::initializer_list<uint256> fs)
{
testcase ("Offer Crossing with Limit Override");
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const gw = Account {"gateway"};
auto const alice = Account {"alice"};
auto const bob = Account {"bob"};
@@ -1143,13 +1146,13 @@ public:
}
void
testOfferAcceptThenCancel()
testOfferAcceptThenCancel(std::initializer_list<uint256> fs)
{
testcase ("Offer Accept then Cancel.");
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const USD = env.master["USD"];
auto const nextOfferSeq = env.seq (env.master);
@@ -1170,14 +1173,14 @@ public:
}
void
testOfferCancelPastAndFuture()
testOfferCancelPastAndFuture(std::initializer_list<uint256> fs)
{
testcase ("Offer Cancel Past and Future Sequence.");
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const alice = Account {"alice"};
auto const nextOfferSeq = env.seq (env.master);
@@ -1200,13 +1203,13 @@ public:
}
void
testCurrencyConversionEntire()
testCurrencyConversionEntire(std::initializer_list<uint256> fs)
{
testcase ("Currency Conversion: Entire Offer");
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const gw = Account {"gateway"};
auto const alice = Account {"alice"};
auto const bob = Account {"bob"};
@@ -1260,13 +1263,13 @@ public:
}
void
testCurrencyConversionIntoDebt()
testCurrencyConversionIntoDebt(std::initializer_list<uint256> fs)
{
testcase ("Currency Conversion: Offerer Into Debt");
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const alice = Account {"alice"};
auto const bob = Account {"bob"};
auto const carol = Account {"carol"};
@@ -1288,13 +1291,13 @@ public:
}
void
testCurrencyConversionInParts()
testCurrencyConversionInParts(std::initializer_list<uint256> fs)
{
testcase ("Currency Conversion: In Parts");
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const gw = Account {"gateway"};
auto const alice = Account {"alice"};
auto const bob = Account {"bob"};
@@ -1375,13 +1378,13 @@ public:
}
void
testCrossCurrencyStartXRP()
testCrossCurrencyStartXRP(std::initializer_list<uint256> fs)
{
testcase ("Cross Currency Payment: Start with XRP");
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const gw = Account {"gateway"};
auto const alice = Account {"alice"};
auto const bob = Account {"bob"};
@@ -1414,13 +1417,13 @@ public:
}
void
testCrossCurrencyEndXRP()
testCrossCurrencyEndXRP(std::initializer_list<uint256> fs)
{
testcase ("Cross Currency Payment: End with XRP");
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const gw = Account {"gateway"};
auto const alice = Account {"alice"};
auto const bob = Account {"bob"};
@@ -1461,13 +1464,13 @@ public:
}
void
testCrossCurrencyBridged()
testCrossCurrencyBridged(std::initializer_list<uint256> fs)
{
testcase ("Cross Currency Payment: Bridged");
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const gw1 = Account {"gateway_1"};
auto const gw2 = Account {"gateway_2"};
auto const alice = Account {"alice"};
@@ -1525,13 +1528,13 @@ public:
}
void
testOfferFeesConsumeFunds()
testOfferFeesConsumeFunds(std::initializer_list<uint256> fs)
{
testcase ("Offer Fees Consume Funds");
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const gw1 = Account {"gateway_1"};
auto const gw2 = Account {"gateway_2"};
auto const gw3 = Account {"gateway_3"};
@@ -1578,13 +1581,13 @@ public:
}
void
testOfferCreateThenCross()
testOfferCreateThenCross(std::initializer_list<uint256> fs)
{
testcase ("Offer Create, then Cross");
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const gw = Account {"gateway"};
auto const alice = Account {"alice"};
auto const bob = Account {"bob"};
@@ -1613,13 +1616,13 @@ public:
}
void
testSellFlagBasic()
testSellFlagBasic(std::initializer_list<uint256> fs)
{
testcase ("Offer tfSell: Basic Sell");
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const gw = Account {"gateway"};
auto const alice = Account {"alice"};
auto const bob = Account {"bob"};
@@ -1654,13 +1657,13 @@ public:
}
void
testSellFlagExceedLimit()
testSellFlagExceedLimit(std::initializer_list<uint256> fs)
{
testcase ("Offer tfSell: 2x Sell Exceed Limit");
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const gw = Account {"gateway"};
auto const alice = Account {"alice"};
auto const bob = Account {"bob"};
@@ -1697,13 +1700,13 @@ public:
}
void
testGatewayCrossCurrency()
testGatewayCrossCurrency(std::initializer_list<uint256> fs)
{
testcase ("Client Issue #535: Gateway Cross Currency");
using namespace jtx;
Env env {*this};
Env env {*this, features(fs)};
auto const gw = Account {"gateway"};
auto const alice = Account {"alice"};
auto const bob = Account {"bob"};
@@ -1764,7 +1767,7 @@ public:
BEAST_EXPECT(jrr[jss::node][sfBalance.fieldName][jss::value] == "-101");
}
void testTickSize ()
void testTickSize (std::initializer_list<uint256> fs)
{
testcase ("Tick Size");
@@ -1772,7 +1775,7 @@ public:
// Try to set tick size without enabling feature
{
Env env {*this};
Env env {*this, features(fs)};
auto const gw = Account {"gateway"};
env.fund (XRP(10000), gw);
@@ -1783,7 +1786,7 @@ public:
// Try to set tick size out of range
{
Env env {*this, features (featureTickSize)};
Env env {*this, features(fs), features (featureTickSize)};
auto const gw = Account {"gateway"};
env.fund (XRP(10000), gw);
@@ -1816,7 +1819,7 @@ public:
BEAST_EXPECT (! env.le(gw)->isFieldPresent (sfTickSize));
}
Env env {*this, features (featureTickSize)};
Env env {*this, features(fs), features (featureTickSize)};
auto const gw = Account {"gateway"};
auto const alice = Account {"alice"};
auto const XTS = gw["XTS"];
@@ -1886,36 +1889,41 @@ public:
void run ()
{
testCanceledOffer ();
testRmFundedOffer ();
testTinyPayment ();
testXRPTinyPayment ();
testEnforceNoRipple ();
testInsufficientReserve ();
testFillModes ();
testMalformed ();
testExpiration ();
testUnfundedCross ();
testSelfCross (false);
testSelfCross (true);
testNegativeBalance ();
testOfferCrossWithXRP (true);
testOfferCrossWithXRP (false);
testOfferCrossWithLimitOverride ();
testOfferAcceptThenCancel ();
testOfferCancelPastAndFuture ();
testCurrencyConversionEntire ();
testCurrencyConversionIntoDebt ();
testCurrencyConversionInParts ();
testCrossCurrencyStartXRP ();
testCrossCurrencyEndXRP ();
testCrossCurrencyBridged ();
testOfferFeesConsumeFunds ();
testOfferCreateThenCross ();
testSellFlagBasic ();
testSellFlagExceedLimit ();
testGatewayCrossCurrency ();
testTickSize ();
auto testAll = [this](std::initializer_list<uint256> fs) {
testCanceledOffer(fs);
testRmFundedOffer(fs);
testTinyPayment(fs);
testXRPTinyPayment(fs);
testEnforceNoRipple(fs);
testInsufficientReserve(fs);
testFillModes(fs);
testMalformed(fs);
testExpiration(fs);
testUnfundedCross(fs);
testSelfCross(false, fs);
testSelfCross(true, fs);
testNegativeBalance(fs);
testOfferCrossWithXRP(true, fs);
testOfferCrossWithXRP(false, fs);
testOfferCrossWithLimitOverride(fs);
testOfferAcceptThenCancel(fs);
testOfferCancelPastAndFuture(fs);
testCurrencyConversionEntire(fs);
testCurrencyConversionIntoDebt(fs);
testCurrencyConversionInParts(fs);
testCrossCurrencyStartXRP(fs);
testCrossCurrencyEndXRP(fs);
testCrossCurrencyBridged(fs);
testOfferFeesConsumeFunds(fs);
testOfferCreateThenCross(fs);
testSellFlagBasic(fs);
testSellFlagExceedLimit(fs);
testGatewayCrossCurrency(fs);
testTickSize(fs);
};
testAll({});
testAll({featureFlow});
testAll({featureFlow, featureToStrandV2});
}
};