diff --git a/src/ripple/app/tests/Regression_test.cpp b/src/ripple/app/tests/Regression_test.cpp index 75dcb082c..df7fe7639 100644 --- a/src/ripple/app/tests/Regression_test.cpp +++ b/src/ripple/app/tests/Regression_test.cpp @@ -146,7 +146,7 @@ struct Regression_test : public beast::unit_test::suite (sfSigningPubKey, std::move(pubKeyBlob.first)); jt.stx.reset (secp256r1Sig.release()); - env (jt, ter (temBAD_SIGNATURE)); + env (jt, ter (temINVALID)); }; Account const alice {"alice", KeyType::secp256k1}; diff --git a/src/ripple/net/RPCCall.h b/src/ripple/net/RPCCall.h index a131ec4c0..4779a4e82 100644 --- a/src/ripple/net/RPCCall.h +++ b/src/ripple/net/RPCCall.h @@ -25,6 +25,7 @@ #include #include #include +#include #include namespace ripple { @@ -53,6 +54,12 @@ void fromNetwork ( std::function callbackFuncP = std::function ()); } +/** Internal invocation of RPC client. +*/ +std::pair +rpcClient(std::vector const& args, + Config const& config, Logs& logs); + } // ripple #endif diff --git a/src/ripple/net/impl/RPCCall.cpp b/src/ripple/net/impl/RPCCall.cpp index 98f966da5..201dd6ed8 100644 --- a/src/ripple/net/impl/RPCCall.cpp +++ b/src/ripple/net/impl/RPCCall.cpp @@ -1079,18 +1079,18 @@ struct RPCCallImp }; //------------------------------------------------------------------------------ -namespace RPCCall { -int fromCommandLine ( - Config const& config, - const std::vector& vCmd, - Logs& logs) +std::pair +rpcClient(std::vector const& args, + Config const& config, Logs& logs) { - if (vCmd.empty ()) - return 1; // 1 = print usage. + static_assert(rpcBAD_SYNTAX == 1 && rpcSUCCESS == 0, + "Expect specific rpc enum values."); + if (args.empty ()) + return { rpcBAD_SYNTAX, {} }; // rpcBAD_SYNTAX = print usage + int nRet = rpcSUCCESS; Json::Value jvOutput; - int nRet = 0; Json::Value jvRequest (Json::objectValue); auto rpcJ = logs.journal ("RPCParser"); @@ -1099,15 +1099,15 @@ int fromCommandLine ( RPCParser rpParser (rpcJ); Json::Value jvRpcParams (Json::arrayValue); - for (int i = 1; i != vCmd.size (); i++) - jvRpcParams.append (vCmd[i]); + for (int i = 1; i != args.size (); i++) + jvRpcParams.append (args[i]); Json::Value jvRpc = Json::Value (Json::objectValue); - jvRpc["method"] = vCmd[0]; + jvRpc["method"] = args[0]; jvRpc[jss::params] = jvRpcParams; - jvRequest = rpParser.parseCommand (vCmd[0], jvRpcParams, true); + jvRequest = rpParser.parseCommand (args[0], jvRpcParams, true); JLOG (rpcJ.trace) << "RPC Request: " << jvRequest << std::endl; @@ -1147,7 +1147,7 @@ int fromCommandLine ( { boost::asio::io_service isService; - fromNetwork ( + RPCCall::fromNetwork ( isService, setup.client.ip, setup.client.port, @@ -1155,7 +1155,7 @@ int fromCommandLine ( setup.client.password, "", jvRequest.isMember ("method") // Allow parser to rewrite method. - ? jvRequest["method"].asString () : vCmd[0], + ? jvRequest["method"].asString () : args[0], jvParams, // Parsed, execute. setup.client.secure != 0, // Use SSL config.QUIET, @@ -1196,7 +1196,7 @@ int fromCommandLine ( nRet = jvOutput.isMember (jss::error_code) ? beast::lexicalCast (jvOutput[jss::error_code].asString ()) - : 1; + : rpcBAD_SYNTAX; } // YYY We could have a command line flag for single line output for scripts. @@ -1209,9 +1209,24 @@ int fromCommandLine ( nRet = rpcINTERNAL; } - std::cout << jvOutput.toStyledString (); + return { nRet, std::move(jvOutput) }; +} - return nRet; +//------------------------------------------------------------------------------ + +namespace RPCCall { + +int fromCommandLine ( + Config const& config, + const std::vector& vCmd, + Logs& logs) +{ + auto const result = rpcClient(vCmd, config, logs); + + if (result.first != rpcBAD_SYNTAX) + std::cout << result.second.toStyledString (); + + return result.first; } //------------------------------------------------------------------------------ diff --git a/src/ripple/test/jtx/Env.h b/src/ripple/test/jtx/Env.h index 7b3f91e5e..0e330b0ce 100644 --- a/src/ripple/test/jtx/Env.h +++ b/src/ripple/test/jtx/Env.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -44,10 +45,12 @@ #include #include #include +#include #include #include #include #include +#include namespace ripple { namespace test { @@ -420,6 +423,11 @@ public: std::shared_ptr meta(); + /** Execute a client command */ + template + std::pair + rpc (Arg&& arg0, Args&&... args); + private: void fund (bool setDefaultRipple, @@ -620,6 +628,18 @@ protected: AccountID, Account> map_; }; +//------------------------------------------------------------------------------ + +template +std::pair +Env::rpc (Arg&& arg0, Args&&... args) +{ + std::vector v({ std::forward(arg0), + std::forward(args)... }); + return rpcClient(v, + app().config(), app().logs()); +} + } // jtx } // test } // ripple diff --git a/src/ripple/test/jtx/impl/Env.cpp b/src/ripple/test/jtx/impl/Env.cpp index c6cf775ba..0c442c26f 100644 --- a/src/ripple/test/jtx/impl/Env.cpp +++ b/src/ripple/test/jtx/impl/Env.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +63,8 @@ setupConfigForUnitTests (Config& config) config.legacy("database_path", ""); config.RUN_STANDALONE = true; + config.QUIET = true; + config.SILENT = true; config["server"].append("port_peer"); config["port_peer"].set("ip", "127.0.0.1"); config["port_peer"].set("port", "8080"); @@ -88,6 +91,8 @@ Env::AppBundle::AppBundle(std::unique_ptr config) auto timeKeeper_ = std::make_unique(); timeKeeper = timeKeeper_.get(); + // Hack so we dont have to call Config::setup + HTTPClient::initializeSSLContext(*config); owned = make_Application(std::move(config), std::move(logs), std::move(timeKeeper_)); app = owned.get(); @@ -258,14 +263,16 @@ Env::submit (JTx const& jt) if (jt.stx) { txid_ = jt.stx->getTransactionID(); - app().openLedger().modify( - [&](OpenView& view, beast::Journal j) - { - std::tie(ter_, didApply) = app().getTxQ().apply( - app(), view, jt.stx, applyFlags(), - beast::Journal{}); - return didApply; - }); + Serializer s; + jt.stx->add(s); + auto const result = rpc("submit", strHex(s.slice())); + if (result.first == rpcSUCCESS && + result.second["result"].isMember("engine_result_code")) + ter_ = static_cast( + result.second["result"]["engine_result_code"].asInt()); + else + ter_ = temINVALID; + didApply = isTesSuccess(ter_) || isTecClaim(ter_); } else { diff --git a/src/ripple/test/jtx/impl/Env_test.cpp b/src/ripple/test/jtx/impl/Env_test.cpp index 0cf6ad709..f7635b73b 100644 --- a/src/ripple/test/jtx/impl/Env_test.cpp +++ b/src/ripple/test/jtx/impl/Env_test.cpp @@ -290,21 +290,21 @@ public: auto const gw = Account("gateway"); auto const USD = gw["USD"]; - env(pay(env.master, "alice", XRP(1000)), fee(none), ter(temMALFORMED)); - env(pay(env.master, "alice", XRP(1000)), fee(1), ter(telINSUF_FEE_P)); - env(pay(env.master, "alice", XRP(1000)), seq(none), ter(temMALFORMED)); - env(pay(env.master, "alice", XRP(1000)), seq(2), ter(terPRE_SEQ)); - env(pay(env.master, "alice", XRP(1000)), sig(none), ter(temMALFORMED)); - env(pay(env.master, "alice", XRP(1000)), sig("bob"), ter(tefBAD_AUTH_MASTER)); - - env(pay(env.master, "dilbert", XRP(1000)), sig(env.master)); - env.fund(XRP(10000), "alice", "bob", "carol", gw); env.require(balance("alice", XRP(10000))); env.require(balance("bob", XRP(10000))); env.require(balance("carol", XRP(10000))); env.require(balance(gw, XRP(10000))); + env(pay(env.master, "alice", XRP(1000)), fee(none), ter(temMALFORMED)); + env(pay(env.master, "alice", XRP(1000)), fee(1), ter(telINSUF_FEE_P)); + env(pay(env.master, "alice", XRP(1000)), seq(none), ter(temMALFORMED)); + env(pay(env.master, "alice", XRP(1000)), seq(20), ter(terPRE_SEQ)); + env(pay(env.master, "alice", XRP(1000)), sig(none), ter(temMALFORMED)); + env(pay(env.master, "alice", XRP(1000)), sig("bob"), ter(tefBAD_AUTH_MASTER)); + + env(pay(env.master, "dilbert", XRP(1000)), sig(env.master)); + env.trust(USD(100), "alice", "bob", "carol"); env.require(owners("alice", 1), lines("alice", 1)); env(rate(gw, 1.05));