Browse Source

RPC: Add new "getzmqnotifications" method.

Cherry-picked from Bitcoin Core.
zmq
Just Wonder 5 years ago
parent
commit
2a90a04efb
  1. 6
      src/Makefile.am
  2. 21
      src/init.cpp
  3. 11
      src/zmq/zmqnotificationinterface.cpp
  4. 4
      src/zmq/zmqnotificationinterface.h
  5. 61
      src/zmq/zmqrpc.cpp
  6. 12
      src/zmq/zmqrpc.h
  7. 34
      test/functional/rpc_zmq.py
  8. 1
      test/functional/test_runner.py

6
src/Makefile.am

@ -179,7 +179,8 @@ BITCOIN_CORE_H = \
zmq/zmqabstractnotifier.h \ zmq/zmqabstractnotifier.h \
zmq/zmqconfig.h\ zmq/zmqconfig.h\
zmq/zmqnotificationinterface.h \ zmq/zmqnotificationinterface.h \
zmq/zmqpublishnotifier.h zmq/zmqpublishnotifier.h \
zmq/zmqrpc.h
BITCOIN_CORE_H += \ BITCOIN_CORE_H += \
keva/main.h \ keva/main.h \
@ -243,7 +244,8 @@ libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libbitcoin_zmq_a_SOURCES = \ libbitcoin_zmq_a_SOURCES = \
zmq/zmqabstractnotifier.cpp \ zmq/zmqabstractnotifier.cpp \
zmq/zmqnotificationinterface.cpp \ zmq/zmqnotificationinterface.cpp \
zmq/zmqpublishnotifier.cpp zmq/zmqpublishnotifier.cpp \
zmq/zmqrpc.cpp
endif endif

21
src/init.cpp

@ -65,6 +65,7 @@
#if ENABLE_ZMQ #if ENABLE_ZMQ
#include <zmq/zmqnotificationinterface.h> #include <zmq/zmqnotificationinterface.h>
#include <zmq/zmqrpc.h>
#endif #endif
#ifdef USE_SSE2 #ifdef USE_SSE2
@ -79,9 +80,6 @@ static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
std::unique_ptr<CConnman> g_connman; std::unique_ptr<CConnman> g_connman;
std::unique_ptr<PeerLogicValidation> peerLogic; std::unique_ptr<PeerLogicValidation> peerLogic;
#if ENABLE_ZMQ
static CZMQNotificationInterface* pzmqNotificationInterface = nullptr;
#endif
#ifdef WIN32 #ifdef WIN32
// Win32 LevelDB doesn't use filedescriptors, and the ones used for // Win32 LevelDB doesn't use filedescriptors, and the ones used for
@ -257,10 +255,10 @@ void Shutdown()
#endif #endif
#if ENABLE_ZMQ #if ENABLE_ZMQ
if (pzmqNotificationInterface) { if (g_zmq_notification_interface) {
UnregisterValidationInterface(pzmqNotificationInterface); UnregisterValidationInterface(g_zmq_notification_interface);
delete pzmqNotificationInterface; delete g_zmq_notification_interface;
pzmqNotificationInterface = nullptr; g_zmq_notification_interface = nullptr;
} }
#endif #endif
@ -1260,6 +1258,9 @@ bool AppInitMain()
* available in the GUI RPC console even if external calls are disabled. * available in the GUI RPC console even if external calls are disabled.
*/ */
RegisterAllCoreRPCCommands(tableRPC); RegisterAllCoreRPCCommands(tableRPC);
#if ENABLE_ZMQ
RegisterZMQRPCCommands(tableRPC);
#endif
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
RegisterWalletRPC(tableRPC); RegisterWalletRPC(tableRPC);
#endif #endif
@ -1388,10 +1389,10 @@ bool AppInitMain()
} }
#if ENABLE_ZMQ #if ENABLE_ZMQ
pzmqNotificationInterface = CZMQNotificationInterface::Create(); g_zmq_notification_interface = CZMQNotificationInterface::Create();
if (pzmqNotificationInterface) { if (g_zmq_notification_interface) {
RegisterValidationInterface(pzmqNotificationInterface); RegisterValidationInterface(g_zmq_notification_interface);
} }
#endif #endif
uint64_t nMaxOutboundLimit = 0; //unlimited unless -maxuploadtarget is set uint64_t nMaxOutboundLimit = 0; //unlimited unless -maxuploadtarget is set

11
src/zmq/zmqnotificationinterface.cpp

@ -29,6 +29,15 @@ CZMQNotificationInterface::~CZMQNotificationInterface()
} }
} }
std::list<const CZMQAbstractNotifier*> CZMQNotificationInterface::GetActiveNotifiers() const
{
std::list<const CZMQAbstractNotifier*> result;
for (const auto* n : notifiers) {
result.push_back(n);
}
return result;
}
CZMQNotificationInterface* CZMQNotificationInterface::Create() CZMQNotificationInterface* CZMQNotificationInterface::Create()
{ {
CZMQNotificationInterface* notificationInterface = nullptr; CZMQNotificationInterface* notificationInterface = nullptr;
@ -180,3 +189,5 @@ void CZMQNotificationInterface::BlockDisconnected(const std::shared_ptr<const CB
TransactionAddedToMempool(ptx); TransactionAddedToMempool(ptx);
} }
} }
CZMQNotificationInterface* g_zmq_notification_interface = nullptr;

4
src/zmq/zmqnotificationinterface.h

@ -18,6 +18,8 @@ class CZMQNotificationInterface final : public CValidationInterface
public: public:
virtual ~CZMQNotificationInterface(); virtual ~CZMQNotificationInterface();
std::list<const CZMQAbstractNotifier*> GetActiveNotifiers() const;
static CZMQNotificationInterface* Create(); static CZMQNotificationInterface* Create();
protected: protected:
@ -37,4 +39,6 @@ private:
std::list<CZMQAbstractNotifier*> notifiers; std::list<CZMQAbstractNotifier*> notifiers;
}; };
extern CZMQNotificationInterface* g_zmq_notification_interface;
#endif // BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H #endif // BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H

61
src/zmq/zmqrpc.cpp

@ -0,0 +1,61 @@
// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <zmq/zmqrpc.h>
#include <rpc/server.h>
#include <zmq/zmqabstractnotifier.h>
#include <zmq/zmqnotificationinterface.h>
#include <univalue.h>
namespace {
UniValue getzmqnotifications(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() != 0) {
throw std::runtime_error(
"getzmqnotifications\n"
"\nReturns information about the active ZeroMQ notifications.\n"
"\nResult:\n"
"[\n"
" { (json object)\n"
" \"type\": \"pubhashtx\", (string) Type of notification\n"
" \"address\": \"...\" (string) Address of the publisher\n"
" },\n"
" ...\n"
"]\n"
"\nExamples:\n"
+ HelpExampleCli("getzmqnotifications", "")
+ HelpExampleRpc("getzmqnotifications", "")
);
}
UniValue result(UniValue::VARR);
if (g_zmq_notification_interface != nullptr) {
for (const auto* n : g_zmq_notification_interface->GetActiveNotifiers()) {
UniValue obj(UniValue::VOBJ);
obj.pushKV("type", n->GetType());
obj.pushKV("address", n->GetAddress());
result.push_back(obj);
}
}
return result;
}
const CRPCCommand commands[] =
{ // category name actor (function) argNames
// ----------------- ------------------------ ----------------------- ----------
{ "zmq", "getzmqnotifications", &getzmqnotifications, {} },
};
} // anonymous namespace
void RegisterZMQRPCCommands(CRPCTable& t)
{
for (const auto& c : commands) {
t.appendCommand(c.name, &c);
}
}

12
src/zmq/zmqrpc.h

@ -0,0 +1,12 @@
// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_ZMQ_ZMQRPC_H
#define BITCOIN_ZMQ_ZMQRPC_H
class CRPCTable;
void RegisterZMQRPCCommands(CRPCTable& t);
#endif // BITCOIN_ZMQ_ZMRRPC_H

34
test/functional/rpc_zmq.py

@ -0,0 +1,34 @@
#!/usr/bin/env python3
# Copyright (c) 2018 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test for the ZMQ RPC methods."""
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
class RPCZMQTest(BitcoinTestFramework):
address = "tcp://127.0.0.1:28332"
def set_test_params(self):
self.num_nodes = 1
self.setup_clean_chain = True
def run_test(self):
self._test_getzmqnotifications()
def _test_getzmqnotifications(self):
self.restart_node(0, extra_args=[])
assert_equal(self.nodes[0].getzmqnotifications(), [])
self.restart_node(0, extra_args=["-zmqpubhashtx=%s" % self.address])
assert_equal(self.nodes[0].getzmqnotifications(), [
{"type": "pubhashtx", "address": self.address},
])
if __name__ == '__main__':
RPCZMQTest().main()

1
test/functional/test_runner.py

@ -115,6 +115,7 @@ BASE_SCRIPTS= [
'feature_versionbits_warning.py', 'feature_versionbits_warning.py',
'rpc_preciousblock.py', 'rpc_preciousblock.py',
'wallet_importprunedfunds.py', 'wallet_importprunedfunds.py',
'rpc_zmq.py',
'rpc_signmessage.py', 'rpc_signmessage.py',
'feature_nulldummy.py', 'feature_nulldummy.py',
'wallet_import_rescan.py', 'wallet_import_rescan.py',

Loading…
Cancel
Save