19 #include <boost/bind.hpp> 20 #include <boost/signals2/signal.hpp> 21 #include <boost/algorithm/string/case_conv.hpp> 22 #include <boost/algorithm/string/classification.hpp> 23 #include <boost/algorithm/string/split.hpp> 26 #include <unordered_map> 28 static bool fRPCRunning =
false;
29 static bool fRPCInWarmup =
true;
30 static std::string rpcWarmupStatus(
"RPC server started");
35 static std::map<std::string, std::unique_ptr<RPCTimerBase> > deadlineTimers;
37 static struct CRPCSignals
39 boost::signals2::signal<void ()>
Started;
40 boost::signals2::signal<void ()>
Stopped;
41 boost::signals2::signal<void (const CRPCCommand&)> PreCommand;
46 g_rpcSignals.Started.connect(slot);
51 g_rpcSignals.Stopped.connect(slot);
56 g_rpcSignals.PreCommand.connect(boost::bind(slot, _1));
60 const std::list<UniValue::VType>& typesExpected,
66 if (params.
size() <= i)
70 if (!(fAllowNull && v.
isNull())) {
79 if (value.
type() != typeExpected) {
85 const std::map<std::string, UniValueType>& typesExpected,
89 for (
const auto& t : typesExpected) {
91 if (!fAllowNull && v.
isNull())
94 if (!(t.second.typeAny || v.
type() == t.second.type || (fAllowNull && v.
isNull()))) {
95 std::string err =
strprintf(
"Expected type %s for %s, got %s",
103 for (
const std::string& k : o.
getKeys())
105 if (typesExpected.count(k) == 0)
107 std::string err =
strprintf(
"Unexpected key %s", k);
133 if (64 != strHex.length())
164 std::string category;
165 std::set<rpcfn_type> setDone;
166 std::vector<std::pair<std::string, const CRPCCommand*> > vCommands;
168 for (std::map<std::string, const CRPCCommand*>::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi)
169 vCommands.push_back(make_pair(mi->second->category + mi->first, mi->second));
170 sort(vCommands.begin(), vCommands.end());
176 for (
const std::pair<std::string, const CRPCCommand*>& command : vCommands)
179 std::string strMethod = pcmd->
name;
180 if ((strCommand !=
"" || pcmd->
category ==
"hidden") && strMethod != strCommand)
182 jreq.strMethod = strMethod;
186 if (setDone.insert(pfn).second)
189 catch (
const std::exception&
e)
192 std::string strHelp = std::string(e.what());
193 if (strCommand ==
"")
195 if (strHelp.find(
'\n') != std::string::npos)
196 strHelp = strHelp.substr(0, strHelp.find(
'\n'));
200 if (!category.empty())
203 std::string firstLetter = category.substr(0,1);
204 boost::to_upper(firstLetter);
205 strRet +=
"== " + firstLetter + category.substr(1) +
" ==\n";
208 strRet += strHelp +
"\n";
212 strRet =
strprintf(
"help: unknown command: %s\n", strCommand);
213 strRet = strRet.substr(0,strRet.size()-1);
220 throw std::runtime_error(
221 "help ( \"command\" )\n" 222 "\nList all commands, or get help for a specified command.\n" 224 "1. \"command\" (string, optional) The command to get help on\n" 226 "\"text\" (string) The help text\n" 229 std::string strCommand;
241 throw std::runtime_error(
243 "\nStop Fabcoin server.");
247 return "Fabcoin server stopping";
253 throw std::runtime_error(
255 "\nReturns the total uptime of the server.\n" 257 "ttt (numeric) The number of seconds that the server has been running\n" 273 {
"control",
"help", &
help,
true, {
"command"} },
274 {
"control",
"stop", &
stop,
true, {} },
275 {
"control",
"uptime", &
uptime,
true, {} },
281 for (vcidx = 0; vcidx < (
sizeof(vRPCCommands) /
sizeof(vRPCCommands[0])); vcidx++)
285 pcmd = &vRPCCommands[vcidx];
286 mapCommands[pcmd->
name] = pcmd;
292 std::map<std::string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
293 if (it == mapCommands.end())
304 std::map<std::string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
305 if (it != mapCommands.end())
308 mapCommands[
name] = pcmd;
316 g_rpcSignals.Started();
330 deadlineTimers.clear();
332 g_rpcSignals.Stopped();
343 rpcWarmupStatus = newStatus;
350 fRPCInWarmup =
false;
357 *outStatus = rpcWarmupStatus;
414 if (!valMethod.
isStr())
423 else if (valParams.
isNull())
444 catch (
const std::exception&
e)
456 for (
unsigned int reqIdx = 0; reqIdx < vReq.
size(); reqIdx++)
457 ret.
push_back(JSONRPCExecOne(vReq[reqIdx]));
459 return ret.
write() +
"\n";
474 std::unordered_map<std::string, const UniValue*> argsIn;
475 for (
size_t i=0; i<keys.size(); ++i) {
476 argsIn[keys[i]] = &values[i];
480 for (
const std::string &argNamePattern: argNames) {
481 std::vector<std::string> vargNames;
482 boost::algorithm::split(vargNames, argNamePattern, boost::algorithm::is_any_of(
"|"));
483 auto fr = argsIn.end();
484 for (
const std::string & argName : vargNames) {
485 fr = argsIn.find(argName);
486 if (fr != argsIn.end()) {
490 if (fr != argsIn.end()) {
491 for (
int i = 0; i < hole; ++i) {
505 if (!argsIn.empty()) {
526 g_rpcSignals.PreCommand(*pcmd);
532 return pcmd->
actor(transformNamedArguments(request, pcmd->
argNames));
534 return pcmd->
actor(request);
537 catch (
const std::exception&
e)
545 std::vector<std::string> commandList;
546 typedef std::map<std::string, const CRPCCommand*> commandMap;
548 std::transform( mapCommands.begin(), mapCommands.end(),
549 std::back_inserter(commandList),
550 boost::bind(&commandMap::value_type::first,_1) );
554 std::string
HelpExampleCli(
const std::string& methodname,
const std::string& args)
556 return "> fabcoin-cli " + methodname +
" " + args +
"\n";
559 std::string
HelpExampleRpc(
const std::string& methodname,
const std::string& args)
561 return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\":\"curltest\", " 562 "\"method\": \"" + methodname +
"\", \"params\": [" + args +
"] }' -H 'content-type: text/plain;' http://127.0.0.1:8667/\n";
568 timerInterface = iface;
573 timerInterface = iface;
578 if (timerInterface == iface)
579 timerInterface =
nullptr;
586 deadlineTimers.erase(name);
587 LogPrint(
BCLog::RPC,
"queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->
Name());
588 deadlineTimers.emplace(name, std::unique_ptr<RPCTimerBase>(timerInterface->
NewTimer(func, nSeconds*1000)));
594 if (
gArgs.
GetArg(
"-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) == 0)
595 flag |= SERIALIZE_TRANSACTION_NO_WITNESS;
void RPCTypeCheckObj(const UniValue &o, const std::map< std::string, UniValueType > &typesExpected, bool fAllowNull, bool fStrict)
UniValue execute(const JSONRPCRequest &request) const
Execute a method.
uint256 ParseHashO(const UniValue &o, std::string strKey)
std::vector< unsigned char > ParseHexO(const UniValue &o, std::string strKey)
const std::string & get_str() const
#define function(a, b, c, d, k, s)
std::vector< std::string > listCommands() const
Returns a list of registered commands.
Fabcoin RPC command dispatcher.
bool IsRPCRunning()
Query whether RPC is running.
void SetRPCWarmupStatus(const std::string &newStatus)
Set the RPC warmup status.
std::string JSONRPCExecBatch(const UniValue &vReq)
UniValue uptime(const JSONRPCRequest &jsonRequest)
int64_t GetStartupTime()
Server/client environment: argument handling, config file parsing, logging, thread wrappers...
const std::vector< UniValue > & getValues() const
bool MoneyRange(const CAmount &nValue)
void Chunk(const std::string &chunk)
Start chunk transfer.
void OnStopped(std::function< void()> slot)
void DeleteAuthCookie()
Delete RPC authentication cookie from disk.
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
assert(len-trim+(2 *lenIndices)<=WIDTH)
bool appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
void ChunkEnd()
End chunk transfer.
std::vector< std::string > argNames
void PollReply(const UniValue &result)
Return the JSON result of a long poll request.
void RPCTypeCheck(const UniValue ¶ms, const std::list< UniValue::VType > &typesExpected, bool fAllowNull)
Type-check arguments; throws JSONRPCError if wrong type given.
Invalid, missing or duplicate parameter.
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded Values (throws error if not hex).
void RPCUnsetTimerInterface(RPCTimerInterface *iface)
Unset factory function for timers.
int64_t CAmount
Amount in lius (Can be negative)
void SetRPCWarmupFinished()
const char * uvTypeName(UniValue::VType t)
bool push_back(const UniValue &val)
virtual RPCTimerBase * NewTimer(std::function< void(void)> &func, int64_t millis)=0
Factory function for timers.
const Object_type::value_type::Value_type & find_value(const Object_type &obj, const String_type &name)
void RPCTypeCheckArgument(const UniValue &value, UniValue::VType typeExpected)
Type-check one argument; throws JSONRPCError if wrong type given.
bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
Parse number as fixed point according to JSON number syntax.
bool IsHex(const std::string &str)
Unexpected type was passed as parameter.
General application defined errors.
UniValue help(const JSONRPCRequest &jsonRequest)
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
CAmount AmountFromValue(const UniValue &value)
void PollStart()
Start long-polling.
void RPCRunLater(const std::string &name, std::function< void(void)> func, int64_t nSeconds)
Run func nSeconds from now.
void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface)
Set the factory function for timer, but only, if unset.
std::vector< unsigned char > ParseHexV(const UniValue &v, std::string strName)
bool PollAlive()
Returns whether the underlying long-poll connection is still alive.
#define LogPrint(category,...)
void PollPing()
Ping long-poll connection with an empty character to make sure it's still alive.
void parse(const UniValue &valRequest)
std::string help(const std::string &name, const JSONRPCRequest &helpreq) const
Note: This interface may still be subject to change.
const std::string & getValStr() const
void WriteHeader(const std::string &hdr, const std::string &value)
Write output header.
JSONRPCRequest()
If using batch JSON request, this object won't get the underlying HTTPRequest.
void PollCancel()
End a long poll request.
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
int RPCSerializationFlags()
void RPCSetTimerInterface(RPCTimerInterface *iface)
Set the factory function for timers.
bool RPCIsInWarmup(std::string *outStatus)
const UniValue NullUniValue
Standard JSON-RPC 2.0 errors.
virtual const char * Name()=0
Implementation name.
UniValue JSONRPCError(int code, const std::string &message)
void OnStarted(std::function< void()> slot)
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
const std::vector< std::string > & getKeys() const
UniValue JSONRPCReplyObj(const UniValue &result, const UniValue &error, const UniValue &id)
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
const UniValue & get_obj() const
void SetHex(const char *psz)
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
UniValue(* rpcfn_type)(const JSONRPCRequest &jsonRequest)
Wrapped boost mutex: supports recursive locking, but no waiting TODO: We should move away from using ...
const CRPCCommand * operator[](const std::string &name) const
UniValue stop(const JSONRPCRequest &jsonRequest)
std::vector< unsigned char > ParseHex(const char *psz)
void OnPreCommand(std::function< void(const CRPCCommand &)> slot)