Skip to content

Commit

Permalink
RPC: Add new getzmqnotifications method.
Browse files Browse the repository at this point in the history
This adds a new RPC method "getzmqnotifications", which returns
information about all active ZMQ notification endpoints.  This is useful
for software that layers on top of bitcoind, so it can verify that
ZeroMQ is enabled and also figure out where it should listen.

See bitcoin#13526.

Github-Pull: bitcoin#13570
Rebased-From: 76c04a84d4e02acbd4ca78af3d4d7b9e854c1160
  • Loading branch information
domob1812 authored and luke-jr committed Jul 29, 2018
1 parent e953e65 commit b87d341
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 4 deletions.
6 changes: 4 additions & 2 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,8 @@ BITCOIN_CORE_H = \
zmq/zmqabstractnotifier.h \
zmq/zmqconfig.h\
zmq/zmqnotificationinterface.h \
zmq/zmqpublishnotifier.h
zmq/zmqpublishnotifier.h \
zmq/zmqrpc.h


obj/build.h: FORCE
Expand Down Expand Up @@ -233,7 +234,8 @@ libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libbitcoin_zmq_a_SOURCES = \
zmq/zmqabstractnotifier.cpp \
zmq/zmqnotificationinterface.cpp \
zmq/zmqpublishnotifier.cpp
zmq/zmqpublishnotifier.cpp \
zmq/zmqrpc.cpp
endif


Expand Down
4 changes: 4 additions & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@

#if ENABLE_ZMQ
#include <zmq/zmqnotificationinterface.h>
#include <zmq/zmqrpc.h>
#endif

bool fFeeEstimatesInitialized = false;
Expand Down Expand Up @@ -1244,6 +1245,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
#ifdef ENABLE_WALLET
RegisterWalletRPC(tableRPC);
#endif
#if ENABLE_ZMQ
RegisterZMQRPCCommands(tableRPC);
#endif

/* Start the RPC server already. It will be started in "warmup" mode
* and not really process calls already (but it will signify connections
Expand Down
11 changes: 10 additions & 1 deletion src/zmq/zmqnotificationinterface.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2015-2017 The Bitcoin Core developers
// Copyright (c) 2015-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.

Expand Down Expand Up @@ -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* notificationInterface = nullptr;
Expand Down
4 changes: 3 additions & 1 deletion src/zmq/zmqnotificationinterface.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2015-2017 The Bitcoin Core developers
// Copyright (c) 2015-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.

Expand All @@ -18,6 +18,8 @@ class CZMQNotificationInterface final : public CValidationInterface
public:
virtual ~CZMQNotificationInterface();

std::list<const CZMQAbstractNotifier*> GetActiveNotifiers() const;

static CZMQNotificationInterface* Create();

protected:
Expand Down
61 changes: 61 additions & 0 deletions src/zmq/zmqrpc.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 12 additions & 0 deletions src/zmq/zmqrpc.h
Original file line number Diff line number Diff line change
@@ -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
33 changes: 33 additions & 0 deletions test/functional/rpc_zmq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/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 change: 1 addition & 0 deletions test/functional/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
'feature_versionbits_warning.py',
'rpc_preciousblock.py',
'wallet_importprunedfunds.py',
'rpc_zmq.py',
'rpc_signmessage.py',
'feature_nulldummy.py',
'wallet_import_rescan.py',
Expand Down

0 comments on commit b87d341

Please sign in to comment.