From 2aa11fa41d4a7849ae6a5d7a11df6f367191e3ef Mon Sep 17 00:00:00 2001 From: Peng Wang Date: Mon, 11 Nov 2019 10:48:51 -0500 Subject: [PATCH] Support API versioning --- Builds/CMake/RippledCore.cmake | 1 + src/ripple/app/main/Application.cpp | 4 +- src/ripple/net/impl/RPCCall.cpp | 15 + src/ripple/protocol/jss.h | 4 + src/ripple/rpc/Context.h | 1 + src/ripple/rpc/RPCHandler.h | 2 +- src/ripple/rpc/impl/Handler.cpp | 64 +++-- src/ripple/rpc/impl/Handler.h | 2 +- src/ripple/rpc/impl/RPCHandler.cpp | 6 +- src/ripple/rpc/impl/RPCHelpers.cpp | 19 ++ src/ripple/rpc/impl/RPCHelpers.h | 46 +++ src/ripple/rpc/impl/ServerHandlerImp.cpp | 51 +++- src/test/app/Path_test.cpp | 7 +- src/test/rpc/RPCCall_test.cpp | 344 +++++++++++++++++++++-- src/test/rpc/Version_test.cpp | 200 +++++++++++++ src/test/unity/rpc_test_unity.cpp | 1 + 16 files changed, 714 insertions(+), 53 deletions(-) create mode 100644 src/test/rpc/Version_test.cpp diff --git a/Builds/CMake/RippledCore.cmake b/Builds/CMake/RippledCore.cmake index 8e57785791f..bd98a5d4195 100644 --- a/Builds/CMake/RippledCore.cmake +++ b/Builds/CMake/RippledCore.cmake @@ -989,6 +989,7 @@ else () src/test/rpc/TransactionEntry_test.cpp src/test/rpc/TransactionHistory_test.cpp src/test/rpc/ValidatorRPC_test.cpp + src/test/rpc/Version_test.cpp #[===============================[ nounity, test sources: subdir: server diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 705617dd657..0e4e2aaf133 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -61,6 +61,7 @@ #include #include #include +#include #include #include @@ -1583,7 +1584,8 @@ bool ApplicationImp::setup() Resource::Charge loadType = Resource::feeReferenceRPC; Resource::Consumer c; RPC::Context context { journal ("RPCHandler"), jvCommand, *this, - loadType, getOPs (), getLedgerMaster (), c, Role::ADMIN}; + loadType, getOPs (), getLedgerMaster(), c, Role::ADMIN, + RPC::ApiMaximumSupportedVersion}; Json::Value jvResult; RPC::doCommand (context, jvResult); diff --git a/src/ripple/net/impl/RPCCall.cpp b/src/ripple/net/impl/RPCCall.cpp index da4e2caa43b..96ded73d53a 100644 --- a/src/ripple/net/impl/RPCCall.cpp +++ b/src/ripple/net/impl/RPCCall.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -1360,6 +1361,20 @@ rpcCmdLineToJson (std::vector const& args, jvRequest = rpParser.parseCommand (args[0], jvRpcParams, true); + auto insert_api_version = [](Json::Value & jr){ + if( jr.isObject() && + !jr.isMember(jss::error) && + !jr.isMember(jss::api_version)) + { + jr[jss::api_version] = RPC::ApiMaximumSupportedVersion; + } + }; + + if(jvRequest.isObject()) + insert_api_version(jvRequest); + else if(jvRequest.isArray()) + std::for_each(jvRequest.begin(), jvRequest.end(), insert_api_version); + JLOG (j.trace()) << "RPC Request: " << jvRequest << std::endl; return jvRequest; } diff --git a/src/ripple/protocol/jss.h b/src/ripple/protocol/jss.h index f7a7f563f05..de235198e17 100644 --- a/src/ripple/protocol/jss.h +++ b/src/ripple/protocol/jss.h @@ -123,6 +123,8 @@ JSS ( alternatives ); // out: PathRequest, RipplePathFind JSS ( amendment_blocked ); // out: NetworkOPs JSS ( amendments ); // in: AccountObjects, out: NetworkOPs JSS ( amount ); // out: AccountChannels +JSS ( api_version); // in: many, out: Version +JSS ( api_version_low); // out: Version JSS ( applied ); // out: SubmitTransaction JSS ( asks ); // out: Subscribe JSS ( assets ); // out: GatewayBalances @@ -265,6 +267,8 @@ JSS ( index ); // in: LedgerEntry, DownloadShard // field JSS ( info ); // out: ServerInfo, ConsensusInfo, FetchInfo JSS ( internal_command ); // in: Internal +JSS ( invalid_API_version ); // out: Many, when a request has an invalid + // version JSS ( io_latency_ms ); // out: NetworkOPs JSS ( ip ); // in: Connect, out: OverlayImpl JSS ( issuer ); // in: RipplePathFind, Subscribe, diff --git a/src/ripple/rpc/Context.h b/src/ripple/rpc/Context.h index 31c7df8e5e7..2c7ca557219 100644 --- a/src/ripple/rpc/Context.h +++ b/src/ripple/rpc/Context.h @@ -55,6 +55,7 @@ struct Context LedgerMaster& ledgerMaster; Resource::Consumer& consumer; Role role; + unsigned int apiVersion; std::shared_ptr coro {}; InfoSub::pointer infoSub {}; Headers headers {}; diff --git a/src/ripple/rpc/RPCHandler.h b/src/ripple/rpc/RPCHandler.h index 1dbcee49ff2..13cd521f95b 100644 --- a/src/ripple/rpc/RPCHandler.h +++ b/src/ripple/rpc/RPCHandler.h @@ -33,7 +33,7 @@ struct Context; /** Execute an RPC command and store the results in a Json::Value. */ Status doCommand (RPC::Context&, Json::Value&); -Role roleRequired (std::string const& method ); +Role roleRequired (unsigned int version, std::string const& method ); } // RPC } // ripple diff --git a/src/ripple/rpc/impl/Handler.cpp b/src/ripple/rpc/impl/Handler.cpp index c0055957f38..c34795470ca 100644 --- a/src/ripple/rpc/impl/Handler.cpp +++ b/src/ripple/rpc/impl/Handler.cpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace ripple { namespace RPC { @@ -129,16 +130,21 @@ class HandlerTable { explicit HandlerTable (const Handler(&entries)[N]) { - for (std::size_t i = 0; i < N; ++i) + for(auto v = RPC::ApiMinimumSupportedVersion; v <= RPC::ApiMaximumSupportedVersion; ++v) { - auto const& entry = entries[i]; - assert (table_.find(entry.name_) == table_.end()); - table_[entry.name_] = entry; + for (std::size_t i = 0; i < N; ++i) + { + auto & innerTable = table_[versionToIndex(v)]; + auto const& entry = entries[i]; + assert (innerTable.find(entry.name_) == innerTable.end()); + innerTable[entry.name_] = entry; + } + + // This is where the new-style handlers are added. + // This is also where different versions of handlers are added. + addHandler(v); + addHandler(v); } - - // This is where the new-style handlers are added. - addHandler(); - addHandler(); } public: @@ -148,29 +154,38 @@ class HandlerTable { return handlerTable; } - Handler const* getHandler(std::string name) const + Handler const* getHandler(unsigned version, std::string name) const { - auto i = table_.find(name); - return i == table_.end() ? nullptr : &i->second; + if(version > RPC::ApiMaximumSupportedVersion || version < RPC::ApiMinimumSupportedVersion) + return nullptr; + auto & innerTable = table_[versionToIndex(version)]; + auto i = innerTable.find(name); + return i == innerTable.end() ? nullptr : &i->second; } std::vector getHandlerNames() const { - std::vector ret; - ret.reserve(table_.size()); - for (auto const& i : table_) - ret.push_back(i.second.name_); - return ret; + std::unordered_set name_set; + for ( int index = 0; index < table_.size(); ++index) + { + for(auto const& h : table_[index]) + { + name_set.insert(h.second.name_); + } + } + return std::vector(name_set.begin(), name_set.end()); } private: - std::map table_; + std::array, APINumberVersionSupported> table_; template - void addHandler() + void addHandler(unsigned version) { - assert (table_.find(HandlerImpl::name()) == table_.end()); + assert (version >= RPC::ApiMinimumSupportedVersion && version <= RPC::ApiMaximumSupportedVersion); + auto & innerTable = table_[versionToIndex(version)]; + assert (innerTable.find(HandlerImpl::name()) == innerTable.end()); Handler h; h.name_ = HandlerImpl::name(); @@ -178,15 +193,20 @@ class HandlerTable { h.role_ = HandlerImpl::role(); h.condition_ = HandlerImpl::condition(); - table_[HandlerImpl::name()] = h; + innerTable[HandlerImpl::name()] = h; + } + + inline unsigned versionToIndex(unsigned version) const + { + return version - RPC::ApiMinimumSupportedVersion; } }; } // namespace -Handler const* getHandler(std::string const& name) +Handler const* getHandler(unsigned version, std::string const& name) { - return HandlerTable::instance().getHandler(name); + return HandlerTable::instance().getHandler(version, name); } std::vector diff --git a/src/ripple/rpc/impl/Handler.h b/src/ripple/rpc/impl/Handler.h index dcc6a8a19a2..15014c8fa83 100644 --- a/src/ripple/rpc/impl/Handler.h +++ b/src/ripple/rpc/impl/Handler.h @@ -51,7 +51,7 @@ struct Handler RPC::Condition condition_; }; -Handler const* getHandler (std::string const&); +Handler const* getHandler (unsigned int version, std::string const&); /** Return a Json::objectValue with a single entry. */ template diff --git a/src/ripple/rpc/impl/RPCHandler.cpp b/src/ripple/rpc/impl/RPCHandler.cpp index 5d686906aed..1b6d81a7efc 100644 --- a/src/ripple/rpc/impl/RPCHandler.cpp +++ b/src/ripple/rpc/impl/RPCHandler.cpp @@ -141,7 +141,7 @@ error_code_i fillHandler (Context& context, JLOG (context.j.trace()) << "COMMAND:" << strCommand; JLOG (context.j.trace()) << "REQUEST:" << context.params; - auto handler = getHandler(strCommand); + auto handler = getHandler(context.apiVersion, strCommand); if (!handler) return rpcUNKNOWN_COMMAND; @@ -296,9 +296,9 @@ Status doCommand ( return rpcUNKNOWN_COMMAND; } -Role roleRequired (std::string const& method) +Role roleRequired (unsigned int version, std::string const& method) { - auto handler = RPC::getHandler(method); + auto handler = RPC::getHandler(version, method); if (!handler) return Role::FORBID; diff --git a/src/ripple/rpc/impl/RPCHelpers.cpp b/src/ripple/rpc/impl/RPCHelpers.cpp index b1b83d6f062..5409e73bc0d 100644 --- a/src/ripple/rpc/impl/RPCHelpers.cpp +++ b/src/ripple/rpc/impl/RPCHelpers.cpp @@ -716,5 +716,24 @@ beast::SemanticVersion const firstVersion("1.0.0"); beast::SemanticVersion const goodVersion("1.0.0"); beast::SemanticVersion const lastVersion("1.0.0"); +unsigned int getAPIVersionNumber(Json::Value const& jv) +{ + static Json::Value const minVersion (RPC::ApiMinimumSupportedVersion); + static Json::Value const maxVersion (RPC::ApiMaximumSupportedVersion); + static Json::Value const invalidVersion (RPC::APIInvalidVersion); + + Json::Value requestedVersion(RPC::APIVersionIfUnspecified); + if(jv.isObject()) + { + requestedVersion = jv.get (jss::api_version, requestedVersion); + } + if( !(requestedVersion.isInt() || requestedVersion.isUInt()) || + requestedVersion < minVersion || requestedVersion > maxVersion) + { + requestedVersion = invalidVersion; + } + return requestedVersion.asUInt(); +} + } // RPC } // ripple diff --git a/src/ripple/rpc/impl/RPCHelpers.h b/src/ripple/rpc/impl/RPCHelpers.h index 63d09d15eaa..981f352dbbc 100644 --- a/src/ripple/rpc/impl/RPCHelpers.h +++ b/src/ripple/rpc/impl/RPCHelpers.h @@ -114,10 +114,42 @@ parseRippleLibSeed(Json::Value const& params); std::pair keypairForSignature(Json::Value const& params, Json::Value& error); +/** + * API version numbers used in API version 1 + */ extern beast::SemanticVersion const firstVersion; extern beast::SemanticVersion const goodVersion; extern beast::SemanticVersion const lastVersion; +/** + * API version numbers used in later API versions + * + * Requests with a version number in the range + * [ApiMinimumSupportedVersion, ApiMaximumSupportedVersion] + * are supported. + * + * Network Requests without explicit version numbers use + * APIVersionIfUnspecified. APIVersionIfUnspecified is 1, + * because all the RPC requests with a version >= 2 must + * explicitly specify the version in the requests. + * Note that APIVersionIfUnspecified will be lower than + * ApiMinimumSupportedVersion when we stop supporting API + * version 1. + * + * Command line Requests use ApiMaximumSupportedVersion. + */ + +constexpr unsigned int APIInvalidVersion = 0; +constexpr unsigned int APIVersionIfUnspecified = 1; +constexpr unsigned int ApiMinimumSupportedVersion = 1; +constexpr unsigned int ApiMaximumSupportedVersion = 1; +constexpr unsigned int APINumberVersionSupported = ApiMaximumSupportedVersion - + ApiMinimumSupportedVersion + 1; + +static_assert (ApiMinimumSupportedVersion >= APIVersionIfUnspecified); +static_assert (ApiMaximumSupportedVersion >= ApiMinimumSupportedVersion); + + template void setVersion(Object& parent) @@ -131,6 +163,20 @@ setVersion(Object& parent) std::pair chooseLedgerEntryType(Json::Value const& params); +/** + * Retrieve the api version number from the json value + * + * Note that APIInvalidVersion will be returned if + * 1) the version number field has a wrong format + * 2) the version number retrieved is out of the supported range + * 3) the version number is unspecified and + * APIVersionIfUnspecified is out of the supported range + * + * @param value a Json value that may or may not specifies + * the api version number + * @return the api version number + */ +unsigned int getAPIVersionNumber(const Json::Value & value); } // RPC } // ripple diff --git a/src/ripple/rpc/impl/ServerHandlerImp.cpp b/src/ripple/rpc/impl/ServerHandlerImp.cpp index 4212b1901e9..9ec6e8808dc 100644 --- a/src/ripple/rpc/impl/ServerHandlerImp.cpp +++ b/src/ripple/rpc/impl/ServerHandlerImp.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -398,7 +399,9 @@ ServerHandlerImp::processSession( Resource::Charge loadType = Resource::feeReferenceRPC; try { - if ((!jv.isMember(jss::command) && !jv.isMember(jss::method)) || + auto apiVersion = RPC::getAPIVersionNumber(jv); + if (apiVersion == RPC::APIInvalidVersion || + (!jv.isMember(jss::command) && !jv.isMember(jss::method)) || (jv.isMember(jss::command) && !jv[jss::command].isString()) || (jv.isMember(jss::method) && !jv[jss::method].isString()) || (jv.isMember(jss::command) && jv.isMember(jss::method) && @@ -406,7 +409,8 @@ ServerHandlerImp::processSession( { jr[jss::type] = jss::response; jr[jss::status] = jss::error; - jr[jss::error] = jss::missingCommand; + jr[jss::error] = apiVersion == RPC::APIInvalidVersion ? + jss::invalid_API_version : jss::missingCommand; jr[jss::request] = jv; if (jv.isMember (jss::id)) jr[jss::id] = jv[jss::id]; @@ -414,12 +418,15 @@ ServerHandlerImp::processSession( jr[jss::jsonrpc] = jv[jss::jsonrpc]; if (jv.isMember(jss::ripplerpc)) jr[jss::ripplerpc] = jv[jss::ripplerpc]; + if (jv.isMember(jss::api_version)) + jr[jss::api_version] = jv[jss::api_version]; is->getConsumer().charge(Resource::feeInvalidRPC); return jr; } - auto required = RPC::roleRequired(jv.isMember(jss::command) ? + auto required = RPC::roleRequired(apiVersion, + jv.isMember(jss::command) ? jv[jss::command].asString() : jv[jss::method].asString()); auto role = requestRole( @@ -444,6 +451,7 @@ ServerHandlerImp::processSession( app_.getLedgerMaster(), is->getConsumer(), role, + apiVersion, coro, is, {is->user(), is->forwarded_for()} @@ -500,6 +508,9 @@ ServerHandlerImp::processSession( jr[jss::jsonrpc] = jv[jss::jsonrpc]; if (jv.isMember(jss::ripplerpc)) jr[jss::ripplerpc] = jv[jss::ripplerpc]; + if (jv.isMember(jss::api_version)) + jr[jss::api_version] = jv[jss::api_version]; + jr[jss::type] = jss::response; return jr; } @@ -545,6 +556,7 @@ make_json_error(Json::Int code, Json::Value&& message) Json::Int constexpr method_not_found = -32601; Json::Int constexpr server_overloaded = -32604; Json::Int constexpr forbidden = -32605; +Json::Int constexpr wrong_version = -32606; void ServerHandlerImp::processRequest (Port const& port, @@ -597,11 +609,40 @@ ServerHandlerImp::processRequest (Port const& port, continue; } + auto apiVersion = RPC::APIVersionIfUnspecified; + if (jsonRPC.isMember(jss::params) && + jsonRPC[jss::params].isArray() && + jsonRPC[jss::params].size() > 0 && + jsonRPC[jss::params][0u].isObject()) + { + apiVersion = RPC::getAPIVersionNumber(jsonRPC[jss::params][Json::UInt(0)]); + } + + if ( apiVersion == RPC::APIVersionIfUnspecified && batch) + { + // for batch request, api_version may be at a different level + apiVersion = RPC::getAPIVersionNumber(jsonRPC); + } + + if(apiVersion == RPC::APIInvalidVersion) + { + if (!batch) + { + HTTPReply (400, jss::invalid_API_version.c_str(), output, rpcJ); + return; + } + Json::Value r(Json::objectValue); + r[jss::request] = jsonRPC; + r[jss::error] = make_json_error(wrong_version, jss::invalid_API_version.c_str()); + reply.append(r); + continue; + } + /* ------------------------------------------------------------------ */ auto role = Role::FORBID; auto required = Role::FORBID; if (jsonRPC.isMember(jss::method) && jsonRPC[jss::method].isString()) - required = RPC::roleRequired(jsonRPC[jss::method].asString()); + required = RPC::roleRequired(apiVersion, jsonRPC[jss::method].asString()); if (jsonRPC.isMember(jss::params) && jsonRPC[jss::params].isArray() && @@ -778,7 +819,7 @@ ServerHandlerImp::processRequest (Port const& port, Resource::Charge loadType = Resource::feeReferenceRPC; RPC::Context context {m_journal, params, app_, loadType, m_networkOPs, - app_.getLedgerMaster(), usage, role, coro, InfoSub::pointer(), + app_.getLedgerMaster(), usage, role, apiVersion, coro, InfoSub::pointer(), {user, forwardedFor}}; Json::Value result; RPC::doCommand (context, result); diff --git a/src/test/app/Path_test.cpp b/src/test/app/Path_test.cpp index 1d38d54e2af..589ced35c28 100644 --- a/src/test/app/Path_test.cpp +++ b/src/test/app/Path_test.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -221,7 +222,8 @@ class Path_test : public beast::unit_test::suite Resource::Charge loadType = Resource::feeReferenceRPC; Resource::Consumer c; RPC::Context context { env.journal, {}, app, loadType, - app.getOPs(), app.getLedgerMaster(), c, Role::USER}; + app.getOPs(), app.getLedgerMaster(), c, Role::USER, + RPC::APIVersionIfUnspecified}; Json::Value params = Json::objectValue; params[jss::command] = "ripple_path_find"; @@ -320,7 +322,8 @@ class Path_test : public beast::unit_test::suite Resource::Charge loadType = Resource::feeReferenceRPC; Resource::Consumer c; RPC::Context context {env.journal, {}, app, loadType, - app.getOPs(), app.getLedgerMaster(), c, Role::USER}; + app.getOPs(), app.getLedgerMaster(), c, Role::USER, + RPC::APIVersionIfUnspecified}; Json::Value result; gate g; // Test RPC::Tuning::max_src_cur source currencies. diff --git a/src/test/rpc/RPCCall_test.cpp b/src/test/rpc/RPCCall_test.cpp index 66de1670443..186da9a11ac 100644 --- a/src/test/rpc/RPCCall_test.cpp +++ b/src/test/rpc/RPCCall_test.cpp @@ -20,10 +20,12 @@ #include #include #include +#include #include #include #include +#include namespace ripple { namespace test { @@ -77,6 +79,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_channels", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" } ] @@ -94,6 +97,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_channels", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "destination_account" : "FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210" } @@ -112,6 +116,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_channels", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "destination_account" : "closed" } @@ -130,6 +135,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_channels", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "destination_account" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA" } @@ -149,6 +155,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_channels", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "destination_account" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA", "ledger_hash" : "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" @@ -169,6 +176,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_channels", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "destination_account" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA", "ledger_index" : 90210 @@ -245,6 +253,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_currencies", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" } ] @@ -262,6 +271,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_currencies", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "strict" : 1 } @@ -280,6 +290,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_currencies", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 42 } @@ -298,6 +309,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_currencies", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : "validated" } @@ -353,6 +365,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_currencies", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 0 } @@ -389,6 +402,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_currencies", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "3.14159", "strict" : 1 } @@ -408,6 +422,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_info", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" } ] @@ -425,6 +440,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_info", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 77777 } @@ -443,6 +459,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_info", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : "closed" } @@ -461,6 +478,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_info", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_hash" : "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" } @@ -480,6 +498,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_info", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "strict" : 1 } @@ -576,6 +595,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_lines", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", } ] @@ -593,6 +613,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_lines", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "peer" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA" } @@ -612,6 +633,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_lines", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 888888888, "peer" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA" @@ -632,6 +654,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_lines", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : "closed", "peer" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA" @@ -652,6 +675,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_lines", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_hash" : "FFFFEEEEDDDDCCCCBBBBAAAA9999888877776666555544443333222211110000", "peer" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA" @@ -691,6 +715,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_lines", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 12345678, "peer" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA" @@ -714,6 +739,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_lines", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 12345678, "peer" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA" @@ -774,6 +800,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_lines", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" } ] @@ -792,6 +819,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_lines", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 0, "peer" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA" @@ -812,6 +840,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_objects", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" } ] @@ -829,6 +858,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_objects", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 77777 } @@ -847,6 +877,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_objects", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : "closed" } @@ -865,6 +896,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_objects", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_hash" : "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" } @@ -884,6 +916,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_objects", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "strict" : 1 } @@ -903,6 +936,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_objects", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : "validated", "strict" : 1 @@ -942,6 +976,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_objects", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "strict" : 1 } @@ -964,6 +999,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_objects", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "strict" : 1 } @@ -1025,6 +1061,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_objects", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 0 } @@ -1046,6 +1083,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_objects", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 0, "strict" : 1 @@ -1066,6 +1104,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" } ] @@ -1083,6 +1122,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 987654321 } @@ -1101,6 +1141,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : "validated" } @@ -1119,6 +1160,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_hash" : "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" } @@ -1138,6 +1180,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "strict" : 1 } @@ -1158,6 +1201,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : "validated", "strict" : 1 @@ -1197,6 +1241,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "strict" : 1 } @@ -1257,6 +1302,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 0 } @@ -1278,6 +1324,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 0, "strict" : 1 @@ -1298,6 +1345,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_tx", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", } ] @@ -1315,6 +1363,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_tx", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 444 } @@ -1336,6 +1385,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_tx", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "count" : true, "binary" : true, @@ -1358,6 +1408,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_tx", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index_max" : -1, "ledger_index_min" : -1 @@ -1381,6 +1432,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_tx", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "binary" : true, "count" : true, @@ -1405,6 +1457,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_tx", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index_max" : -1, "ledger_index_min" : 247, @@ -1430,6 +1483,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_tx", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "binary" : true, "count" : true, @@ -1456,6 +1510,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_tx", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index_max" : 590, "ledger_index_min" : 589, @@ -1482,6 +1537,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_tx", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "count" : true, "descending" : true, @@ -1567,6 +1623,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "account_tx", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 0 } @@ -1674,6 +1731,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "book_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "taker_gets" : { "currency" : "EUR" }, @@ -1696,6 +1754,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "book_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "taker_gets" : { "currency" : "EUR", "issuer" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA" @@ -1723,6 +1782,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "book_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "issuer" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA", "taker_gets" : { "currency" : "EUR" @@ -1748,6 +1808,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "book_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "issuer" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA", "ledger_index" : 666, "taker_gets" : { @@ -1775,6 +1836,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "book_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "issuer" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA", "ledger_index" : "current", "taker_gets" : { @@ -1802,6 +1864,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "book_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "issuer" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA", "ledger_hash" : "ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789", "taker_gets" : { @@ -1832,6 +1895,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "book_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "issuer" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA", "ledger_hash" : "ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789", "limit" : 200, @@ -1866,6 +1930,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "book_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "issuer" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA", "ledger_hash" : "ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789", "limit" : 200, @@ -1977,6 +2042,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "book_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "issuer" : "not_a_valid_issuer", "taker_gets" : { "currency" : "EUR" @@ -2002,6 +2068,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "book_offers", "params" : [ { + "api_version" : %MAX_API_VER%, "issuer" : "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA", "ledger_index" : 0, "taker_gets" : { @@ -2039,7 +2106,12 @@ static RPCCallTestData const rpcCallTestArray [] = }, RPCCallTestData::no_exception, R"({ - "method" : "can_delete" + "method" : "can_delete", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -2053,6 +2125,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "can_delete", "params" : [ { + "api_version" : %MAX_API_VER%, "can_delete" : 4294967295 } ] @@ -2069,6 +2142,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "can_delete", "params" : [ { + "api_version" : %MAX_API_VER%, "can_delete" : "FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210" } ] @@ -2085,6 +2159,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "can_delete", "params" : [ { + "api_version" : %MAX_API_VER%, "can_delete" : "always" } ] @@ -2101,6 +2176,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "can_delete", "params" : [ { + "api_version" : %MAX_API_VER%, "can_delete" : "never" } ] @@ -2117,6 +2193,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "can_delete", "params" : [ { + "api_version" : %MAX_API_VER%, "can_delete" : "now" } ] @@ -2152,6 +2229,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "can_delete", "params" : [ { + "api_version" : %MAX_API_VER%, "can_delete" : "invalid" } ] @@ -2192,6 +2270,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "channel_authorize", "params" : [ { + "api_version" : %MAX_API_VER%, "amount" : "18446744073709551615", "channel_id" : "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF", "secret" : "secret_can_be_anything" @@ -2377,6 +2456,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "channel_verify", "params" : [ { + "api_version" : %MAX_API_VER%, "amount" : "0", "channel_id" : "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF", "public_key" : "aB4BXXLuPu8DpVuyq1DBiu3SrPdtK9AYZisKhu8mvkoiUD8J9Gov", @@ -2399,6 +2479,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "channel_verify", "params" : [ { + "api_version" : %MAX_API_VER%, "amount" : "18446744073709551615", "channel_id" : "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF", "public_key" : "021D93E21C44160A1B3B66DA1F37B86BE39FFEA3FC4B95FAA2063F82EE823599F6", @@ -2588,6 +2669,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "channel_verify", "params" : [ { + "api_version" : %MAX_API_VER%, "amount" : "40000000", "channel_id" : "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF", "public_key" : "aB4BXXLuPu8DpVuyq1DBiu3SrPdtK9AYZisKhu8mvkoiUD8J9Gov", @@ -2609,6 +2691,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "connect", "params" : [ { + "api_version" : %MAX_API_VER%, "ip" : "ThereIsNoCheckingOnTheIPFormat" } ] @@ -2626,6 +2709,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "connect", "params" : [ { + "api_version" : %MAX_API_VER%, "ip" : "ThereIsNoCheckingOnTheIPFormat", "port" : 6561 } @@ -2701,6 +2785,11 @@ static RPCCallTestData const rpcCallTestArray [] = RPCCallTestData::no_exception, R"({ "method" : "consensus_info", + "params" : [ + { + "api_version" : %MAX_API_VER% + } + ] })" }, { @@ -2735,6 +2824,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "deposit_authorized", "params" : [ { + "api_version" : %MAX_API_VER%, "destination_account" : "destination_account_NotValidated", "source_account" : "source_account_NotValidated" } @@ -2754,6 +2844,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "deposit_authorized", "params" : [ { + "api_version" : %MAX_API_VER%, "destination_account" : "destination_account_NotValidated", "ledger_index" : "validated", "source_account" : "source_account_NotValidated" @@ -2774,6 +2865,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "deposit_authorized", "params" : [ { + "api_version" : %MAX_API_VER%, "destination_account" : "destination_account_NotValidated", "ledger_index" : 4294967295, "source_account" : "source_account_NotValidated" @@ -2794,6 +2886,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "deposit_authorized", "params" : [ { + "api_version" : %MAX_API_VER%, "destination_account" : "destination_account_NotValidated", "ledger_hash" : "ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789", "source_account" : "source_account_NotValidated" @@ -2853,6 +2946,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "deposit_authorized", "params" : [ { + "api_version" : %MAX_API_VER%, "destination_account" : "destination_account_NotValidated", "ledger_index" : 0, "source_account" : "source_account_NotValidated" @@ -2874,6 +2968,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "download_shard", "params" : [ { + "api_version" : %MAX_API_VER%, "shards" : [ { "index" : 20, @@ -2897,6 +2992,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "download_shard", "params" : [ { + "api_version" : %MAX_API_VER%, "shards" : [ { "index" : 20, @@ -2926,6 +3022,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "download_shard", "params" : [ { + "api_version" : %MAX_API_VER%, "shards" : [ { "index" : 200000000, @@ -2969,6 +3066,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "download_shard", "params" : [ { + "api_version" : %MAX_API_VER%, "shards" : [ { "index" : 2000000, @@ -3038,6 +3136,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "download_shard", "params" : [ { + "api_version" : %MAX_API_VER%, "shards" : [ { "index" : 20, @@ -3112,6 +3211,11 @@ static RPCCallTestData const rpcCallTestArray [] = RPCCallTestData::no_exception, R"({ "method" : "feature", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -3125,6 +3229,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "feature", "params" : [ { + "api_version" : %MAX_API_VER%, "feature" : "featureNameOrHexIsNotValidated" } ] @@ -3142,6 +3247,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "feature", "params" : [ { + "api_version" : %MAX_API_VER%, "feature" : "FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210", "vetoed" : false } @@ -3160,6 +3266,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "feature", "params" : [ { + "api_version" : %MAX_API_VER%, "feature" : "0", "vetoed" : true } @@ -3215,6 +3322,11 @@ static RPCCallTestData const rpcCallTestArray [] = RPCCallTestData::no_exception, R"({ "method" : "fetch_info", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -3228,6 +3340,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "fetch_info", "params" : [ { + "api_version" : %MAX_API_VER%, "clear" : true } ] @@ -3263,6 +3376,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "fetch_info", "params" : [ { + "api_version" : %MAX_API_VER%, "too" : true } ] @@ -3281,6 +3395,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "gateway_balances", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", } ] @@ -3298,6 +3413,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "gateway_balances", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : "890765" } @@ -3316,6 +3432,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "gateway_balances", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : "current" } @@ -3334,6 +3451,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "gateway_balances", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_hash" : "0123456789ABCDEFGHIJKLMNOPQRSTUV0123456789ABCDEFGHIJKLMNOPQRSTUV" } @@ -3352,6 +3470,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "gateway_balances", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "hotwallet" : [ "hotwallet_is_not_validated" ] } @@ -3373,6 +3492,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "gateway_balances", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "hotwallet" : [ "hotwallet_is_not_validated_1", @@ -3482,7 +3602,12 @@ static RPCCallTestData const rpcCallTestArray [] = }, RPCCallTestData::no_exception, R"({ - "method" : "get_counts" + "method" : "get_counts", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -3496,6 +3621,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "get_counts", "params" : [ { + "api_version" : %MAX_API_VER%, "min_count" : 100 } ] @@ -3552,6 +3678,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "command", "params" : [ { + "api_version" : %MAX_API_VER%, "json_argument" : true, "method" : "command" } @@ -3570,6 +3697,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "command", "params" : [ { + "api_version" : %MAX_API_VER%, "method" : "command" } ] @@ -3666,6 +3794,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "call_1", "params" : [ { + "api_version" : %MAX_API_VER%, "id" : "A1", "jsonrpc" : "2.0", "method" : "call_1", @@ -3694,6 +3823,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "call_1", "params" : [ { + "api_version" : %MAX_API_VER%, "0" : { "inner_arg" : "yup" }, @@ -3718,6 +3848,7 @@ static RPCCallTestData const rpcCallTestArray [] = "params" : [ [ { + "api_version" : %MAX_API_VER%, "id" : "A1", "jsonrpc" : "2.0", "method" : "call_1", @@ -3745,6 +3876,7 @@ static RPCCallTestData const rpcCallTestArray [] = "params" : [ [ { + "api_version" : %MAX_API_VER%, "0" : { "inner_arg" : "yup" }, @@ -4053,7 +4185,12 @@ static RPCCallTestData const rpcCallTestArray [] = }, RPCCallTestData::no_exception, R"({ - "method" : "ledger" + "method" : "ledger", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -4067,6 +4204,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : 4294967295 } ] @@ -4083,6 +4221,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : "validated" } ] @@ -4099,6 +4238,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_hash" : "ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789" } ] @@ -4116,6 +4256,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger", "params" : [ { + "api_version" : %MAX_API_VER%, "full" : true, "ledger_index" : "current" } @@ -4134,6 +4275,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger", "params" : [ { + "api_version" : %MAX_API_VER%, "expand" : true, "ledger_index" : "closed", "transactions" : true @@ -4153,6 +4295,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : 4294967295 } ] @@ -4169,6 +4312,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : 0 } ] @@ -4185,6 +4329,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : 0 } ] @@ -4201,6 +4346,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : 0 } ] @@ -4218,6 +4364,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : "current" } ] @@ -4232,7 +4379,12 @@ static RPCCallTestData const rpcCallTestArray [] = }, RPCCallTestData::no_exception, R"({ - "method" : "ledger_closed" + "method" : "ledger_closed", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -4262,7 +4414,12 @@ static RPCCallTestData const rpcCallTestArray [] = }, RPCCallTestData::no_exception, R"({ - "method" : "ledger_current" + "method" : "ledger_current", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -4296,6 +4453,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger_header", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : 4294967295 } ] @@ -4312,6 +4470,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger_header", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_hash" : "ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789" } ] @@ -4364,6 +4523,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger_header", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : 0 } ] @@ -4380,6 +4540,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger_header", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : 0 } ] @@ -4396,6 +4557,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger_header", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : 0 } ] @@ -4414,6 +4576,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger_request", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : 4294967295 } ] @@ -4430,6 +4593,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger_request", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_hash" : "ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789" } ] @@ -4482,6 +4646,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger_request", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : 0 } ] @@ -4498,6 +4663,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger_request", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : 0 } ] @@ -4514,6 +4680,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ledger_request", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : 0 } ] @@ -4528,7 +4695,12 @@ static RPCCallTestData const rpcCallTestArray [] = }, RPCCallTestData::no_exception, R"({ - "method" : "log_level" + "method" : "log_level", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -4542,6 +4714,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "log_level", "params" : [ { + "api_version" : %MAX_API_VER%, "severity" : "fatal" } ] @@ -4558,6 +4731,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "log_level", "params" : [ { + "api_version" : %MAX_API_VER%, "severity" : "error" } ] @@ -4574,6 +4748,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "log_level", "params" : [ { + "api_version" : %MAX_API_VER%, "severity" : "warn" } ] @@ -4590,6 +4765,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "log_level", "params" : [ { + "api_version" : %MAX_API_VER%, "severity" : "debug" } ] @@ -4606,6 +4782,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "log_level", "params" : [ { + "api_version" : %MAX_API_VER%, "severity" : "trace" } ] @@ -4623,6 +4800,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "log_level", "params" : [ { + "api_version" : %MAX_API_VER%, "partition" : "base", "severity" : "trace" } @@ -4641,6 +4819,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "log_level", "params" : [ { + "api_version" : %MAX_API_VER%, "partition" : "partition_name", "severity" : "fatal" } @@ -4678,6 +4857,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "log_level", "params" : [ { + "api_version" : %MAX_API_VER%, "severity" : "err" } ] @@ -4695,6 +4875,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "log_level", "params" : [ { + "api_version" : %MAX_API_VER%, "partition" : "fatal", "severity" : "partition_name" } @@ -4710,7 +4891,12 @@ static RPCCallTestData const rpcCallTestArray [] = }, RPCCallTestData::no_exception, R"({ - "method" : "logrotate" + "method" : "logrotate", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -4744,6 +4930,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "owner_info", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" } ] @@ -4761,6 +4948,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "owner_info", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 987654321 } @@ -4779,6 +4967,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "owner_info", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : "validated" } @@ -4797,6 +4986,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "owner_info", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_hash" : "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" } @@ -4816,6 +5006,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "owner_info", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "strict" : 1 } @@ -4912,6 +5103,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "owner_info", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 0 } @@ -4949,7 +5141,12 @@ static RPCCallTestData const rpcCallTestArray [] = }, RPCCallTestData::no_exception, R"({ - "method" : "peers" + "method" : "peers", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -4979,7 +5176,12 @@ static RPCCallTestData const rpcCallTestArray [] = }, RPCCallTestData::no_exception, R"({ - "method" : "ping" + "method" : "ping", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -5009,7 +5211,12 @@ static RPCCallTestData const rpcCallTestArray [] = }, RPCCallTestData::no_exception, R"({ - "method" : "print" + "method" : "print", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -5024,6 +5231,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "print", "params" : [ { + "api_version" : %MAX_API_VER%, "params" : [ "extra" ] } ] @@ -5057,7 +5265,12 @@ static RPCCallTestData const rpcCallTestArray [] = }, RPCCallTestData::no_exception, R"({ - "method" : "random" + "method" : "random", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -5091,6 +5304,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ripple_path_find", "params" : [ { + "api_version" : %MAX_API_VER%, "json_argument" : true } ] @@ -5108,6 +5322,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ripple_path_find", "params" : [ { + "api_version" : %MAX_API_VER%, "json_argument" : true, "ledger_index" : 4294967295 } @@ -5126,6 +5341,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ripple_path_find", "params" : [ { + "api_version" : %MAX_API_VER%, "json_argument" : true, "ledger_index" : "closed" } @@ -5144,6 +5360,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ripple_path_find", "params" : [ { + "api_version" : %MAX_API_VER%, "json_argument" : true, "ledger_hash" : "0123456789ABCDEFGHIJKLMNOPQRSTUV0123456789ABCDEFGHIJKLMNOPQRSTUV" } @@ -5218,7 +5435,8 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ripple_path_find", "params" : [ { - "json_argument" : true, + "api_version" : %MAX_API_VER%, + "json_argument" : true, "ledger_index" : 0 } ] @@ -5236,6 +5454,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ripple_path_find", "params" : [ { + "api_version" : %MAX_API_VER%, "json_argument" : true, "ledger_index" : 0 } @@ -5254,6 +5473,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "ripple_path_find", "params" : [ { + "api_version" : %MAX_API_VER%, "json_argument" : true, "ledger_index" : 0 } @@ -5274,6 +5494,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "sign", "params" : [ { + "api_version" : %MAX_API_VER%, "secret" : "my_secret", "tx_json" : { "json_argument" : true @@ -5295,6 +5516,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "sign", "params" : [ { + "api_version" : %MAX_API_VER%, "offline" : true, "secret" : "my_secret", "tx_json" : { @@ -5397,6 +5619,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "sign_for", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "secret" : "my_secret", "tx_json" : { @@ -5420,6 +5643,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "sign_for", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "offline" : true, "secret" : "my_secret", @@ -5525,6 +5749,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "submit", "params" : [ { + "api_version" : %MAX_API_VER%, "tx_blob" : "the blob is unvalidated and may be any length..." } ] @@ -5542,6 +5767,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "submit", "params" : [ { + "api_version" : %MAX_API_VER%, "secret" : "my_secret", "tx_json" : { "json_argument" : true @@ -5581,6 +5807,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "submit", "params" : [ { + "api_version" : %MAX_API_VER%, "offline" : true, "secret" : "my_secret", "tx_json" : { @@ -5663,6 +5890,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "submit_multisigned", "params" : [ { + "api_version" : %MAX_API_VER%, "tx_json" : { "json_argument" : true } @@ -5735,6 +5963,11 @@ static RPCCallTestData const rpcCallTestArray [] = RPCCallTestData::no_exception, R"({ "method" : "server_info", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -5748,6 +5981,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "server_info", "params" : [ { + "api_version" : %MAX_API_VER%, "counters" : true } ] @@ -5781,6 +6015,11 @@ static RPCCallTestData const rpcCallTestArray [] = RPCCallTestData::no_exception, R"({ "method" : "server_info", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, @@ -5793,6 +6032,11 @@ static RPCCallTestData const rpcCallTestArray [] = RPCCallTestData::no_exception, R"({ "method" : "server_state", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -5806,6 +6050,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "server_state", "params" : [ { + "api_version" : %MAX_API_VER%, "counters" : true } ] @@ -5839,6 +6084,11 @@ static RPCCallTestData const rpcCallTestArray [] = RPCCallTestData::no_exception, R"({ "method" : "server_state", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, @@ -5851,6 +6101,11 @@ static RPCCallTestData const rpcCallTestArray [] = RPCCallTestData::no_exception, R"({ "method" : "stop", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -5885,6 +6140,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "transaction_entry", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : 4294967295, "tx_hash" : "0123456789ABCDEFGHIJKLMNOPQRSTUV0123456789ABCDEFGHIJKLMNOPQRSTUV" } @@ -5903,6 +6159,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "transaction_entry", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_index" : "current", "tx_hash" : "0123456789ABCDEFGHIJKLMNOPQRSTUV0123456789ABCDEFGHIJKLMNOPQRSTUV" } @@ -5921,6 +6178,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "transaction_entry", "params" : [ { + "api_version" : %MAX_API_VER%, "ledger_hash" : "VUTSRQPONMLKJIHGFEDCBA9876543210VUTSRQPONMLKJIHGFEDCBA9876543210", "tx_hash" : "0123456789ABCDEFGHIJKLMNOPQRSTUV0123456789ABCDEFGHIJKLMNOPQRSTUV" } @@ -6092,6 +6350,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "tx", "params" : [ { + "api_version" : %MAX_API_VER%, "transaction" : "transaction_hash_is_not_validated" } ] @@ -6109,6 +6368,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "tx", "params" : [ { + "api_version" : %MAX_API_VER%, "binary" : true, "transaction" : "transaction_hash_is_not_validated" } @@ -6166,6 +6426,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "tx", "params" : [ { + "api_version" : %MAX_API_VER%, "transaction" : "transaction_hash_is_not_validated" } ] @@ -6184,6 +6445,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "tx_account", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", } ] @@ -6201,6 +6463,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "tx_account", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 4294967295 } @@ -6222,6 +6485,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "tx_account", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "binary" : true, "count" : true, @@ -6244,6 +6508,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "tx_account", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index_max" : 2147483647, "ledger_index_min" : 2147483647 @@ -6267,6 +6532,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "tx_account", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "binary" : true, "count" : true, @@ -6291,6 +6557,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "tx_account", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index_max" : 2147483647, "ledger_index_min" : -1, @@ -6316,6 +6583,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "tx_account", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "binary" : true, "count" : true, @@ -6400,6 +6668,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "tx_account", "params" : [ { + "api_version" : %MAX_API_VER%, "account" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index" : 0 } @@ -6513,7 +6782,8 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "tx_history", "params" : [ { - "start" : 0 + "api_version" : %MAX_API_VER%, + "start" : 0 } ] })" @@ -6594,6 +6864,11 @@ static RPCCallTestData const rpcCallTestArray [] = RPCCallTestData::no_exception, R"({ "method" : "unl_list", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -6623,7 +6898,12 @@ static RPCCallTestData const rpcCallTestArray [] = }, RPCCallTestData::no_exception, R"({ - "method" : "validation_create" + "method" : "validation_create", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -6637,6 +6917,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "validation_create", "params" : [ { + "api_version" : %MAX_API_VER%, "secret" : "the form of the secret is not validated" } ] @@ -6671,6 +6952,11 @@ static RPCCallTestData const rpcCallTestArray [] = RPCCallTestData::no_exception, R"({ "method" : "version", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -6700,7 +6986,12 @@ static RPCCallTestData const rpcCallTestArray [] = }, RPCCallTestData::no_exception, R"({ - "method" : "wallet_propose" + "method" : "wallet_propose", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -6714,6 +7005,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "wallet_propose", "params" : [ { + "api_version" : %MAX_API_VER%, "passphrase" : "the form of the passphrase is not validated" } ] @@ -6751,6 +7043,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "internal", "params" : [ { + "api_version" : %MAX_API_VER%, "internal_command" : "command_name", "params" : [] } @@ -6773,6 +7066,7 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "internal", "params" : [ { + "api_version" : %MAX_API_VER%, "internal_command" : "command_name", "params" : [ "string_arg", "1", "-1", "4294967296", "3.14159" ] } @@ -6928,7 +7222,12 @@ static RPCCallTestData const rpcCallTestArray [] = }, RPCCallTestData::no_exception, R"({ - "method" : "unknown_command" + "method" : "unknown_command", + "params" : [ + { + "api_version" : %MAX_API_VER%, + } + ] })" }, { @@ -6946,14 +7245,23 @@ static RPCCallTestData const rpcCallTestArray [] = "method" : "unknown_command", "params" : [ { + "api_version" : %MAX_API_VER%, "params" : [ "string_arg", "1", "-1", "4294967296", "3.14159" ] } ] })" }, - }; +std::string updateAPIVersionString(const char * const req) +{ + static std::string version_str = std::to_string(RPC::ApiMaximumSupportedVersion); + static auto place_holder = "%MAX_API_VER%"; + std::string jr(req); + boost::replace_all(jr, place_holder, version_str); + return jr; +} + class RPCCall_test : public beast::unit_test::suite { public: @@ -6992,7 +7300,7 @@ class RPCCall_test : public beast::unit_test::suite } Json::Value exp; - Json::Reader{}.parse (rpcCallTest.exp, exp); + Json::Reader{}.parse (updateAPIVersionString(rpcCallTest.exp), exp); // Lambda to remove the "params[0u]:error_code" field if present. // Error codes are not expected to be stable between releases. diff --git a/src/test/rpc/Version_test.cpp b/src/test/rpc/Version_test.cpp new file mode 100644 index 00000000000..2d5e7f04348 --- /dev/null +++ b/src/test/rpc/Version_test.cpp @@ -0,0 +1,200 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012-2017 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 + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include +#include +#include + +namespace ripple { + +class Version_test : public beast::unit_test::suite +{ + void + testCorrectVersionNumber() + { + testcase ("right api_version: explicitly specified or filled by parser"); + + using namespace test::jtx; + Env env {*this}; + + auto isCorrectReply = [](Json::Value const & re) -> bool + { + if(re.isMember(jss::error)) + return false; + return re.isMember(jss::version); + }; + + auto jrr = env.rpc("json", "version", "{\"api_version\": " + + std::to_string(RPC::ApiMaximumSupportedVersion) + + "}") [jss::result]; + BEAST_EXPECT(isCorrectReply(jrr)); + + jrr = env.rpc("version") [jss::result]; + BEAST_EXPECT(isCorrectReply(jrr)); + } + + void + testWrongVersionNumber() + { + testcase ("wrong api_version: too low, too high, or wrong format"); + + using namespace test::jtx; + Env env {*this}; + + auto get_error_what = [](Json::Value const &re) -> std::string + { + if (re.isMember("error_what")) + if (re["error_what"].isString()) + return re["error_what"].asString(); + return {}; + }; + + auto re = env.rpc("json", "version", "{\"api_version\": " + + std::to_string(RPC::ApiMinimumSupportedVersion - 1) + + "}"); + BEAST_EXPECT(get_error_what(re).find(jss::invalid_API_version.c_str())); + + re = env.rpc("json", "version", "{\"api_version\": " + + std::to_string(RPC::ApiMaximumSupportedVersion + 1) + + "}"); + BEAST_EXPECT(get_error_what(re).find(jss::invalid_API_version.c_str())); + + re = env.rpc("json", "version", "{\"api_version\": \"a\"}"); + BEAST_EXPECT(get_error_what(re).find(jss::invalid_API_version.c_str())); + } + + void testGetAPIVersionNumber() + { + testcase ("test getAPIVersionNumber function"); + + unsigned int versionIfUnspecified = + RPC::APIVersionIfUnspecified < RPC::ApiMinimumSupportedVersion ? + RPC::APIInvalidVersion : RPC::APIVersionIfUnspecified; + + Json::Value j_array = Json::Value (Json::arrayValue); + Json::Value j_null = Json::Value (Json::nullValue); + BEAST_EXPECT(RPC::getAPIVersionNumber(j_array) == versionIfUnspecified); + BEAST_EXPECT(RPC::getAPIVersionNumber(j_null) == versionIfUnspecified); + + Json::Value j_object = Json::Value (Json::objectValue); + BEAST_EXPECT(RPC::getAPIVersionNumber(j_object) == versionIfUnspecified); + j_object[jss::api_version] = RPC::APIVersionIfUnspecified; + BEAST_EXPECT(RPC::getAPIVersionNumber(j_object) == versionIfUnspecified); + + j_object[jss::api_version] = RPC::ApiMinimumSupportedVersion; + BEAST_EXPECT(RPC::getAPIVersionNumber(j_object) == RPC::ApiMinimumSupportedVersion); + j_object[jss::api_version] = RPC::ApiMaximumSupportedVersion; + BEAST_EXPECT(RPC::getAPIVersionNumber(j_object) == RPC::ApiMaximumSupportedVersion); + + j_object[jss::api_version] = RPC::ApiMinimumSupportedVersion - 1; + BEAST_EXPECT(RPC::getAPIVersionNumber(j_object) == RPC::APIInvalidVersion); + j_object[jss::api_version] = RPC::ApiMaximumSupportedVersion + 1; + BEAST_EXPECT(RPC::getAPIVersionNumber(j_object) == RPC::APIInvalidVersion); + + j_object[jss::api_version] = RPC::APIInvalidVersion; + BEAST_EXPECT(RPC::getAPIVersionNumber(j_object) == RPC::APIInvalidVersion); + j_object[jss::api_version] = "a"; + BEAST_EXPECT(RPC::getAPIVersionNumber(j_object) == RPC::APIInvalidVersion); + } + + void + testBatch() + { + testcase ("batch, all good request"); + + using namespace test::jtx; + Env env {*this}; + + auto const without_api_verion = std::string ("{ ") + + "\"jsonrpc\": \"2.0\", " + "\"ripplerpc\": \"2.0\", " + "\"id\": 5, " + "\"method\": \"version\", " + "\"params\": {}}"; + auto const with_api_verion = std::string ("{ ") + + "\"jsonrpc\": \"2.0\", " + "\"ripplerpc\": \"2.0\", " + "\"id\": 6, " + "\"method\": \"version\", " + "\"params\": { " + "\"api_version\": " + std::to_string(RPC::ApiMaximumSupportedVersion) + + "}}"; + auto re = env.rpc("json2", '[' + without_api_verion + ", " + + with_api_verion + ']'); + + if( !BEAST_EXPECT( re.isArray() )) + return; + if( !BEAST_EXPECT( re.size() == 2 )) + return; + BEAST_EXPECT(re[0u].isMember(jss::result) && + re[0u][jss::result].isMember(jss::version)); + BEAST_EXPECT(re[1u].isMember(jss::result) && + re[1u][jss::result].isMember(jss::version)); + } + + void + testBatchFail() + { + testcase ("batch, with a bad request"); + + using namespace test::jtx; + Env env {*this}; + + auto const without_api_verion = std::string ("{ ") + + "\"jsonrpc\": \"2.0\", " + "\"ripplerpc\": \"2.0\", " + "\"id\": 5, " + "\"method\": \"version\", " + "\"params\": {}}"; + auto const with_wrong_api_verion = std::string ("{ ") + + "\"jsonrpc\": \"2.0\", " + "\"ripplerpc\": \"2.0\", " + "\"id\": 6, " + "\"method\": \"version\", " + "\"params\": { " + "\"api_version\": " + + std::to_string(RPC::ApiMaximumSupportedVersion + 1) + + "}}"; + auto re = env.rpc("json2", '[' + without_api_verion + ", " + + with_wrong_api_verion + ']'); + + if( !BEAST_EXPECT( re.isArray() )) + return; + if( !BEAST_EXPECT( re.size() == 2 )) + return; + BEAST_EXPECT(re[0u].isMember(jss::result) && + re[0u][jss::result].isMember(jss::version)); + BEAST_EXPECT(re[1u].isMember(jss::error)); + } + +public: + + void run() override + { + testCorrectVersionNumber(); + testWrongVersionNumber(); + testGetAPIVersionNumber(); + testBatch(); + testBatchFail(); + } +}; + +BEAST_DEFINE_TESTSUITE(Version,rpc,ripple); + +} // ripple diff --git a/src/test/unity/rpc_test_unity.cpp b/src/test/unity/rpc_test_unity.cpp index 90d9f6ea571..cb8a2833581 100644 --- a/src/test/unity/rpc_test_unity.cpp +++ b/src/test/unity/rpc_test_unity.cpp @@ -53,3 +53,4 @@ #include #include #include +#include