@@ -30,6 +30,7 @@ static std::string rpcWarmupStatus GUARDED_BY(cs_rpcWarmup) = "RPC server starte
3030static RPCTimerInterface* timerInterface = nullptr ;
3131/* Map of name to timer. */
3232static std::map<std::string, std::unique_ptr<RPCTimerBase> > deadlineTimers;
33+ static bool ExecuteCommand (const CRPCCommand& command, const JSONRPCRequest& request, UniValue& result, bool last_handler);
3334
3435struct RPCCommandExecutionInfo
3536{
@@ -173,11 +174,11 @@ std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest&
173174{
174175 std::string strRet;
175176 std::string category;
176- std::set<rpcfn_type > setDone;
177+ std::set<intptr_t > setDone;
177178 std::vector<std::pair<std::string, const CRPCCommand*> > vCommands;
178179
179180 for (const auto & entry : mapCommands)
180- vCommands.push_back (make_pair (entry.second ->category + entry.first , entry.second ));
181+ vCommands.push_back (make_pair (entry.second . front () ->category + entry.first , entry.second . front () ));
181182 sort (vCommands.begin (), vCommands.end ());
182183
183184 JSONRPCRequest jreq (helpreq);
@@ -193,9 +194,9 @@ std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest&
193194 jreq.strMethod = strMethod;
194195 try
195196 {
196- rpcfn_type pfn = pcmd-> actor ;
197- if (setDone.insert (pfn ).second )
198- (*pfn)( jreq);
197+ UniValue unused_result ;
198+ if (setDone.insert (pcmd-> unique_id ).second )
199+ pcmd-> actor ( jreq, unused_result, true /* last_handler */ );
199200 }
200201 catch (const std::exception& e)
201202 {
@@ -337,32 +338,32 @@ CRPCTable::CRPCTable()
337338 const CRPCCommand *pcmd;
338339
339340 pcmd = &vRPCCommands[vcidx];
340- mapCommands[pcmd->name ] = pcmd;
341+ mapCommands[pcmd->name ]. push_back ( pcmd) ;
341342 }
342343}
343344
344- const CRPCCommand *CRPCTable::operator [](const std::string &name) const
345- {
346- std::map<std::string, const CRPCCommand*>::const_iterator it = mapCommands.find (name);
347- if (it == mapCommands.end ())
348- return nullptr ;
349- return (*it).second ;
350- }
351-
352345bool CRPCTable::appendCommand (const std::string& name, const CRPCCommand* pcmd)
353346{
354347 if (IsRPCRunning ())
355348 return false ;
356349
357- // don't allow overwriting for now
358- std::map<std::string, const CRPCCommand*>::const_iterator it = mapCommands.find (name);
359- if (it != mapCommands.end ())
360- return false ;
361-
362- mapCommands[name] = pcmd;
350+ mapCommands[name].push_back (pcmd);
363351 return true ;
364352}
365353
354+ bool CRPCTable::removeCommand (const std::string& name, const CRPCCommand* pcmd)
355+ {
356+ auto it = mapCommands.find (name);
357+ if (it != mapCommands.end ()) {
358+ auto new_end = std::remove (it->second .begin (), it->second .end (), pcmd);
359+ if (it->second .end () != new_end) {
360+ it->second .erase (new_end, it->second .end ());
361+ return true ;
362+ }
363+ }
364+ return false ;
365+ }
366+
366367void StartRPC ()
367368{
368369 LogPrint (BCLog::RPC, " Starting RPC\n " );
@@ -543,18 +544,28 @@ UniValue CRPCTable::execute(const JSONRPCRequest &request) const
543544 }
544545
545546 // Find method
546- const CRPCCommand *pcmd = tableRPC[request.strMethod ];
547- if (!pcmd)
548- throw JSONRPCError (RPC_METHOD_NOT_FOUND, " Method not found" );
547+ auto it = mapCommands.find (request.strMethod );
548+ if (it != mapCommands.end ()) {
549+ UniValue result;
550+ for (const auto & command : it->second ) {
551+ if (ExecuteCommand (*command, request, result, &command == &it->second .back ())) {
552+ return result;
553+ }
554+ }
555+ }
556+ throw JSONRPCError (RPC_METHOD_NOT_FOUND, " Method not found" );
557+ }
549558
559+ static bool ExecuteCommand (const CRPCCommand& command, const JSONRPCRequest& request, UniValue& result, bool last_handler)
560+ {
550561 try
551562 {
552563 RPCCommandExecution execution (request.strMethod );
553564 // Execute, convert arguments to array if necessary
554565 if (request.params .isObject ()) {
555- return pcmd-> actor (transformNamedArguments (request, pcmd-> argNames ));
566+ return command. actor (transformNamedArguments (request, command. argNames ), result, last_handler );
556567 } else {
557- return pcmd-> actor (request);
568+ return command. actor (request, result, last_handler );
558569 }
559570 }
560571 catch (const std::exception& e)
0 commit comments