mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Submit Env transactions through RPC interface
This commit is contained in:
committed by
Edward Hennis
parent
8f74ee1d96
commit
d5363d1a85
@@ -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};
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace ripple {
|
||||
@@ -53,6 +54,12 @@ void fromNetwork (
|
||||
std::function<void (Json::Value const& jvInput)> callbackFuncP = std::function<void (Json::Value const& jvInput)> ());
|
||||
}
|
||||
|
||||
/** Internal invocation of RPC client.
|
||||
*/
|
||||
std::pair<int, Json::Value>
|
||||
rpcClient(std::vector<std::string> const& args,
|
||||
Config const& config, Logs& logs);
|
||||
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1079,18 +1079,18 @@ struct RPCCallImp
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
namespace RPCCall {
|
||||
|
||||
int fromCommandLine (
|
||||
Config const& config,
|
||||
const std::vector<std::string>& vCmd,
|
||||
Logs& logs)
|
||||
std::pair<int, Json::Value>
|
||||
rpcClient(std::vector<std::string> 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 <int> (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<std::string>& vCmd,
|
||||
Logs& logs)
|
||||
{
|
||||
auto const result = rpcClient(vCmd, config, logs);
|
||||
|
||||
if (result.first != rpcBAD_SYNTAX)
|
||||
std::cout << result.second.toStyledString ();
|
||||
|
||||
return result.first;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <ripple/json/json_value.h>
|
||||
#include <ripple/json/to_string.h>
|
||||
#include <ripple/ledger/CachedSLEs.h>
|
||||
#include <ripple/net/RPCCall.h>
|
||||
#include <ripple/protocol/Indexes.h>
|
||||
#include <ripple/protocol/Issue.h>
|
||||
#include <ripple/protocol/STAmount.h>
|
||||
@@ -44,10 +45,12 @@
|
||||
#include <beast/is_call_possible.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
@@ -420,6 +423,11 @@ public:
|
||||
std::shared_ptr<STObject const>
|
||||
meta();
|
||||
|
||||
/** Execute a client command */
|
||||
template <class Arg, class... Args>
|
||||
std::pair<int, Json::Value>
|
||||
rpc (Arg&& arg0, Args&&... args);
|
||||
|
||||
private:
|
||||
void
|
||||
fund (bool setDefaultRipple,
|
||||
@@ -620,6 +628,18 @@ protected:
|
||||
AccountID, Account> map_;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class Arg, class... Args>
|
||||
std::pair<int, Json::Value>
|
||||
Env::rpc (Arg&& arg0, Args&&... args)
|
||||
{
|
||||
std::vector<std::string> v({ std::forward<Arg>(arg0),
|
||||
std::forward<Args>(args)... });
|
||||
return rpcClient(v,
|
||||
app().config(), app().logs());
|
||||
}
|
||||
|
||||
} // jtx
|
||||
} // test
|
||||
} // ripple
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <ripple/basics/Slice.h>
|
||||
#include <ripple/core/ConfigSections.h>
|
||||
#include <ripple/json/to_string.h>
|
||||
#include <ripple/net/HTTPClient.h>
|
||||
#include <ripple/protocol/ErrorCodes.h>
|
||||
#include <ripple/protocol/HashPrefix.h>
|
||||
#include <ripple/protocol/Indexes.h>
|
||||
@@ -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> config)
|
||||
auto timeKeeper_ =
|
||||
std::make_unique<ManualTimeKeeper>();
|
||||
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<TER>(
|
||||
result.second["result"]["engine_result_code"].asInt());
|
||||
else
|
||||
ter_ = temINVALID;
|
||||
didApply = isTesSuccess(ter_) || isTecClaim(ter_);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user