diff --git a/src/BeastConfig.h b/src/BeastConfig.h index 4851307551..082e7c8539 100644 --- a/src/BeastConfig.h +++ b/src/BeastConfig.h @@ -171,15 +171,6 @@ #define RIPPLE_ENABLE_TICKETS 0 #endif -/** Config: RIPPLE_ENABLE_MULTI_SIGN - When set, activates the current state of the multi-sign feature which is - under development. When the feature is complete and released this - #define should be removed. -*/ -#ifndef RIPPLE_ENABLE_MULTI_SIGN -#define RIPPLE_ENABLE_MULTI_SIGN 0 -#endif - // Uses OpenSSL instead of alternatives #ifndef RIPPLE_USE_OPENSSL #define RIPPLE_USE_OPENSSL 0 diff --git a/src/ripple/app/main/Main.cpp b/src/ripple/app/main/Main.cpp index 3c1b214f15..91aeea8004 100644 --- a/src/ripple/app/main/Main.cpp +++ b/src/ripple/app/main/Main.cpp @@ -146,14 +146,10 @@ void printHelp (const po::options_description& desc) " version\n" " server_info\n" " sign [offline]\n" -#if RIPPLE_ENABLE_MULTI_SIGN " sign_for\n" -#endif // RIPPLE_ENABLE_MULTI_SIGN " stop\n" " submit |[ ]\n" -#if RIPPLE_ENABLE_MULTI_SIGN " submit_multisigned\n" -#endif // RIPPLE_ENABLE_MULTI_SIGN " tx \n" " validation_create [||]\n" " validation_seed [||]\n" diff --git a/src/ripple/app/misc/NetworkOPs.cpp b/src/ripple/app/misc/NetworkOPs.cpp index 1647aec64b..922b7cc43e 100644 --- a/src/ripple/app/misc/NetworkOPs.cpp +++ b/src/ripple/app/misc/NetworkOPs.cpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -675,7 +676,10 @@ void NetworkOPsImp::submitTransaction (Job&, STTx::pointer iTrans) { try { - if (! passesLocalChecks (*trans, reason) || ! trans->checkSign ()) + // Tell the call to checkSign() whether multisign is enabled. + if (!passesLocalChecks (*trans, reason) || + !trans->checkSign (m_ledgerMaster.getValidatedRules().enabled( + featureMultiSign, getConfig().features))) { m_journal.warning << "Submitted transaction " << (reason.empty () ? "has bad signature" : "error: " + reason); diff --git a/src/ripple/app/tests/MultiSign.test.cpp b/src/ripple/app/tests/MultiSign.test.cpp index 993ba1c1bc..2f9a78e5b8 100644 --- a/src/ripple/app/tests/MultiSign.test.cpp +++ b/src/ripple/app/tests/MultiSign.test.cpp @@ -219,7 +219,7 @@ public: expect (env.seq(alice) == aliceSeq + 1); // Make sure multisign is disabled in production. - // NOTE: THESE FOUR TESTS FAIL IF RIPPLE_ENABLE_MULTI_SIGN != 0 + // 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)); diff --git a/src/ripple/app/tx/impl/SetAccount.cpp b/src/ripple/app/tx/impl/SetAccount.cpp index 628bdd98f8..cc560c7703 100644 --- a/src/ripple/app/tx/impl/SetAccount.cpp +++ b/src/ripple/app/tx/impl/SetAccount.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -197,8 +198,8 @@ SetAccount::doApply () // Account has no regular key or multi-signer signer list. // Prevent transaction changes until we're ready. - if ((RIPPLE_ENABLE_MULTI_SIGN) || - view().flags() & tapENABLE_TESTING) + if (view().flags() & tapENABLE_TESTING || + view().rules().enabled(featureMultiSign, ctx_.config.features)) return tecNO_ALTERNATIVE_KEY; return tecNO_REGULAR_KEY; diff --git a/src/ripple/app/tx/impl/SetSignerList.cpp b/src/ripple/app/tx/impl/SetSignerList.cpp index e5257f8d6b..c148b01640 100644 --- a/src/ripple/app/tx/impl/SetSignerList.cpp +++ b/src/ripple/app/tx/impl/SetSignerList.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -74,10 +75,10 @@ SetSignerList::determineOperation(STTx const& tx, TER SetSignerList::preflight (PreflightContext const& ctx) { -#if ! RIPPLE_ENABLE_MULTI_SIGN - if (! (ctx.flags & tapENABLE_TESTING)) + if (! (ctx.flags & tapENABLE_TESTING) && + ! ctx.rules.enabled(featureMultiSign, + ctx.config.features)) return temDISABLED; -#endif auto const ret = preflight1 (ctx); if (!isTesSuccess (ret)) diff --git a/src/ripple/app/tx/impl/Transaction.cpp b/src/ripple/app/tx/impl/Transaction.cpp index c3937a36f8..7d3b31d61b 100644 --- a/src/ripple/app/tx/impl/Transaction.cpp +++ b/src/ripple/app/tx/impl/Transaction.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -89,11 +90,14 @@ Transaction::pointer Transaction::sharedTransaction ( bool Transaction::checkSign (std::string& reason, SigVerify sigVerify) const { + bool const allowMultiSign = getApp().getLedgerMaster(). + getValidatedRules().enabled (featureMultiSign, getConfig().features); + if (! mFromPubKey.isValid ()) reason = "Transaction has bad source public key"; - else if (!sigVerify(*mTransaction, [] (STTx const& tx) + else if (!sigVerify(*mTransaction, [allowMultiSign] (STTx const& tx) { - return tx.checkSign(); + return tx.checkSign(allowMultiSign); })) reason = "Transaction has bad signature"; else diff --git a/src/ripple/app/tx/impl/Transactor.cpp b/src/ripple/app/tx/impl/Transactor.cpp index 1e31a55a19..cf90758e8a 100644 --- a/src/ripple/app/tx/impl/Transactor.cpp +++ b/src/ripple/app/tx/impl/Transactor.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -70,12 +71,8 @@ preflight2 (PreflightContext const& ctx) { return (ctx.flags & tapNO_CHECK_SIGN) || tx.checkSign( -#if RIPPLE_ENABLE_MULTI_SIGN - true -#else - ctx.flags & tapENABLE_TESTING -#endif - ); + (ctx.flags & tapENABLE_TESTING) || + (ctx.rules.enabled(featureMultiSign, ctx.config.features))); })) { JLOG(ctx.j.debug) << "preflight2: bad signature"; @@ -258,12 +255,11 @@ TER Transactor::apply () TER Transactor::checkSign () { -#if RIPPLE_ENABLE_MULTI_SIGN -#else - if(view().flags() & tapENABLE_TESTING) -#endif + // Make sure multisigning is enabled before we check for multisignatures. + if ((view().flags() & tapENABLE_TESTING) || + (view().rules().enabled(featureMultiSign, ctx_.config.features))) { - // If the mSigningPubKey is empty, then we must be multi-signing. + // If the mSigningPubKey is empty, then we must be multisigning. if (mSigningPubKey.getAccountPublic ().empty ()) return checkMultiSign (); } diff --git a/src/ripple/net/impl/RPCCall.cpp b/src/ripple/net/impl/RPCCall.cpp index e824192b83..e5dda8a181 100644 --- a/src/ripple/net/impl/RPCCall.cpp +++ b/src/ripple/net/impl/RPCCall.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -922,13 +923,9 @@ public: { "random", &RPCParser::parseAsIs, 0, 0 }, { "ripple_path_find", &RPCParser::parseRipplePathFind, 1, 2 }, { "sign", &RPCParser::parseSignSubmit, 2, 3 }, -#if RIPPLE_ENABLE_MULTI_SIGN { "sign_for", &RPCParser::parseSignFor, 4, 4 }, -#endif // RIPPLE_ENABLE_MULTI_SIGN { "submit", &RPCParser::parseSignSubmit, 1, 3 }, -#if RIPPLE_ENABLE_MULTI_SIGN { "submit_multisigned", &RPCParser::parseSubmitMultiSigned, 1, 1 }, -#endif // RIPPLE_ENABLE_MULTI_SIGN { "server_info", &RPCParser::parseAsIs, 0, 0 }, { "server_state", &RPCParser::parseAsIs, 0, 0 }, { "stop", &RPCParser::parseAsIs, 0, 0 }, diff --git a/src/ripple/protocol/Feature.h b/src/ripple/protocol/Feature.h index 3519bd9327..2eea444b0b 100644 --- a/src/ripple/protocol/Feature.h +++ b/src/ripple/protocol/Feature.h @@ -34,6 +34,7 @@ uint256 feature (const char* name); /** @} */ +extern uint256 const featureMultiSign; extern uint256 const featureSusPay; } // ripple diff --git a/src/ripple/protocol/STTx.h b/src/ripple/protocol/STTx.h index ac19ddb389..6a7a4c7316 100644 --- a/src/ripple/protocol/STTx.h +++ b/src/ripple/protocol/STTx.h @@ -122,13 +122,7 @@ public: void sign (RippleAddress const& private_key); - bool checkSign(bool allowMultiSign = -#if RIPPLE_ENABLE_MULTI_SIGN - true -#else - false -#endif - ) const; + bool checkSign(bool allowMultiSign) const; // SQL Functions with metadata. static diff --git a/src/ripple/protocol/impl/Feature.cpp b/src/ripple/protocol/impl/Feature.cpp index 5825de38b7..d37e0431fe 100644 --- a/src/ripple/protocol/impl/Feature.cpp +++ b/src/ripple/protocol/impl/Feature.cpp @@ -45,6 +45,7 @@ feature (const char* name) return feature(name, std::strlen(name)); } +uint256 const featureMultiSign = feature("MultiSign"); uint256 const featureSusPay = feature("SusPay"); } // ripple diff --git a/src/ripple/protocol/tests/STTx.test.cpp b/src/ripple/protocol/tests/STTx.test.cpp index 427f7c9ed0..516de5268c 100644 --- a/src/ripple/protocol/tests/STTx.test.cpp +++ b/src/ripple/protocol/tests/STTx.test.cpp @@ -44,7 +44,7 @@ public: j.setFieldVL (sfMessageKey, publicAcct.getAccountPublic ()); j.sign (privateAcct); - unexpected (!j.checkSign (), "Transaction fails signature test"); + unexpected (!j.checkSign (true), "Transaction fails signature test"); Serializer rawTxn; j.add (rawTxn); diff --git a/src/ripple/rpc/handlers/SignFor.cpp b/src/ripple/rpc/handlers/SignFor.cpp index 4c82ef94a3..763b3599e9 100755 --- a/src/ripple/rpc/handlers/SignFor.cpp +++ b/src/ripple/rpc/handlers/SignFor.cpp @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ /* This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2012-2014 Ripple Labs Inc. + Copyright (c) 2012-2015 Ripple Labs Inc. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -18,10 +18,9 @@ //============================================================================== #include -#include -#include -#include -#include +#include +#include +#include #include #include #include @@ -35,11 +34,16 @@ namespace ripple { // } Json::Value doSignFor (RPC::Context& context) { + // Bail if multisign is not enabled. + if (! getApp().getLedgerMaster().getValidatedRules(). + enabled (featureMultiSign, getConfig().features)) + { + RPC::inject_error (rpcNOT_ENABLED, context.params); + return context.params; + } context.loadType = Resource::feeHighBurdenRPC; - NetworkOPs::FailHard const failType = - NetworkOPs::doFailHard ( - context.params.isMember ("fail_hard") - && context.params["fail_hard"].asBool ()); + auto const failHard = context.params[jss::fail_hard].asBool(); + auto const failType = NetworkOPs::doFailHard (failHard); return RPC::transactionSignFor ( context.params, failType, context.netOps, context.role); diff --git a/src/ripple/rpc/handlers/SubmitMultiSigned.cpp b/src/ripple/rpc/handlers/SubmitMultiSigned.cpp index a8ed8e08ac..1462a3dac5 100644 --- a/src/ripple/rpc/handlers/SubmitMultiSigned.cpp +++ b/src/ripple/rpc/handlers/SubmitMultiSigned.cpp @@ -1,10 +1,12 @@ //------------------------------------------------------------------------------ /* This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2012-2014 Ripple Labs Inc. + Copyright (c) 2012-2015 Ripple Labs Inc. + Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR @@ -16,8 +18,9 @@ //============================================================================== #include -#include -#include +#include +#include +#include #include #include #include @@ -30,11 +33,16 @@ namespace ripple { // } Json::Value doSubmitMultiSigned (RPC::Context& context) { + // Bail if multisign is not enabled. + if (! getApp().getLedgerMaster().getValidatedRules(). + enabled (featureMultiSign, getConfig().features)) + { + RPC::inject_error (rpcNOT_ENABLED, context.params); + return context.params; + } context.loadType = Resource::feeHighBurdenRPC; - - NetworkOPs::FailHard const failType = NetworkOPs::doFailHard ( - context.params.isMember ("fail_hard") - && context.params["fail_hard"].asBool ()); + auto const failHard = context.params[jss::fail_hard].asBool(); + auto const failType = NetworkOPs::doFailHard (failHard); return RPC::transactionSubmitMultiSigned ( context.params, failType, context.netOps, context.role); diff --git a/src/ripple/rpc/impl/Handler.cpp b/src/ripple/rpc/impl/Handler.cpp index f80a29dece..e0721816f7 100644 --- a/src/ripple/rpc/impl/Handler.cpp +++ b/src/ripple/rpc/impl/Handler.cpp @@ -58,9 +58,12 @@ Status handle (Context& context, Object& object) class HandlerTable { public: - HandlerTable (std::vector const& entries) { - for (auto& entry: entries) + template + HandlerTable (const Handler(&entries)[N]) + { + for (std::size_t i = 0; i < N; ++i) { + auto const& entry = entries[i]; assert (table_.find(entry.name_) == table_.end()); table_[entry.name_] = entry; } @@ -70,7 +73,7 @@ class HandlerTable { addHandler(); } - const Handler* getHandler(std::string name) { + const Handler* getHandler(std::string name) const { auto i = table_.find(name); return i == table_.end() ? nullptr : &i->second; } @@ -94,7 +97,7 @@ class HandlerTable { }; }; -HandlerTable HANDLERS({ +Handler handlerArray[] { // Some handlers not specified here are added to the table via addHandler() // Request-response methods { "account_info", byRef (&doAccountInfo), Role::USER, NO_CONDITION }, @@ -133,13 +136,9 @@ HandlerTable HANDLERS({ { "random", byRef (&doRandom), Role::USER, NO_CONDITION }, { "ripple_path_find", byRef (&doRipplePathFind), Role::USER, NO_CONDITION }, { "sign", byRef (&doSign), Role::USER, NO_CONDITION }, -#if RIPPLE_ENABLE_MULTI_SIGN - { "sign_for", byRef (&doSignFor), Role::USER, NO_CONDITION }, -#endif // RIPPLE_ENABLE_MULTI_SIGN + { "sign_for", byRef (&doSignFor), Role::USER, NO_CONDITION }, { "submit", byRef (&doSubmit), Role::USER, NEEDS_CURRENT_LEDGER }, -#if RIPPLE_ENABLE_MULTI_SIGN { "submit_multisigned", byRef (&doSubmitMultiSigned), Role::USER, NEEDS_CURRENT_LEDGER }, -#endif // RIPPLE_ENABLE_MULTI_SIGN { "server_info", byRef (&doServerInfo), Role::USER, NO_CONDITION }, { "server_state", byRef (&doServerState), Role::USER, NO_CONDITION }, { "stop", byRef (&doStop), Role::ADMIN, NO_CONDITION }, @@ -161,12 +160,13 @@ HandlerTable HANDLERS({ // Evented methods { "subscribe", byRef (&doSubscribe), Role::USER, NO_CONDITION }, { "unsubscribe", byRef (&doUnsubscribe), Role::USER, NO_CONDITION }, -}); +}; } // namespace const Handler* getHandler(std::string const& name) { - return HANDLERS.getHandler(name); + static beast::static_initializer const handlers(handlerArray); + return handlers->getHandler(name); } } // RPC diff --git a/src/ripple/unity/rpcx.cpp b/src/ripple/unity/rpcx.cpp index 580dd4b8b9..f00834e666 100644 --- a/src/ripple/unity/rpcx.cpp +++ b/src/ripple/unity/rpcx.cpp @@ -72,8 +72,8 @@ #include #include #include -#include #include +#include #include #include #include