Skip to content

Commit 161e8d4

Browse files
committed
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 bitcoin/bitcoin#13526.
1 parent caac39b commit 161e8d4

File tree

9 files changed

+130
-4
lines changed

9 files changed

+130
-4
lines changed

doc/release-notes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ RPC changes
7979
`getmempoolentry` when verbosity is set to `true` with sub-fields `ancestor`, `base`, `modified`
8080
and `descendant` denominated in BTC. This new field deprecates previous fee fields, such as
8181
`fee`, `modifiedfee`, `ancestorfee` and `descendantfee`.
82+
- The new RPC `getzmqnotifications` returns information about active ZMQ
83+
notifications.
8284

8385
External wallet files
8486
---------------------

src/Makefile.am

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,8 @@ BITCOIN_CORE_H = \
193193
zmq/zmqabstractnotifier.h \
194194
zmq/zmqconfig.h\
195195
zmq/zmqnotificationinterface.h \
196-
zmq/zmqpublishnotifier.h
196+
zmq/zmqpublishnotifier.h \
197+
zmq/zmqrpc.h
197198

198199

199200
obj/build.h: FORCE
@@ -253,7 +254,8 @@ libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
253254
libbitcoin_zmq_a_SOURCES = \
254255
zmq/zmqabstractnotifier.cpp \
255256
zmq/zmqnotificationinterface.cpp \
256-
zmq/zmqpublishnotifier.cpp
257+
zmq/zmqpublishnotifier.cpp \
258+
zmq/zmqrpc.cpp
257259
endif
258260

259261

src/init.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262

6363
#if ENABLE_ZMQ
6464
#include <zmq/zmqnotificationinterface.h>
65+
#include <zmq/zmqrpc.h>
6566
#endif
6667

6768
bool fFeeEstimatesInitialized = false;
@@ -1287,6 +1288,9 @@ bool AppInitMain()
12871288
*/
12881289
RegisterAllCoreRPCCommands(tableRPC);
12891290
g_wallet_init_interface.RegisterRPC(tableRPC);
1291+
#if ENABLE_ZMQ
1292+
RegisterZMQRPCCommands(tableRPC);
1293+
#endif
12901294

12911295
/* Start the RPC server already. It will be started in "warmup" mode
12921296
* and not really process calls already (but it will signify connections

src/zmq/zmqnotificationinterface.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2015-2017 The Bitcoin Core developers
1+
// Copyright (c) 2015-2018 The Bitcoin Core developers
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

@@ -29,6 +29,15 @@ CZMQNotificationInterface::~CZMQNotificationInterface()
2929
}
3030
}
3131

32+
std::list<const CZMQAbstractNotifier*> CZMQNotificationInterface::GetActiveNotifiers() const
33+
{
34+
std::list<const CZMQAbstractNotifier*> result;
35+
for (const auto* n : notifiers) {
36+
result.push_back(n);
37+
}
38+
return result;
39+
}
40+
3241
CZMQNotificationInterface* CZMQNotificationInterface::Create()
3342
{
3443
CZMQNotificationInterface* notificationInterface = nullptr;

src/zmq/zmqnotificationinterface.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2015-2017 The Bitcoin Core developers
1+
// Copyright (c) 2015-2018 The Bitcoin Core developers
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

@@ -18,6 +18,8 @@ class CZMQNotificationInterface final : public CValidationInterface
1818
public:
1919
virtual ~CZMQNotificationInterface();
2020

21+
std::list<const CZMQAbstractNotifier*> GetActiveNotifiers() const;
22+
2123
static CZMQNotificationInterface* Create();
2224

2325
protected:

src/zmq/zmqrpc.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) 2018 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <zmq/zmqrpc.h>
6+
7+
#include <rpc/server.h>
8+
#include <zmq/zmqabstractnotifier.h>
9+
#include <zmq/zmqnotificationinterface.h>
10+
11+
#include <univalue.h>
12+
13+
namespace {
14+
15+
UniValue getzmqnotifications(const JSONRPCRequest& request)
16+
{
17+
if (request.fHelp || request.params.size() != 0) {
18+
throw std::runtime_error(
19+
"getzmqnotifications\n"
20+
"\nReturns information about the active ZeroMQ notifications.\n"
21+
"\nResult:\n"
22+
"[\n"
23+
" { (json object)\n"
24+
" \"type\": \"pubhashtx\", (string) Type of notification\n"
25+
" \"address\": \"...\" (string) Address of the publisher\n"
26+
" },\n"
27+
" ...\n"
28+
"]\n"
29+
"\nExamples:\n"
30+
+ HelpExampleCli("getzmqnotifications", "")
31+
+ HelpExampleRpc("getzmqnotifications", "")
32+
);
33+
}
34+
35+
UniValue result(UniValue::VARR);
36+
if (g_zmq_notification_interface != nullptr) {
37+
for (const auto* n : g_zmq_notification_interface->GetActiveNotifiers()) {
38+
UniValue obj(UniValue::VOBJ);
39+
obj.pushKV("type", n->GetType());
40+
obj.pushKV("address", n->GetAddress());
41+
result.push_back(obj);
42+
}
43+
}
44+
45+
return result;
46+
}
47+
48+
const CRPCCommand commands[] =
49+
{ // category name actor (function) argNames
50+
// ----------------- ------------------------ ----------------------- ----------
51+
{ "zmq", "getzmqnotifications", &getzmqnotifications, {} },
52+
};
53+
54+
} // anonymous namespace
55+
56+
void RegisterZMQRPCCommands(CRPCTable& t)
57+
{
58+
for (const auto& c : commands) {
59+
t.appendCommand(c.name, &c);
60+
}
61+
}

src/zmq/zmqrpc.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) 2018 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_ZMQ_ZMQRPC_H
6+
#define BITCOIN_ZMQ_ZMQRPC_H
7+
8+
class CRPCTable;
9+
10+
void RegisterZMQRPCCommands(CRPCTable& t);
11+
12+
#endif // BITCOIN_ZMQ_ZMRRPC_H

test/functional/rpc_zmq.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2018 The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
"""Test for the ZMQ RPC methods."""
6+
7+
from test_framework.test_framework import BitcoinTestFramework
8+
from test_framework.util import assert_equal
9+
10+
11+
class RPCZMQTest(BitcoinTestFramework):
12+
13+
address = "tcp://127.0.0.1:28332"
14+
15+
def set_test_params(self):
16+
self.num_nodes = 1
17+
self.setup_clean_chain = True
18+
19+
def run_test(self):
20+
self._test_getzmqnotifications()
21+
22+
def _test_getzmqnotifications(self):
23+
self.restart_node(0, extra_args=[])
24+
assert_equal(self.nodes[0].getzmqnotifications(), [])
25+
26+
self.restart_node(0, extra_args=["-zmqpubhashtx=%s" % self.address])
27+
assert_equal(self.nodes[0].getzmqnotifications(), [
28+
{"type": "pubhashtx", "address": self.address},
29+
])
30+
31+
32+
if __name__ == '__main__':
33+
RPCZMQTest().main()

test/functional/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
'feature_versionbits_warning.py',
117117
'rpc_preciousblock.py',
118118
'wallet_importprunedfunds.py',
119+
'rpc_zmq.py',
119120
'rpc_signmessage.py',
120121
'feature_nulldummy.py',
121122
'mempool_accept.py',

0 commit comments

Comments
 (0)