Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/server.cpp
Show All 28 Lines | |||||
static bool fRPCInWarmup = true; | static bool fRPCInWarmup = true; | ||||
static std::string rpcWarmupStatus("RPC server started"); | static std::string rpcWarmupStatus("RPC server started"); | ||||
static CCriticalSection cs_rpcWarmup; | static CCriticalSection cs_rpcWarmup; | ||||
/* Timer-creating functions */ | /* Timer-creating functions */ | ||||
static RPCTimerInterface *timerInterface = nullptr; | static RPCTimerInterface *timerInterface = nullptr; | ||||
/* Map of name to timer. */ | /* Map of name to timer. */ | ||||
static std::map<std::string, std::unique_ptr<RPCTimerBase>> deadlineTimers; | static std::map<std::string, std::unique_ptr<RPCTimerBase>> deadlineTimers; | ||||
UniValue RPCServer::ExecuteCommand(Config &config, | |||||
const JSONRPCRequest &request) const { | |||||
// Return immediately if in warmup | |||||
{ | |||||
LOCK(cs_rpcWarmup); | |||||
if (fRPCInWarmup) { | |||||
throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); | |||||
} | |||||
} | |||||
// TODO Only call tableRPC.execute() if no context-sensitive RPC command | |||||
// exists | |||||
// Check if context-free RPC method is valid and execute it | |||||
return tableRPC.execute(config, request); | |||||
} | |||||
static struct CRPCSignals { | static struct CRPCSignals { | ||||
boost::signals2::signal<void()> Started; | boost::signals2::signal<void()> Started; | ||||
boost::signals2::signal<void()> Stopped; | boost::signals2::signal<void()> Stopped; | ||||
boost::signals2::signal<void(const ContextFreeRPCCommand &)> PreCommand; | boost::signals2::signal<void(const ContextFreeRPCCommand &)> PreCommand; | ||||
boost::signals2::signal<void(const ContextFreeRPCCommand &)> PostCommand; | boost::signals2::signal<void(const ContextFreeRPCCommand &)> PostCommand; | ||||
} g_rpcSignals; | } g_rpcSignals; | ||||
void RPCServerSignals::OnStarted(std::function<void()> slot) { | void RPCServerSignals::OnStarted(std::function<void()> slot) { | ||||
▲ Show 20 Lines • Show All 349 Lines • ▼ Show 20 Lines | |||||
bool RPCIsInWarmup(std::string *outStatus) { | bool RPCIsInWarmup(std::string *outStatus) { | ||||
LOCK(cs_rpcWarmup); | LOCK(cs_rpcWarmup); | ||||
if (outStatus) { | if (outStatus) { | ||||
*outStatus = rpcWarmupStatus; | *outStatus = rpcWarmupStatus; | ||||
} | } | ||||
return fRPCInWarmup; | return fRPCInWarmup; | ||||
} | } | ||||
static UniValue JSONRPCExecOne(Config &config, JSONRPCRequest jreq, | static UniValue JSONRPCExecOne(Config &config, RPCServer &rpcServer, | ||||
const UniValue &req) { | JSONRPCRequest jreq, const UniValue &req) { | ||||
UniValue rpc_result(UniValue::VOBJ); | UniValue rpc_result(UniValue::VOBJ); | ||||
try { | try { | ||||
jreq.parse(req); | jreq.parse(req); | ||||
UniValue result = tableRPC.execute(config, jreq); | UniValue result = rpcServer.ExecuteCommand(config, jreq); | ||||
rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id); | rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id); | ||||
} catch (const UniValue &objError) { | } catch (const UniValue &objError) { | ||||
rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id); | rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id); | ||||
} catch (const std::exception &e) { | } catch (const std::exception &e) { | ||||
rpc_result = JSONRPCReplyObj( | rpc_result = JSONRPCReplyObj( | ||||
NullUniValue, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); | NullUniValue, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); | ||||
} | } | ||||
return rpc_result; | return rpc_result; | ||||
} | } | ||||
std::string JSONRPCExecBatch(Config &config, const JSONRPCRequest &jreq, | std::string JSONRPCExecBatch(Config &config, RPCServer &rpcServer, | ||||
const UniValue &vReq) { | const JSONRPCRequest &jreq, const UniValue &vReq) { | ||||
UniValue ret(UniValue::VARR); | UniValue ret(UniValue::VARR); | ||||
for (size_t i = 0; i < vReq.size(); i++) { | for (size_t i = 0; i < vReq.size(); i++) { | ||||
ret.push_back(JSONRPCExecOne(config, jreq, vReq[i])); | ret.push_back(JSONRPCExecOne(config, rpcServer, jreq, vReq[i])); | ||||
} | } | ||||
return ret.write() + "\n"; | return ret.write() + "\n"; | ||||
} | } | ||||
/** | /** | ||||
* Process named arguments into a vector of positional arguments, based on the | * Process named arguments into a vector of positional arguments, based on the | ||||
* passed-in specification for the RPC call's arguments. | * passed-in specification for the RPC call's arguments. | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | UniValue CRPCTable::execute(Config &config, | ||||
// Return immediately if in warmup | // Return immediately if in warmup | ||||
{ | { | ||||
LOCK(cs_rpcWarmup); | LOCK(cs_rpcWarmup); | ||||
if (fRPCInWarmup) { | if (fRPCInWarmup) { | ||||
throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); | throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); | ||||
} | } | ||||
} | } | ||||
// Find method | // Check if legacy RPC method is valid. | ||||
// See RPCServer::ExecuteCommand for context-sensitive RPC commands. | |||||
const ContextFreeRPCCommand *pcmd = tableRPC[request.strMethod]; | const ContextFreeRPCCommand *pcmd = tableRPC[request.strMethod]; | ||||
if (!pcmd) { | if (!pcmd) { | ||||
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found"); | throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found"); | ||||
} | } | ||||
g_rpcSignals.PreCommand(*pcmd); | g_rpcSignals.PreCommand(*pcmd); | ||||
try { | try { | ||||
▲ Show 20 Lines • Show All 73 Lines • Show Last 20 Lines |