1.CRPCTable的作用和相关方法实现
1.1.作用:维持所能执行的RPC命令集合
src/rpc/server.h
/**
* Bitcoin RPC command dispatcher.
*/
class CRPCTable
{
private:
std::map<std::string, const CRPCCommand*> mapCommands;
public:
CRPCTable();
const CRPCCommand* operator[](const std::string& name) const;
std::string help(const std::string& name, const JSONRPCRequest& helpreq) const;
/**
* Execute a method.
* @param request The JSONRPCRequest to execute
* @returns Result of the call.
* @throws an exception (UniValue) when an error happens.
*/
UniValue execute(const JSONRPCRequest &request) const;
/**
* Returns a list of registered commands
* @returns List of registered commands.
*/
std::vector<std::string> listCommands() const;
/**
* Appends a CRPCCommand to the dispatch table.
*
* Returns false if RPC server is already running (dump concurrency protection).
*
* Commands cannot be overwritten (returns false).
*
* Commands with different method names but the same callback function will
* be considered aliases, and only the first registered method name will
* show up in the help text command listing. Aliased commands do not have
* to have the same behavior. Server and client code can distinguish
* between calls based on method name, and aliased commands can also
* register different names, types, and numbers of parameters.
*/
bool appendCommand(const std::string& name, const CRPCCommand* pcmd);
};
1.2.operator[]的实现:
src/rpc/server.cpp
const CRPCCommand *CRPCTable::operator[](const std::string &name) const
{
std::map<std::string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
if (it == mapCommands.end())
return nullptr;
return (*it).second;
}
1.3.往CRPCTable添加命令:
src/rpc/server.cpp
bool CRPCTable::appendCommand(const std::string& name, const CRPCCommand* pcmd)
{
if (IsRPCRunning())
return false;
// don't allow overwriting for now
std::map<std::string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
if (it != mapCommands.end())
return false;
mapCommands[name] = pcmd; //operator[]
return true;
}
1.4. 命令的执行
src/rpc/server.cpp
UniValue CRPCTable::execute(const JSONRPCRequest &request) const
{
// Return immediately if in warmup
{
LOCK(cs_rpcWarmup);
if (fRPCInWarmup)
throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
}
// Find method
const CRPCCommand *pcmd = tableRPC[request.strMethod];
if (!pcmd)
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
g_rpcSignals.PreCommand(*pcmd);
try
{
// Execute, convert arguments to array if necessary
if (request.params.isObject()) {
return pcmd->actor(transformNamedArguments(request, pcmd->argNames));
} else {
return pcmd->actor(request);
}
}
catch (const std::exception& e)
{
throw JSONRPCError(RPC_MISC_ERROR, e.what());
}
}
2. 往CRPCTable添加RPC命令的调用堆栈
2.1. bitcoind命令入口main函数
src/bitcoind.cpp
int main(int argc, char* argv[])
{
return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);
}
2.2. AppInit函数
src/bitcoind.cpp
static bool AppInit(int argc, char* argv[])
{
fRet = AppInitMain();
}
2.3. AppInitMain函数
src/init.cpp
bool AppInitMain()
{
RegisterAllCoreRPCCommands(tableRPC);
}
2.4. RegisterAllCoreRPCCommands函数
src/rpc/register.h
static inline void RegisterAllCoreRPCCommands(CRPCTable &t)
{
RegisterBlockchainRPCCommands(t);
RegisterNetRPCCommands(t);
RegisterMiscRPCCommands(t);
RegisterMiningRPCCommands(t);
RegisterRawTransactionRPCCommands(t);
}
网友评论