Use features instead of ApplyFlags:

tapENABLE_TESTING is removed from checks, and feature enablement
is the sole method for activating features. Unit tests are updated
to enable required features in the construction of the Env.

Tickets are put on a feature switch instead of a build macro.
This commit is contained in:
Vinnie Falco
2015-12-17 15:35:56 -05:00
parent 48e0466a2b
commit a5583de6e6
17 changed files with 64 additions and 81 deletions

View File

@@ -164,13 +164,6 @@
#define RIPPLE_SINGLE_IO_SERVICE_THREAD 0
#endif
/** Config: RIPPLE_ENABLE_TICKETS
Enables processing of ticket transactions
*/
#ifndef RIPPLE_ENABLE_TICKETS
#define RIPPLE_ENABLE_TICKETS 0
#endif
// Uses OpenSSL instead of alternatives
#ifndef RIPPLE_USE_OPENSSL
#define RIPPLE_USE_OPENSSL 1

View File

@@ -17,6 +17,7 @@
#include <BeastConfig.h>
#include <ripple/protocol/JsonFields.h> // jss:: definitions
#include <ripple/protocol/Feature.h>
#include <ripple/test/jtx.h>
namespace ripple {
@@ -38,7 +39,7 @@ public:
void test_noReserve()
{
using namespace jtx;
Env env(*this);
Env env(*this, features(featureMultiSign));
Account const alice {"alice", KeyType::secp256k1};
// Pay alice enough to meet the initial reserve, but not enough to
@@ -86,7 +87,7 @@ public:
void test_signerListSet()
{
using namespace jtx;
Env env(*this);
Env env(*this, features(featureMultiSign));
Account const alice {"alice", KeyType::ed25519};
env.fund(XRP(1000), alice);
@@ -131,7 +132,7 @@ public:
void test_phantomSigners()
{
using namespace jtx;
Env env(*this);
Env env(*this, features(featureMultiSign));
Account const alice {"alice", KeyType::ed25519};
env.fund(XRP(1000), alice);
env.close();
@@ -225,22 +226,15 @@ public:
env.fund(XRP(1000), alice);
env.close();
// Add a signer list to alice. Should succeed.
env(signers(alice, 1, {{bogie, 1}}));
// Make sure multisign is disabled in production.
// NOTE: These six tests will fail when multisign is default enabled.
env.disable_testing();
env(signers(alice, 1, {{bogie, 1}}), ter(temDISABLED));
env.close();
env.require (owners (alice, 3));
env.require (owners (alice, 0));
// alice multisigns a transaction. Should succeed.
std::uint32_t aliceSeq = env.seq (alice);
auto const baseFee = env.app().config().FEE_DEFAULT;
env(noop(alice), msig(bogie), fee(2 * baseFee));
env.close();
expect (env.seq(alice) == aliceSeq + 1);
// Make sure multisign is disabled in production.
// NOTE: These four tests will fail when multisign is default enabled.
env.disable_testing();
aliceSeq = env.seq (alice);
env(noop(alice), msig(bogie), fee(2 * baseFee), ter(temINVALID));
env.close();
expect (env.seq(alice) == aliceSeq);
@@ -253,7 +247,7 @@ public:
void test_fee ()
{
using namespace jtx;
Env env(*this);
Env env(*this, features(featureMultiSign));
Account const alice {"alice", KeyType::ed25519};
env.fund(XRP(1000), alice);
env.close();
@@ -303,7 +297,7 @@ public:
void test_misorderedSigners()
{
using namespace jtx;
Env env(*this);
Env env(*this, features(featureMultiSign));
Account const alice {"alice", KeyType::ed25519};
env.fund(XRP(1000), alice);
env.close();
@@ -325,7 +319,7 @@ public:
void test_masterSigners()
{
using namespace jtx;
Env env(*this);
Env env(*this, features(featureMultiSign));
Account const alice {"alice", KeyType::ed25519};
Account const becky {"becky", KeyType::secp256k1};
Account const cheri {"cheri", KeyType::ed25519};
@@ -377,7 +371,7 @@ public:
void test_regularSigners()
{
using namespace jtx;
Env env(*this);
Env env(*this, features(featureMultiSign));
Account const alice {"alice", KeyType::secp256k1};
Account const becky {"becky", KeyType::ed25519};
Account const cheri {"cheri", KeyType::secp256k1};
@@ -436,7 +430,7 @@ public:
void test_heterogeneousSigners()
{
using namespace jtx;
Env env(*this);
Env env(*this, features(featureMultiSign));
Account const alice {"alice", KeyType::secp256k1};
Account const becky {"becky", KeyType::ed25519};
Account const cheri {"cheri", KeyType::secp256k1};
@@ -551,7 +545,7 @@ public:
void test_keyDisable()
{
using namespace jtx;
Env env(*this);
Env env(*this, features(featureMultiSign));
Account const alice {"alice", KeyType::ed25519};
env.fund(XRP(1000), alice);
@@ -626,7 +620,7 @@ public:
void test_regKey()
{
using namespace jtx;
Env env(*this);
Env env(*this, features(featureMultiSign));
Account const alice {"alice", KeyType::secp256k1};
env.fund(XRP(1000), alice);
@@ -658,7 +652,7 @@ public:
void test_txTypes()
{
using namespace jtx;
Env env(*this);
Env env(*this, features(featureMultiSign));
Account const alice {"alice", KeyType::secp256k1};
Account const becky {"becky", KeyType::ed25519};
Account const zelda {"zelda", KeyType::secp256k1};

View File

@@ -66,8 +66,7 @@ struct Regression_test : public beast::unit_test::suite
OpenView accum(&*next);
auto const result = ripple::apply(env.app(),
accum, *jt.stx, tapENABLE_TESTING,
env.journal);
accum, *jt.stx, tapNONE, env.journal);
expect(result.first == tesSUCCESS);
expect(result.second);
@@ -93,8 +92,7 @@ struct Regression_test : public beast::unit_test::suite
OpenView accum(&*next);
auto const result = ripple::apply(env.app(),
accum, *jt.stx, tapENABLE_TESTING,
env.journal);
accum, *jt.stx, tapNONE, env.journal);
expect(result.first == tecINSUFF_FEE);
expect(result.second);

View File

@@ -19,6 +19,7 @@
#include <BeastConfig.h>
#include <ripple/test/jtx.h>
#include <ripple/protocol/Feature.h>
#include <ripple/protocol/JsonFields.h>
namespace ripple {
@@ -52,13 +53,12 @@ struct SetAuth_test : public beast::unit_test::suite
auto const USD = gw["USD"];
{
Env env(*this);
env.disable_testing();
env.fund(XRP(100000), "alice", gw);
env(fset(gw, asfRequireAuth));
env(auth(gw, "alice", "USD"), ter(tecNO_LINE_REDUNDANT));
}
{
Env env(*this);
Env env(*this, features(featureTrustSetAuth));
env.fund(XRP(100000), "alice", "bob", gw);
env(fset(gw, asfRequireAuth));
env(auth(gw, "alice", "USD"));

View File

@@ -20,6 +20,7 @@
#include <BeastConfig.h>
#include <ripple/test/jtx.h>
#include <ripple/protocol/digest.h>
#include <ripple/protocol/Feature.h>
#include <ripple/protocol/Indexes.h>
#include <ripple/protocol/JsonFields.h>
#include <ripple/protocol/TxFlags.h>
@@ -145,15 +146,20 @@ struct SusPay_test : public beast::unit_test::suite
using namespace jtx;
using namespace std::chrono;
using S = seconds;
auto const c = cond("receipt");
{
Env env(*this, features(featureSusPay));
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob");
// syntax
env(condpay("alice", "bob", XRP(1000), c.first, T(S{1})));
}
{
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob");
auto const c = cond("receipt");
// syntax
env(condpay("alice", "bob", XRP(1000), c.first, T(S{1})));
env.disable_testing();
// disabled in production
env(condpay("alice", "bob", XRP(1000), c.first, T(S{1})), ter(temDISABLED));
env(finish("bob", "alice", 1), ter(temDISABLED));
@@ -168,7 +174,7 @@ struct SusPay_test : public beast::unit_test::suite
using namespace std::chrono;
using S = seconds;
{
Env env(*this);
Env env(*this, features(featureSusPay));
auto const alice = Account("alice");
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
@@ -190,7 +196,7 @@ struct SusPay_test : public beast::unit_test::suite
using namespace std::chrono;
using S = seconds;
{
Env env(*this);
Env env(*this, features(featureSusPay));
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob");
@@ -222,7 +228,7 @@ struct SusPay_test : public beast::unit_test::suite
using namespace std::chrono;
using S = seconds;
{
Env env(*this);
Env env(*this, features(featureSusPay));
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob");
@@ -244,7 +250,7 @@ struct SusPay_test : public beast::unit_test::suite
using namespace std::chrono;
using S = seconds;
{
Env env(*this);
Env env(*this, features(featureSusPay));
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
@@ -270,7 +276,7 @@ struct SusPay_test : public beast::unit_test::suite
env.close();
}
{
Env env(*this);
Env env(*this, features(featureSusPay));
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
@@ -287,7 +293,7 @@ struct SusPay_test : public beast::unit_test::suite
expect(! env.le(keylet::susPay(Account("alice").id(), seq)));
}
{
Env env(*this);
Env env(*this, features(featureSusPay));
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
@@ -306,7 +312,7 @@ struct SusPay_test : public beast::unit_test::suite
env.require(balance("carol", XRP(5000)));
}
{
Env env(*this);
Env env(*this, features(featureSusPay));
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
@@ -318,7 +324,7 @@ struct SusPay_test : public beast::unit_test::suite
env(finish("bob", "alice", seq, cx.first, cx.second), ter(tecNO_PERMISSION));
}
{
Env env(*this);
Env env(*this, features(featureSusPay));
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
@@ -338,7 +344,7 @@ struct SusPay_test : public beast::unit_test::suite
using namespace jtx;
using namespace std::chrono;
using S = seconds;
Env env(*this);
Env env(*this, features(featureSusPay));
auto T = [&env](NetClock::duration const& d)
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");

View File

@@ -20,6 +20,7 @@
#include <BeastConfig.h>
#include <ripple/app/tx/impl/CancelTicket.h>
#include <ripple/basics/Log.h>
#include <ripple/protocol/Feature.h>
#include <ripple/protocol/Indexes.h>
#include <ripple/ledger/View.h>
@@ -28,10 +29,9 @@ namespace ripple {
TER
CancelTicket::preflight (PreflightContext const& ctx)
{
#if ! RIPPLE_ENABLE_TICKETS
if (! (ctx.flags & tapENABLE_TESTING))
if (! ctx.rules.enabled(featureTickets,
ctx.app.config().features))
return temDISABLED;
#endif
auto const ret = preflight1 (ctx);
if (!isTesSuccess (ret))

View File

@@ -21,6 +21,7 @@
#include <ripple/app/tx/impl/CreateTicket.h>
#include <ripple/app/ledger/Ledger.h>
#include <ripple/basics/Log.h>
#include <ripple/protocol/Feature.h>
#include <ripple/protocol/Indexes.h>
namespace ripple {
@@ -28,10 +29,9 @@ namespace ripple {
TER
CreateTicket::preflight (PreflightContext const& ctx)
{
#if ! RIPPLE_ENABLE_TICKETS
if (! (ctx.flags & tapENABLE_TESTING))
if (! ctx.rules.enabled(featureTickets,
ctx.app.config().features))
return temDISABLED;
#endif
auto const ret = preflight1 (ctx);
if (!isTesSuccess (ret))

View File

@@ -253,9 +253,8 @@ SetAccount::doApply ()
// Account has no regular key or multi-signer signer list.
// Prevent transaction changes until we're ready.
if (view().flags() & tapENABLE_TESTING ||
view().rules().enabled(featureMultiSign,
ctx_.app.config().features))
if (view().rules().enabled(featureMultiSign,
ctx_.app.config().features))
return tecNO_ALTERNATIVE_KEY;
return tecNO_REGULAR_KEY;

View File

@@ -73,9 +73,8 @@ SetSignerList::determineOperation(STTx const& tx,
TER
SetSignerList::preflight (PreflightContext const& ctx)
{
if (! (ctx.flags & tapENABLE_TESTING) &&
! ctx.rules.enabled(featureMultiSign,
ctx.app.config().features))
if (! ctx.rules.enabled(featureMultiSign,
ctx.app.config().features))
return temDISABLED;
auto const ret = preflight1 (ctx);

View File

@@ -430,9 +430,7 @@ SetTrust::doApply ()
else if (! saLimitAmount && // Setting default limit.
(! bQualityIn || ! uQualityIn) && // Not setting quality in or setting default quality in.
(! bQualityOut || ! uQualityOut) && // Not setting quality out or setting default quality out.
(! ((view().flags() & tapENABLE_TESTING) ||
view().rules().enabled(featureTrustSetAuth,
ctx_.app.config().features)) || ! bSetAuth))
(! (view().rules().enabled(featureTrustSetAuth, ctx_.app.config().features)) || ! bSetAuth))
{
j_.trace <<
"Redundant: Setting non-existent ripple line to defaults.";

View File

@@ -131,8 +131,7 @@ namespace ripple {
TER
SusPayCreate::preflight (PreflightContext const& ctx)
{
if (! (ctx.flags & tapENABLE_TESTING) &&
! ctx.rules.enabled(featureSusPay,
if (! ctx.rules.enabled(featureSusPay,
ctx.app.config().features))
return temDISABLED;
@@ -251,8 +250,7 @@ SusPayCreate::doApply()
TER
SusPayFinish::preflight (PreflightContext const& ctx)
{
if (! (ctx.flags & tapENABLE_TESTING) &&
! ctx.rules.enabled(featureSusPay,
if (! ctx.rules.enabled(featureSusPay,
ctx.app.config().features))
return temDISABLED;
@@ -371,8 +369,7 @@ SusPayFinish::doApply()
TER
SusPayCancel::preflight (PreflightContext const& ctx)
{
if (! (ctx.flags & tapENABLE_TESTING) &&
! ctx.rules.enabled(featureSusPay,
if (! ctx.rules.enabled(featureSusPay,
ctx.app.config().features))
return temDISABLED;

View File

@@ -314,8 +314,7 @@ TER
Transactor::checkSign (PreclaimContext const& ctx)
{
// Make sure multisigning is enabled before we check for multisignatures.
if ((ctx.flags & tapENABLE_TESTING) ||
(ctx.view.rules().enabled(featureMultiSign,
if ((ctx.view.rules().enabled(featureMultiSign,
ctx.app.config().features)))
{
auto pk =

View File

@@ -83,9 +83,8 @@ checkValidity(HashRouter& router,
ApplyFlags const& flags)
{
auto const allowMultiSign =
(flags & tapENABLE_TESTING) ||
(rules.enabled(featureMultiSign,
config.features));
rules.enabled(featureMultiSign,
config.features);
return checkValidity(router, tx, allowMultiSign);
}

View File

@@ -35,6 +35,7 @@ feature (const char* name);
/** @} */
extern uint256 const featureMultiSign;
extern uint256 const featureTickets;
extern uint256 const featureSusPay;
extern uint256 const featureTrustSetAuth;
extern uint256 const featureFeeEscalation;

View File

@@ -46,8 +46,8 @@ feature (const char* name)
}
uint256 const featureMultiSign = feature("MultiSign");
uint256 const featureTickets = feature("Tickets");
uint256 const featureSusPay = feature("SusPay");
uint256 const featureTrustSetAuth = feature("TrustSetAuth");
uint256 const featureFeeEscalation = feature("FeeEscalation");
} // ripple

View File

@@ -22,6 +22,7 @@
#include <ripple/core/LoadFeeTrack.h>
#include <ripple/json/json_reader.h>
#include <ripple/protocol/ErrorCodes.h>
#include <ripple/protocol/Feature.h>
#include <ripple/rpc/impl/TransactionSign.h>
#include <ripple/test/jtx.h>
#include <beast/unit_test/suite.h>
@@ -1648,7 +1649,7 @@ public:
// "b" (not in the ledger) is rDg53Haik2475DJx8bjMDSDPj4VX7htaMd.
// "c" (phantom signer) is rPcNzota6B8YBokhYtcTNqQVCngtbnWfux.
test::jtx::Env env(*this);
test::jtx::Env env(*this, test::jtx::features(featureMultiSign));
env.fund(test::jtx::XRP(100000), a, g);
env.close();

View File

@@ -21,6 +21,7 @@
#include <ripple/basics/Log.h>
#include <ripple/test/jtx.h>
#include <ripple/json/to_string.h>
#include <ripple/protocol/Feature.h>
#include <ripple/protocol/TxFlags.h>
#include <beast/hash/uhash.h>
#include <beast/unit_test/suite.h>
@@ -352,7 +353,7 @@ public:
{
using namespace jtx;
Env env(*this);
Env env(*this, features(featureMultiSign));
env.fund(XRP(10000), "alice");
env(signers("alice", 1,
{ { "alice", 1 }, { "bob", 2 } }), ter(temBAD_SIGNER));
@@ -381,14 +382,12 @@ public:
ticket::create("alice", 60, "bob");
{
Env env(*this);
Env env(*this, features(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)));
env(ticket::create("alice"), require(owners("alice", 2), tickets("alice", 2)));
}
Env env(*this);
}
struct UDT