Skip to content

Commit a247594

Browse files
committed
Merge #13570: RPC: Add new "getzmqnotifications" method
161e8d4 RPC: Add new getzmqnotifications method. (Daniel Kraft) caac39b Make ZMQ notification interface instance global. (Daniel Kraft) Pull request description: 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 #13526. Tree-SHA512: edce722925741c84ddbf7b3a879fc9db1907e5269d0d97138fe724035d93ee541c2118c24fa92f4197403f380d0e25c2fda5ca6c62d526792ea749cf527a99a0
2 parents 17e9106 + 161e8d4 commit a247594

File tree

9 files changed

+141
-15
lines changed

9 files changed

+141
-15
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
@@ -194,7 +194,8 @@ BITCOIN_CORE_H = \
194194
zmq/zmqabstractnotifier.h \
195195
zmq/zmqconfig.h\
196196
zmq/zmqnotificationinterface.h \
197-
zmq/zmqpublishnotifier.h
197+
zmq/zmqpublishnotifier.h \
198+
zmq/zmqrpc.h
198199

199200

200201
obj/build.h: FORCE
@@ -255,7 +256,8 @@ libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
255256
libbitcoin_zmq_a_SOURCES = \
256257
zmq/zmqabstractnotifier.cpp \
257258
zmq/zmqnotificationinterface.cpp \
258-
zmq/zmqpublishnotifier.cpp
259+
zmq/zmqpublishnotifier.cpp \
260+
zmq/zmqrpc.cpp
259261
endif
260262

261263

src/init.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363

6464
#if ENABLE_ZMQ
6565
#include <zmq/zmqnotificationinterface.h>
66+
#include <zmq/zmqrpc.h>
6667
#endif
6768

6869
bool fFeeEstimatesInitialized = false;
@@ -100,10 +101,6 @@ void DummyWalletInit::AddWalletOptions() const
100101
const WalletInitInterface& g_wallet_init_interface = DummyWalletInit();
101102
#endif
102103

103-
#if ENABLE_ZMQ
104-
static CZMQNotificationInterface* pzmqNotificationInterface = nullptr;
105-
#endif
106-
107104
#ifdef WIN32
108105
// Win32 LevelDB doesn't use filedescriptors, and the ones used for
109106
// accessing block files don't count towards the fd_set size limit
@@ -269,10 +266,10 @@ void Shutdown()
269266
g_wallet_init_interface.Stop();
270267

271268
#if ENABLE_ZMQ
272-
if (pzmqNotificationInterface) {
273-
UnregisterValidationInterface(pzmqNotificationInterface);
274-
delete pzmqNotificationInterface;
275-
pzmqNotificationInterface = nullptr;
269+
if (g_zmq_notification_interface) {
270+
UnregisterValidationInterface(g_zmq_notification_interface);
271+
delete g_zmq_notification_interface;
272+
g_zmq_notification_interface = nullptr;
276273
}
277274
#endif
278275

@@ -1282,6 +1279,9 @@ bool AppInitMain()
12821279
*/
12831280
RegisterAllCoreRPCCommands(tableRPC);
12841281
g_wallet_init_interface.RegisterRPC(tableRPC);
1282+
#if ENABLE_ZMQ
1283+
RegisterZMQRPCCommands(tableRPC);
1284+
#endif
12851285

12861286
/* Start the RPC server already. It will be started in "warmup" mode
12871287
* and not really process calls already (but it will signify connections
@@ -1398,10 +1398,10 @@ bool AppInitMain()
13981398
}
13991399

14001400
#if ENABLE_ZMQ
1401-
pzmqNotificationInterface = CZMQNotificationInterface::Create();
1401+
g_zmq_notification_interface = CZMQNotificationInterface::Create();
14021402

1403-
if (pzmqNotificationInterface) {
1404-
RegisterValidationInterface(pzmqNotificationInterface);
1403+
if (g_zmq_notification_interface) {
1404+
RegisterValidationInterface(g_zmq_notification_interface);
14051405
}
14061406
#endif
14071407
uint64_t nMaxOutboundLimit = 0; //unlimited unless -maxuploadtarget is set

src/zmq/zmqnotificationinterface.cpp

Lines changed: 12 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;
@@ -180,3 +189,5 @@ void CZMQNotificationInterface::BlockDisconnected(const std::shared_ptr<const CB
180189
TransactionAddedToMempool(ptx);
181190
}
182191
}
192+
193+
CZMQNotificationInterface* g_zmq_notification_interface = nullptr;

src/zmq/zmqnotificationinterface.h

Lines changed: 5 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:
@@ -37,4 +39,6 @@ class CZMQNotificationInterface final : public CValidationInterface
3739
std::list<CZMQAbstractNotifier*> notifiers;
3840
};
3941

42+
extern CZMQNotificationInterface* g_zmq_notification_interface;
43+
4044
#endif // BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H

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)