aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kraft <d@domob.eu>2018-06-29 16:10:01 +0200
committerDaniel Kraft <d@domob.eu>2018-07-05 08:02:22 +0200
commit161e8d40a4e4c0e701b6c8142b8dcacf2190545e (patch)
tree1a897ac73c6e7c6d60b0f46f9624481f1b854af3
parentcaac39b0ace38aa088d88c1a5a9a9dbb4d2e893f (diff)
RPC: Add new getzmqnotifications method.
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 https://github.com/bitcoin/bitcoin/issues/13526.
-rw-r--r--doc/release-notes.md2
-rw-r--r--src/Makefile.am6
-rw-r--r--src/init.cpp4
-rw-r--r--src/zmq/zmqnotificationinterface.cpp11
-rw-r--r--src/zmq/zmqnotificationinterface.h4
-rw-r--r--src/zmq/zmqrpc.cpp61
-rw-r--r--src/zmq/zmqrpc.h12
-rwxr-xr-xtest/functional/rpc_zmq.py33
-rwxr-xr-xtest/functional/test_runner.py1
9 files changed, 130 insertions, 4 deletions
diff --git a/doc/release-notes.md b/doc/release-notes.md
index e1bb84cca9..57f93abe03 100644
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -79,6 +79,8 @@ RPC changes
`getmempoolentry` when verbosity is set to `true` with sub-fields `ancestor`, `base`, `modified`
and `descendant` denominated in BTC. This new field deprecates previous fee fields, such as
`fee`, `modifiedfee`, `ancestorfee` and `descendantfee`.
+- The new RPC `getzmqnotifications` returns information about active ZMQ
+ notifications.
External wallet files
---------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index a2599d33e1..d78f75e200 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -193,7 +193,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
@@ -253,7 +254,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
diff --git a/src/init.cpp b/src/init.cpp
index 299b478e85..79f1ba91b7 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -62,6 +62,7 @@
#if ENABLE_ZMQ
#include <zmq/zmqnotificationinterface.h>
+#include <zmq/zmqrpc.h>
#endif
bool fFeeEstimatesInitialized = false;
@@ -1287,6 +1288,9 @@ bool AppInitMain()
*/
RegisterAllCoreRPCCommands(tableRPC);
g_wallet_init_interface.RegisterRPC(tableRPC);
+#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
diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp
index 89ae62f4cb..8cbc969972 100644
--- a/src/zmq/zmqnotificationinterface.cpp
+++ b/src/zmq/zmqnotificationinterface.cpp
@@ -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.
@@ -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;
diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h
index 3fcc96ce24..a0cc26a162 100644
--- a/src/zmq/zmqnotificationinterface.h
+++ b/src/zmq/zmqnotificationinterface.h
@@ -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.
@@ -18,6 +18,8 @@ class CZMQNotificationInterface final : public CValidationInterface
public:
virtual ~CZMQNotificationInterface();
+ std::list<const CZMQAbstractNotifier*> GetActiveNotifiers() const;
+
static CZMQNotificationInterface* Create();
protected:
diff --git a/src/zmq/zmqrpc.cpp b/src/zmq/zmqrpc.cpp
new file mode 100644
index 0000000000..4f88bf4eb9
--- /dev/null
+++ b/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);
+ }
+}
diff --git a/src/zmq/zmqrpc.h b/src/zmq/zmqrpc.h
new file mode 100644
index 0000000000..5a810a16fb
--- /dev/null
+++ b/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
diff --git a/test/functional/rpc_zmq.py b/test/functional/rpc_zmq.py
new file mode 100755
index 0000000000..eb789face2
--- /dev/null
+++ b/test/functional/rpc_zmq.py
@@ -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()
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 36101d9f57..c3a5468296 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -116,6 +116,7 @@ BASE_SCRIPTS = [
'feature_versionbits_warning.py',
'rpc_preciousblock.py',
'wallet_importprunedfunds.py',
+ 'rpc_zmq.py',
'rpc_signmessage.py',
'feature_nulldummy.py',
'mempool_accept.py',