diff options
Diffstat (limited to 'src/interfaces/chain.cpp')
-rw-r--r-- | src/interfaces/chain.cpp | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp index 8ce718cc50..f04d07d49d 100644 --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -15,12 +15,15 @@ #include <primitives/block.h> #include <primitives/transaction.h> #include <protocol.h> +#include <rpc/protocol.h> +#include <rpc/server.h> #include <sync.h> #include <threadsafety.h> #include <timedata.h> #include <txmempool.h> #include <ui_interface.h> #include <uint256.h> +#include <univalue.h> #include <util/system.h> #include <validation.h> #include <validationinterface.h> @@ -212,6 +215,45 @@ public: Chain::Notifications* m_notifications; }; +class RpcHandlerImpl : public Handler +{ +public: + RpcHandlerImpl(const CRPCCommand& command) : m_command(command), m_wrapped_command(&command) + { + m_command.actor = [this](const JSONRPCRequest& request, UniValue& result, bool last_handler) { + if (!m_wrapped_command) return false; + try { + return m_wrapped_command->actor(request, result, last_handler); + } catch (const UniValue& e) { + // If this is not the last handler and a wallet not found + // exception was thrown, return false so the next handler can + // try to handle the request. Otherwise, reraise the exception. + if (!last_handler) { + const UniValue& code = e["code"]; + if (code.isNum() && code.get_int() == RPC_WALLET_NOT_FOUND) { + return false; + } + } + throw; + } + }; + ::tableRPC.appendCommand(m_command.name, &m_command); + } + + void disconnect() override final + { + if (m_wrapped_command) { + m_wrapped_command = nullptr; + ::tableRPC.removeCommand(m_command.name, &m_command); + } + } + + ~RpcHandlerImpl() override { disconnect(); } + + CRPCCommand m_command; + const CRPCCommand* m_wrapped_command; +}; + class ChainImpl : public Chain { public: @@ -310,8 +352,11 @@ public: return MakeUnique<NotificationsHandlerImpl>(*this, notifications); } void waitForNotifications() override { SyncWithValidationInterfaceQueue(); } + std::unique_ptr<Handler> handleRpc(const CRPCCommand& command) override + { + return MakeUnique<RpcHandlerImpl>(command); + } }; - } // namespace std::unique_ptr<Chain> MakeChain() { return MakeUnique<ChainImpl>(); } |