diff --git a/src/ripple/app/main/Amendments.cpp b/src/ripple/app/main/Amendments.cpp index c64997ee90..7e8c5ac4c8 100644 --- a/src/ripple/app/main/Amendments.cpp +++ b/src/ripple/app/main/Amendments.cpp @@ -57,7 +57,8 @@ supportedAmendments () { "DC9CA96AEA1DCF83E527D1AFC916EFAF5D27388ECA4060A88817C1238CAEE0BF EnforceInvariants" }, { "3012E8230864E95A58C60FD61430D7E1B4D3353195F2981DC12B0C7C0950FFAC FlowCross" }, { "CC5ABAE4F3EC92E94A59B1908C2BE82D2228B6485C00AFF8F22DF930D89C194E SortedDirectories" }, - { "B4D44CC3111ADD964E846FC57760C8B50FFCD5A82C86A72756F6B058DDDF96AD fix1201" } + { "B4D44CC3111ADD964E846FC57760C8B50FFCD5A82C86A72756F6B058DDDF96AD fix1201" }, + { "6C92211186613F9647A89DFFBAB8F94C99D4C7E956D495270789128569177DA1 fix1512" } }; } diff --git a/src/ripple/app/tx/impl/PayChan.cpp b/src/ripple/app/tx/impl/PayChan.cpp index f818bbdc94..1a14cbe653 100644 --- a/src/ripple/app/tx/impl/PayChan.cpp +++ b/src/ripple/app/tx/impl/PayChan.cpp @@ -344,6 +344,9 @@ PayChanClaim::preflight (PreflightContext const& ctx) if (! ctx.rules.enabled(featurePayChan)) return temDISABLED; + + bool const noTecs = ctx.rules.enabled(fix1512); + auto const ret = preflight1 (ctx); if (!isTesSuccess (ret)) return ret; @@ -357,7 +360,12 @@ PayChanClaim::preflight (PreflightContext const& ctx) return temBAD_AMOUNT; if (bal && amt && *bal > *amt) - return tecNO_PERMISSION; + { + if (noTecs) + return temBAD_AMOUNT; + else + return tecNO_PERMISSION; + } auto const flags = ctx.tx.getFlags (); if ((flags & tfClose) && (flags & tfRenew)) @@ -376,7 +384,12 @@ PayChanClaim::preflight (PreflightContext const& ctx) auto const authAmt = amt ? amt->xrp() : reqBalance; if (reqBalance > authAmt) - return tecNO_PERMISSION; + { + if (noTecs) + return temBAD_AMOUNT; + else + return tecNO_PERMISSION; + } Keylet const k (ltPAYCHAN, ctx.tx[sfPayChannel]); if (!publicKeyType(ctx.tx[sfPublicKey])) diff --git a/src/ripple/protocol/Feature.h b/src/ripple/protocol/Feature.h index 4085bd9e84..4a70a88a72 100644 --- a/src/ripple/protocol/Feature.h +++ b/src/ripple/protocol/Feature.h @@ -68,7 +68,8 @@ class FeatureCollections "fix1373", "EnforceInvariants", "SortedDirectories", - "fix1201"}; + "fix1201", + "fix1512"}; std::vector features; boost::container::flat_map featureToIndex; @@ -162,6 +163,7 @@ extern uint256 const fix1373; extern uint256 const featureEnforceInvariants; extern uint256 const featureSortedDirectories; extern uint256 const fix1201; +extern uint256 const fix1512; } // ripple diff --git a/src/ripple/protocol/impl/Feature.cpp b/src/ripple/protocol/impl/Feature.cpp index 37b795f0c8..dbda491a09 100644 --- a/src/ripple/protocol/impl/Feature.cpp +++ b/src/ripple/protocol/impl/Feature.cpp @@ -115,5 +115,6 @@ uint256 const fix1373 = *getRegisteredFeature("fix1373"); uint256 const featureEnforceInvariants = *getRegisteredFeature("EnforceInvariants"); uint256 const featureSortedDirectories = *getRegisteredFeature("SortedDirectories"); uint256 const fix1201 = *getRegisteredFeature("fix1201"); +uint256 const fix1512 = *getRegisteredFeature("fix1512"); } // ripple diff --git a/src/test/app/PayChan_test.cpp b/src/test/app/PayChan_test.cpp index 7cca6a4573..f2f5dfc749 100644 --- a/src/test/app/PayChan_test.cpp +++ b/src/test/app/PayChan_test.cpp @@ -175,7 +175,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("simple"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, with_features (featurePayChan)); + Env env (*this); auto const alice = Account ("alice"); auto const bob = Account ("bob"); auto USDA = alice["USD"]; @@ -242,7 +242,7 @@ struct PayChan_test : public beast::unit_test::suite auto const reqBal = chanBal + delta; auto const authAmt = reqBal + XRP (-100); assert (reqBal <= chanAmt); - env (claim (alice, chan, reqBal, authAmt), ter (tecNO_PERMISSION)); + env (claim (alice, chan, reqBal, authAmt), ter (temBAD_AMOUNT)); } { // No signature needed since the owner is claiming @@ -290,11 +290,10 @@ struct PayChan_test : public beast::unit_test::suite auto const sig = signClaimAuth (alice.pk (), alice.sk (), chan, authAmt); env (claim (bob, chan, reqAmt, authAmt, Slice (sig), alice.pk ()), - ter (tecNO_PERMISSION)); + ter (temBAD_AMOUNT)); BEAST_EXPECT (channelBalance (*env.current (), chan) == chanBal); BEAST_EXPECT (channelAmount (*env.current (), chan) == chanAmt); - auto const feeDrops = env.current ()->fees ().base; - BEAST_EXPECT (env.balance (bob) == preBob - feeDrops); + BEAST_EXPECT (env.balance (bob) == preBob); } // Dst tries to fund the channel @@ -347,7 +346,7 @@ struct PayChan_test : public beast::unit_test::suite auto const carol = Account ("carol"); { // If dst claims after cancel after, channel closes - Env env (*this, with_features (featurePayChan)); + Env env (*this); env.fund (XRP (10000), alice, bob); auto const pk = alice.pk (); auto const settleDelay = 100s; @@ -386,7 +385,7 @@ struct PayChan_test : public beast::unit_test::suite } { // Third party can close after cancel after - Env env (*this, with_features (featurePayChan)); + Env env (*this); env.fund (XRP (10000), alice, bob, carol); auto const pk = alice.pk (); auto const settleDelay = 100s; @@ -416,7 +415,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("expiration"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, with_features (featurePayChan)); + Env env (*this); auto const alice = Account ("alice"); auto const bob = Account ("bob"); auto const carol = Account ("carol"); @@ -477,7 +476,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("settle delay"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, with_features (featurePayChan)); + Env env (*this); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -537,7 +536,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("close dry"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, with_features (featurePayChan)); + Env env (*this); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -573,7 +572,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("default amount"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, with_features (featurePayChan)); + Env env (*this); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -632,7 +631,7 @@ struct PayChan_test : public beast::unit_test::suite using namespace std::literals::chrono_literals; { // Create a channel where dst disallows XRP - Env env (*this, with_features (featurePayChan)); + Env env (*this); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -648,7 +647,7 @@ struct PayChan_test : public beast::unit_test::suite { // Claim to a channel where dst disallows XRP // (channel is created before disallow xrp is set) - Env env (*this, with_features (featurePayChan)); + Env env (*this); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -674,7 +673,7 @@ struct PayChan_test : public beast::unit_test::suite using namespace jtx; using namespace std::literals::chrono_literals; // Create a channel where dst disallows XRP - Env env (*this, with_features (featurePayChan)); + Env env (*this); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -699,7 +698,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("Multiple channels to the same account"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, with_features (featurePayChan)); + Env env (*this); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -721,7 +720,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("RPC"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, with_features (featurePayChan)); + Env env (*this); auto const alice = Account ("alice"); auto const bob = Account ("bob"); env.fund (XRP (10000), alice, bob); @@ -791,7 +790,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("Optional Fields"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, with_features (featurePayChan)); + Env env (*this); auto const alice = Account ("alice"); auto const bob = Account ("bob"); auto const carol = Account ("carol"); @@ -831,7 +830,7 @@ struct PayChan_test : public beast::unit_test::suite testcase ("malformed pk"); using namespace jtx; using namespace std::literals::chrono_literals; - Env env (*this, with_features (featurePayChan)); + Env env (*this); auto const alice = Account ("alice"); auto const bob = Account ("bob"); auto USDA = alice["USD"];