mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
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:
@@ -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});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user