From 7e6ec078fa92bc8d2a35074de1279d6b8296dfcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Thu, 7 May 2015 15:49:00 +0100 Subject: [PATCH 01/35] Add UpdatedBlockTip signal to CMainSignals and CValidationInterface --- src/main.cpp | 1 + src/validationinterface.cpp | 4 ++++ src/validationinterface.h | 3 +++ 3 files changed, 8 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index d5c9198f..70be4445 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2707,6 +2707,7 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) { pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip)); } // Notify external listeners about the new tip. + GetMainSignals().UpdatedBlockTip(hashNewTip); uiInterface.NotifyBlockTip(hashNewTip); } } while(pindexMostWork != chainActive.Tip()); diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index 3df6cd3f..d06fd9a8 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -13,6 +13,7 @@ CMainSignals& GetMainSignals() } void RegisterValidationInterface(CValidationInterface* pwalletIn) { + g_signals.UpdatedBlockTip.connect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1)); g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); @@ -32,6 +33,7 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) { g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); + g_signals.UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1)); } void UnregisterAllValidationInterfaces() { @@ -43,6 +45,8 @@ void UnregisterAllValidationInterfaces() { g_signals.UpdatedTransaction.disconnect_all_slots(); g_signals.EraseTransaction.disconnect_all_slots(); g_signals.SyncTransaction.disconnect_all_slots(); + g_signals.UpdatedTransaction.disconnect_all_slots(); + g_signals.UpdatedBlockTip.disconnect_all_slots(); } void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) { diff --git a/src/validationinterface.h b/src/validationinterface.h index 144e716b..70489cb3 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -31,6 +31,7 @@ void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL); class CValidationInterface { protected: + virtual void UpdatedBlockTip(const uint256 &newHashTip) {} virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {} virtual void EraseFromWallet(const uint256 &hash) {} virtual void ChainTip(const CBlockIndex *pindex, const CBlock *pblock, ZCIncrementalMerkleTree tree, bool added) {} @@ -45,6 +46,8 @@ protected: }; struct CMainSignals { + /** Notifies listeners of updated block chain tip */ + boost::signals2::signal UpdatedBlockTip; /** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */ boost::signals2::signal SyncTransaction; /** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */ From cce7754eb809472015b1611a3b6a029d0b476837 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 5 May 2015 20:30:20 -0400 Subject: [PATCH 02/35] Depends: Add ZeroMQ package --- depends/packages/packages.mk | 2 ++ depends/packages/zeromq.mk | 26 ++++++++++++++++++++++++++ qa/pull-tester/rpc-tests.sh | 4 ++++ qa/pull-tester/tests-config.sh.in | 1 + 4 files changed, 33 insertions(+) create mode 100644 depends/packages/zeromq.mk diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index babc1598..ee577e88 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,5 +1,7 @@ zcash_packages := libsnark libgmp libsodium packages := boost openssl $(zcash_packages) googletest googlemock +packages_darwin:=zeromq +packages_linux:=zeromq native_packages := native_ccache wallet_packages=bdb diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk new file mode 100644 index 00000000..24e8e5f1 --- /dev/null +++ b/depends/packages/zeromq.mk @@ -0,0 +1,26 @@ +package=zeromq +$(package)_version=4.0.4 +$(package)_download_path=http://download.zeromq.org +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_sha256_hash=1ef71d46e94f33e27dd5a1661ed626cd39be4d2d6967792a275040e34457d399 + +define $(package)_set_vars + $(package)_config_opts=--without-documentation --disable-shared + $(package)_config_opts_linux=--with-pic +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) -C src +endef + +define $(package)_stage_cmds + $(MAKE) -C src DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm -rf bin share +endef diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 28e59d55..eb30517a 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -57,6 +57,10 @@ testScriptsExt=( 'p2p-acceptblock.py' ); +if [ "x$ENABLE_ZMQ" = "x1" ]; then + testScripts=( ${testScripts[@]} 'zmq_test.py' ) +fi + extArg="-extended" passOn=${@#$extArg} diff --git a/qa/pull-tester/tests-config.sh.in b/qa/pull-tester/tests-config.sh.in index 1c27b15e..1cb9ee06 100755 --- a/qa/pull-tester/tests-config.sh.in +++ b/qa/pull-tester/tests-config.sh.in @@ -10,6 +10,7 @@ EXEEXT="@EXEEXT@" @ENABLE_WALLET_TRUE@ENABLE_WALLET=1 @BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=1 @BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=1 +@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=1 REAL_BITCOIND="$BUILDDIR/src/zcashd${EXEEXT}" REAL_BITCOINCLI="$BUILDDIR/src/zcash-cli${EXEEXT}" From f200002cf3f8a6921cca0cad65e0cd58d0dec973 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 18 Nov 2014 12:06:32 -0500 Subject: [PATCH 03/35] Add ZeroMQ support. Notify blocks and transactions via ZeroMQ Continues Johnathan Corgan's work. Publishing multipart messages Bugfix: Add missing zmq header includes Bugfix: Adjust build system to link ZeroMQ code for Qt binaries --- configure.ac | 22 ++++ contrib/zmq/zmq_sub.py | 37 ++++++ doc/zmq.md | 98 +++++++++++++++ src/Makefile.am | 26 +++- src/Makefile.qt.include | 3 + src/Makefile.qttest.include | 3 + src/Makefile.test.include | 4 + src/init.cpp | 36 +++++- src/validationinterface.cpp | 1 - src/zmq/zmqabstractnotifier.cpp | 22 ++++ src/zmq/zmqabstractnotifier.h | 42 +++++++ src/zmq/zmqconfig.h | 24 ++++ src/zmq/zmqnotificationinterface.cpp | 155 ++++++++++++++++++++++++ src/zmq/zmqnotificationinterface.h | 35 ++++++ src/zmq/zmqpublishnotifier.cpp | 172 +++++++++++++++++++++++++++ src/zmq/zmqpublishnotifier.h | 41 +++++++ 16 files changed, 717 insertions(+), 4 deletions(-) create mode 100755 contrib/zmq/zmq_sub.py create mode 100644 doc/zmq.md create mode 100644 src/zmq/zmqabstractnotifier.cpp create mode 100644 src/zmq/zmqabstractnotifier.h create mode 100644 src/zmq/zmqconfig.h create mode 100644 src/zmq/zmqnotificationinterface.cpp create mode 100644 src/zmq/zmqnotificationinterface.h create mode 100644 src/zmq/zmqpublishnotifier.cpp create mode 100644 src/zmq/zmqpublishnotifier.h diff --git a/configure.ac b/configure.ac index 8a666ec6..3d312ca8 100644 --- a/configure.ac +++ b/configure.ac @@ -150,6 +150,12 @@ AC_ARG_ENABLE([glibc-back-compat], [use_glibc_compat=$enableval], [use_glibc_compat=no]) +AC_ARG_ENABLE([zmq], + [AC_HELP_STRING([--disable-zmq], + [Disable ZMQ notifications])], + [use_zmq=$enableval], + [use_zmq=yes]) + AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], []) # Enable debug @@ -857,6 +863,22 @@ if test x$bitcoin_enable_qt != xno; then fi fi +# conditional search for and use libzmq +AC_MSG_CHECKING([whether to build ZMQ support]) +if test "x$use_zmq" = "xyes"; then + AC_MSG_RESULT([yes]) + PKG_CHECK_MODULES([ZMQ],[libzmq], + [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], + [AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) + AC_MSG_WARN([libzmq not found, disabling]) + use_zmq=no]) +else + AC_MSG_RESULT([no, --disable-zmq used]) + AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) +fi + +AM_CONDITIONAL([ENABLE_ZMQ], [test "x$use_zmq" = "xyes"]) + AC_MSG_CHECKING([whether to build test_bitcoin]) if test x$use_tests = xyes; then AC_MSG_RESULT([yes]) diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py new file mode 100755 index 00000000..decf29d4 --- /dev/null +++ b/contrib/zmq/zmq_sub.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python2 + +import array +import binascii +import zmq + +port = 28332 + +zmqContext = zmq.Context() +zmqSubSocket = zmqContext.socket(zmq.SUB) +zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashblock") +zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashtx") +zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawblock") +zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawtx") +zmqSubSocket.connect("tcp://127.0.0.1:%i" % port) + +try: + while True: + msg = zmqSubSocket.recv_multipart() + topic = str(msg[0]) + body = msg[1] + + if topic == "hashblock": + print "- HASH BLOCK -" + print binascii.hexlify(body) + elif topic == "hashtx": + print '- HASH TX -' + print binascii.hexlify(body) + elif topic == "rawblock": + print "- RAW BLOCK HEADER -" + print binascii.hexlify(body[:80]) + elif topic == "rawtx": + print '- RAW TX -' + print binascii.hexlify(body) + +except KeyboardInterrupt: + zmqContext.destroy() diff --git a/doc/zmq.md b/doc/zmq.md new file mode 100644 index 00000000..fd04f6d9 --- /dev/null +++ b/doc/zmq.md @@ -0,0 +1,98 @@ +# Block and Transaction Broadcasting With ZeroMQ + +[ZeroMQ](http://zeromq.org/) is a lightweight wrapper around TCP +connections, inter-process communications, and shared-memory, +providing various message-oriented semantics such as publish/subcribe, +request/reply, and push/pull. + +The Bitcoin Core daemon can be configured to act as a trusted "border +router", implementing the bitcoin wire protocol and relay, making +consensus decisions, maintaining the local blockchain database, +broadcasting locally generated transactions into the network, and +providing a queryable RPC interface to interact on a polled basis for +requesting blockchain related data. However, there exists only a +limited service to notify external software of events like the arrival +of new blocks or transactions. + +The ZeroMQ facility implements a notification interface through a +set of specific notifiers. Currently there are notifiers that publish +blocks and transactions. This read-only facility requires only the +connection of a corresponding ZeroMQ subscriber port in receiving +software; it is not authenticated nor is there any two-way protocol +involvement. Therefore, subscribers should validate the received data +since it may be out of date, incomplete or even invalid. + +ZeroMQ sockets are self-connecting and self-healing; that is, connects +made between two endpoints will be automatically restored after an +outage, and either end may be freely started or stopped in any order. + +Because ZeroMQ is message oriented, subscribers receive transactions +and blocks all-at-once and do not need to implement any sort of +buffering or reassembly. + +## Prerequisites + +The ZeroMQ feature in Bitcoin Core uses only a very small part of the +ZeroMQ C API, and is thus compatible with any version of ZeroMQ +from 2.1 onward, including all versions in the 3.x and 4.x release +series. Typically, it is packaged by distributions as something like +*libzmq-dev*. + +The C++ wrapper for ZeroMQ is *not* needed. + +## Enabling + +By default, the ZeroMQ port functionality is enabled. Two steps are +required to enable--compiling in the ZeroMQ code, and configuring +runtime operation on the command-line or configuration file. + + $ ./configure --enable-zmq (other options) + +This will produce a binary that is capable of providing the ZeroMQ +facility, but will not do so until also configured properly. + +## Usage + +Currently, the following notifications are supported: + + -zmqpubhashtx=address + -zmqpubhashblock=address + -zmqpubrawblock=address + -zmqpubrawtx=address + +The socket type is PUB and the address must be a valid ZeroMQ +socket address. The same address can be used in more than one notification. + +For instance: + + $ bitcoind -zmqpubhashtx=tcp://127.0.0.1:28332 -zmqpubrawtx=ipc:///tmp/bitcoind.tx.raw + +Each PUB notification has a topic and body, where the header +corresponds to the notification type. For instance, for the notification +`-zmqpubhashtx` the topic is `hashtx` (no null terminator) and the body is the +hexadecimal transaction hash (32 bytes). + +These options can also be provided in bitcoin.conf. + +ZeroMQ endpoint specifiers for TCP (and others) are documented in the +[ZeroMQ API](http://api.zeromq.org). + +Client side, then, the ZeroMQ subscriber socket must have the +ZMQ_SUBSCRIBE option set to one or either of these prefixes (for instance, just `hash`); without +doing so will result in no messages arriving. Please see `contrib/zmq/zmq_sub.py` +for a working example. + +## Remarks + +From the perspective of bitcoind, the ZeroMQ socket is write-only; PUB +sockets don't even have a read function. Thus, there is no state +introduced into bitcoind directly. Furthermore, no information is +broadcast that wasn't already received from the public P2P network. + +No authentication or authorization is done on connecting clients; it +is assumed that the ZeroMQ port is exposed only to trusted entities, +using other means such as firewalling. + +Note that when the block chain tip changes, a reorganisation may occur and just +the tip will be notified. It is up to the subscriber to retrieve the chain +from the last known block to the new tip. diff --git a/src/Makefile.am b/src/Makefile.am index f1807167..54743878 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -50,6 +50,9 @@ if ENABLE_WALLET BITCOIN_INCLUDES += $(BDB_CPPFLAGS) EXTRA_LIBRARIES += libbitcoin_wallet.a endif +if ENABLE_ZMQ +EXTRA_LIBRARIES += libbitcoin_zmq.a +endif if BUILD_BITCOIN_LIBS lib_LTLIBRARIES = libzcashconsensus.la @@ -172,7 +175,12 @@ BITCOIN_CORE_H = \ wallet/db.h \ wallet/wallet.h \ wallet/wallet_ismine.h \ - wallet/walletdb.h + wallet/walletdb.h \ + zmq/zmqabstractnotifier.h \ + zmq/zmqconfig.h\ + zmq/zmqnotificationinterface.h \ + zmq/zmqpublishnotifier.h + JSON_H = \ json/json_spirit.h \ @@ -229,6 +237,17 @@ libbitcoin_server_a_SOURCES = \ $(BITCOIN_CORE_H) \ $(LIBZCASH_H) +if ENABLE_ZMQ +LIBBITCOIN_ZMQ=libbitcoin_zmq.a + +libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) +libbitcoin_zmq_a_SOURCES = \ + zmq/zmqabstractnotifier.cpp \ + zmq/zmqnotificationinterface.cpp \ + zmq/zmqpublishnotifier.cpp +endif + + # wallet: shared between bitcoind and bitcoin-qt, but only linked # when wallet enabled libbitcoin_wallet_a_CPPFLAGS = $(BITCOIN_INCLUDES) @@ -369,6 +388,10 @@ zcashd_LDADD = \ $(LIBMEMENV) \ $(LIBSECP256K1) +if ENABLE_ZMQ +zcashd_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) +endif + if ENABLE_WALLET zcashd_LDADD += libbitcoin_wallet.a endif @@ -382,7 +405,6 @@ zcashd_LDADD += \ $(LIBZCASH) \ $(LIBBITCOIN_CRYPTO) \ $(LIBZCASH_LIBS) -# # bitcoin-cli binary # zcash_cli_SOURCES = bitcoin-cli.cpp diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index d45de8d2..9513da08 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -361,6 +361,9 @@ qt_bitcoin_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER) if ENABLE_WALLET qt_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET) endif +if ENABLE_ZMQ +qt_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) +endif qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) $(LIBZCASH_LIBS) qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index 4963a396..128c3f6d 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -30,6 +30,9 @@ qt_test_test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER) if ENABLE_WALLET qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET) endif +if ENABLE_ZMQ +qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) +endif qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) \ $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \ $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) $(LIBZCASH_LIBS) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 09d34043..56be626d 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -107,6 +107,10 @@ endif test_test_bitcoin_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBZCASH) $(LIBZCASH_LIBS) test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static +if ENABLE_ZMQ +test_test_bitcoin_LDADD += $(ZMQ_LIBS) +endif + nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES) $(BITCOIN_TESTS): $(GENERATED_TEST_FILES) diff --git a/src/init.cpp b/src/init.cpp index cf09fe06..3fc30a28 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -31,7 +31,6 @@ #include "wallet/wallet.h" #include "wallet/walletdb.h" #endif - #include #include @@ -50,6 +49,10 @@ #include "libsnark/common/profiling.hpp" +#if ENABLE_ZMQ +#include "zmq/zmqnotificationinterface.h" +#endif + using namespace std; extern void ThreadSendAlert(); @@ -61,6 +64,10 @@ CWallet* pwalletMain = NULL; #endif bool fFeeEstimatesInitialized = false; +#if ENABLE_ZMQ +static CZMQNotificationInterface* pzmqNotificationInterface = NULL; +#endif + #ifdef WIN32 // Win32 LevelDB doesn't use file descriptors, and the ones used for // accessing block files don't count towards the fd_set size limit @@ -197,6 +204,16 @@ void Shutdown() if (pwalletMain) pwalletMain->Flush(true); #endif + +#if ENABLE_ZMQ + if (pzmqNotificationInterface) { + UnregisterValidationInterface(pzmqNotificationInterface); + pzmqNotificationInterface->Shutdown(); + delete pzmqNotificationInterface; + pzmqNotificationInterface = NULL; + } +#endif + #ifndef WIN32 try { boost::filesystem::remove(GetPidFile()); @@ -365,6 +382,14 @@ std::string HelpMessage(HelpMessageMode mode) #endif +#if ENABLE_ZMQ + strUsage += HelpMessageGroup(_("ZeroMQ notification options:")); + strUsage += HelpMessageOpt("-zmqpubhashblock=
", _("Enable publish hash block in
")); + strUsage += HelpMessageOpt("-zmqpubhashtransaction=
", _("Enable publish hash transaction in
")); + strUsage += HelpMessageOpt("-zmqpubrawblock=
", _("Enable publish raw block in
")); + strUsage += HelpMessageOpt("-zmqpubrawtransaction=
", _("Enable publish raw transaction in
")); +#endif + strUsage += HelpMessageGroup(_("Debugging/Testing options:")); if (showDebug) { @@ -1141,6 +1166,15 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"]) AddOneShot(strDest); +#if ENABLE_ZMQ + pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs); + + if (pzmqNotificationInterface) { + pzmqNotificationInterface->Initialize(); + RegisterValidationInterface(pzmqNotificationInterface); + } +#endif + // ********************************************************* Step 7: load block chain fReindex = GetBoolArg("-reindex", false); diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index d06fd9a8..cd3e30f3 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -45,7 +45,6 @@ void UnregisterAllValidationInterfaces() { g_signals.UpdatedTransaction.disconnect_all_slots(); g_signals.EraseTransaction.disconnect_all_slots(); g_signals.SyncTransaction.disconnect_all_slots(); - g_signals.UpdatedTransaction.disconnect_all_slots(); g_signals.UpdatedBlockTip.disconnect_all_slots(); } diff --git a/src/zmq/zmqabstractnotifier.cpp b/src/zmq/zmqabstractnotifier.cpp new file mode 100644 index 00000000..744ec592 --- /dev/null +++ b/src/zmq/zmqabstractnotifier.cpp @@ -0,0 +1,22 @@ +// Copyright (c) 2015 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 "zmqabstractnotifier.h" +#include "util.h" + + +CZMQAbstractNotifier::~CZMQAbstractNotifier() +{ + assert(!psocket); +} + +bool CZMQAbstractNotifier::NotifyBlock(const uint256 &/*hash*/) +{ + return true; +} + +bool CZMQAbstractNotifier::NotifyTransaction(const CTransaction &/*transaction*/) +{ + return true; +} diff --git a/src/zmq/zmqabstractnotifier.h b/src/zmq/zmqabstractnotifier.h new file mode 100644 index 00000000..626d1ddf --- /dev/null +++ b/src/zmq/zmqabstractnotifier.h @@ -0,0 +1,42 @@ +// Copyright (c) 2015 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_ZMQABSTRACTNOTIFIER_H +#define BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H + +#include "zmqconfig.h" + +class CZMQAbstractNotifier; +typedef CZMQAbstractNotifier* (*CZMQNotifierFactory)(); + +class CZMQAbstractNotifier +{ +public: + CZMQAbstractNotifier() : psocket(0) { } + virtual ~CZMQAbstractNotifier(); + + template + static CZMQAbstractNotifier* Create() + { + return new T(); + } + + std::string GetType() const { return type; } + void SetType(const std::string &t) { type = t; } + std::string GetAddress() const { return address; } + void SetAddress(const std::string &a) { address = a; } + + virtual bool Initialize(void *pcontext) = 0; + virtual void Shutdown() = 0; + + virtual bool NotifyBlock(const uint256 &hash); + virtual bool NotifyTransaction(const CTransaction &transaction); + +protected: + void *psocket; + std::string type; + std::string address; +}; + +#endif // BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H diff --git a/src/zmq/zmqconfig.h b/src/zmq/zmqconfig.h new file mode 100644 index 00000000..6057f5d1 --- /dev/null +++ b/src/zmq/zmqconfig.h @@ -0,0 +1,24 @@ +// Copyright (c) 2015 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_ZMQCONFIG_H +#define BITCOIN_ZMQ_ZMQCONFIG_H + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include +#include + +#if ENABLE_ZMQ +#include +#endif + +#include "primitives/block.h" +#include "primitives/transaction.h" + +void zmqError(const char *str); + +#endif // BITCOIN_ZMQ_ZMQCONFIG_H diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp new file mode 100644 index 00000000..71ccb59a --- /dev/null +++ b/src/zmq/zmqnotificationinterface.cpp @@ -0,0 +1,155 @@ +// Copyright (c) 2015 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 "zmqnotificationinterface.h" +#include "zmqpublishnotifier.h" + +#include "version.h" +#include "main.h" +#include "streams.h" +#include "util.h" + +void zmqError(const char *str) +{ + LogPrint("zmq", "Error: %s, errno=%s\n", str, zmq_strerror(errno)); +} + +CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(NULL) +{ +} + +CZMQNotificationInterface::~CZMQNotificationInterface() +{ + // ensure Shutdown if Initialize is called + assert(!pcontext); + + for (std::list::iterator i=notifiers.begin(); i!=notifiers.end(); ++i) + { + delete *i; + } +} + +CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const std::map &args) +{ + CZMQNotificationInterface* notificationInterface = NULL; + std::map factories; + std::list notifiers; + + factories["pubhashblock"] = CZMQAbstractNotifier::Create; + factories["pubhashtx"] = CZMQAbstractNotifier::Create; + factories["pubrawblock"] = CZMQAbstractNotifier::Create; + factories["pubrawtx"] = CZMQAbstractNotifier::Create; + + for (std::map::const_iterator i=factories.begin(); i!=factories.end(); ++i) + { + std::map::const_iterator j = args.find("-zmq" + i->first); + if (j!=args.end()) + { + CZMQNotifierFactory factory = i->second; + std::string address = j->second; + CZMQAbstractNotifier *notifier = factory(); + notifier->SetType(i->first); + notifier->SetAddress(address); + notifiers.push_back(notifier); + } + } + + if (!notifiers.empty()) + { + notificationInterface = new CZMQNotificationInterface(); + notificationInterface->notifiers = notifiers; + } + + return notificationInterface; +} + +// Called at startup to conditionally set up ZMQ socket(s) +bool CZMQNotificationInterface::Initialize() +{ + LogPrint("zmq", "Initialize notification interface\n"); + assert(!pcontext); + + pcontext = zmq_init(1); + + if (!pcontext) + { + zmqError("Unable to initialize context"); + return false; + } + + std::list::iterator i=notifiers.begin(); + for (; i!=notifiers.end(); ++i) + { + CZMQAbstractNotifier *notifier = *i; + if (notifier->Initialize(pcontext)) + { + LogPrint("zmq", " Notifier %s ready (address = %s)\n", notifier->GetType(), notifier->GetAddress()); + } + else + { + LogPrint("zmq", " Notifier %s failed (address = %s)\n", notifier->GetType(), notifier->GetAddress()); + break; + } + } + + if (i!=notifiers.end()) + { + Shutdown(); + return false; + } + + return false; +} + +// Called during shutdown sequence +void CZMQNotificationInterface::Shutdown() +{ + LogPrint("zmq", "Shutdown notification interface\n"); + if (pcontext) + { + for (std::list::iterator i=notifiers.begin(); i!=notifiers.end(); ++i) + { + CZMQAbstractNotifier *notifier = *i; + LogPrint("zmq", " Shutdown notifier %s at %s\n", notifier->GetType(), notifier->GetAddress()); + notifier->Shutdown(); + } + zmq_ctx_destroy(pcontext); + + pcontext = 0; + } +} + +void CZMQNotificationInterface::UpdatedBlockTip(const uint256 &hash) +{ + for (std::list::iterator i = notifiers.begin(); i!=notifiers.end(); ) + { + CZMQAbstractNotifier *notifier = *i; + if (notifier->NotifyBlock(hash)) + { + i++; + } + else + { + notifier->Shutdown(); + i = notifiers.erase(i); + } + } +} + +void CZMQNotificationInterface::SyncTransaction(const CTransaction &tx, const CBlock *pblock) +{ + for (std::list::iterator i = notifiers.begin(); i!=notifiers.end(); ) + { + CZMQAbstractNotifier *notifier = *i; + if (notifier->NotifyTransaction(tx)) + { + i++; + } + else + { + notifier->Shutdown(); + i = notifiers.erase(i); + } + } +} diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h new file mode 100644 index 00000000..afc0b8d2 --- /dev/null +++ b/src/zmq/zmqnotificationinterface.h @@ -0,0 +1,35 @@ +// Copyright (c) 2015 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_ZMQNOTIFICATIONINTERFACE_H +#define BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H + +#include "validationinterface.h" +#include +#include + +class CZMQAbstractNotifier; + +class CZMQNotificationInterface : public CValidationInterface +{ +public: + virtual ~CZMQNotificationInterface(); + + static CZMQNotificationInterface* CreateWithArguments(const std::map &args); + + bool Initialize(); + void Shutdown(); + +protected: // CValidationInterface + void SyncTransaction(const CTransaction &tx, const CBlock *pblock); + void UpdatedBlockTip(const uint256 &newHashTip); + +private: + CZMQNotificationInterface(); + + void *pcontext; + std::list notifiers; +}; + +#endif // BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp new file mode 100644 index 00000000..0a6d7d0d --- /dev/null +++ b/src/zmq/zmqpublishnotifier.cpp @@ -0,0 +1,172 @@ +// Copyright (c) 2015 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 "zmqpublishnotifier.h" +#include "main.h" +#include "util.h" + +static std::multimap mapPublishNotifiers; + +// Internal function to send multipart message +static int zmq_send_multipart(void *sock, const void* data, size_t size, ...) +{ + va_list args; + va_start(args, size); + + while (1) + { + zmq_msg_t msg; + + int rc = zmq_msg_init_size(&msg, size); + if (rc != 0) + { + zmqError("Unable to initialize ZMQ msg"); + return -1; + } + + void *buf = zmq_msg_data(&msg); + memcpy(buf, data, size); + + data = va_arg(args, const void*); + + rc = zmq_msg_send(&msg, sock, data ? ZMQ_SNDMORE : 0); + if (rc == -1) + { + zmqError("Unable to send ZMQ msg"); + zmq_msg_close(&msg); + return -1; + } + + zmq_msg_close(&msg); + + if (!data) + break; + + size = va_arg(args, size_t); + } + return 0; +} + +bool CZMQAbstractPublishNotifier::Initialize(void *pcontext) +{ + assert(!psocket); + + // check if address is being used by other publish notifier + std::multimap::iterator i = mapPublishNotifiers.find(address); + + if (i==mapPublishNotifiers.end()) + { + psocket = zmq_socket(pcontext, ZMQ_PUB); + if (!psocket) + { + zmqError("Failed to create socket"); + return false; + } + + int rc = zmq_bind(psocket, address.c_str()); + if (rc!=0) + { + zmqError("Failed to bind address"); + return false; + } + + // register this notifier for the address, so it can be reused for other publish notifier + mapPublishNotifiers.insert(std::make_pair(address, this)); + return true; + } + else + { + LogPrint("zmq", " Reuse socket for address %s\n", address); + + psocket = i->second->psocket; + mapPublishNotifiers.insert(std::make_pair(address, this)); + + return true; + } +} + +void CZMQAbstractPublishNotifier::Shutdown() +{ + assert(psocket); + + int count = mapPublishNotifiers.count(address); + + // remove this notifier from the list of publishers using this address + typedef std::multimap::iterator iterator; + std::pair iterpair = mapPublishNotifiers.equal_range(address); + + for (iterator it = iterpair.first; it != iterpair.second; ++it) + { + if (it->second==this) + { + mapPublishNotifiers.erase(it); + break; + } + } + + if (count == 1) + { + LogPrint("zmq", "Close socket at address %s\n", address); + int linger = 0; + zmq_setsockopt(psocket, ZMQ_LINGER, &linger, sizeof(linger)); + zmq_close(psocket); + } + + psocket = 0; +} + +bool CZMQPublishHashBlockNotifier::NotifyBlock(const uint256 &hash) +{ + LogPrint("zmq", "Publish hash block %s\n", hash.GetHex()); + char data[32]; + for (unsigned int i = 0; i < 32; i++) + data[31 - i] = hash.begin()[i]; + int rc = zmq_send_multipart(psocket, "hashblock", 9, data, 32, 0); + return rc == 0; +} + +bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction) +{ + uint256 hash = transaction.GetHash(); + LogPrint("zmq", "Publish hash transaction %s\n", hash.GetHex()); + char data[32]; + for (unsigned int i = 0; i < 32; i++) + data[31 - i] = hash.begin()[i]; + int rc = zmq_send_multipart(psocket, "hashtx", 6, data, 32, 0); + return rc == 0; +} + +bool CZMQPublishRawBlockNotifier::NotifyBlock(const uint256 &hash) +{ + LogPrint("zmq", "Publish raw block %s\n", hash.GetHex()); + + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + { + LOCK(cs_main); + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + + if(!ReadBlockFromDisk(block, pblockindex)) + { + zmqError("Can't read block from disk"); + return false; + } + + ss << block; + } + + int rc = zmq_send_multipart(psocket, "rawblock", 8, &(*ss.begin()), ss.size(), 0); + return rc == 0; +} + +bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction) +{ + uint256 hash = transaction.GetHash(); + LogPrint("zmq", "Publish raw transaction %s\n", hash.GetHex()); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << transaction; + int rc = zmq_send_multipart(psocket, "rawtx", 5, &(*ss.begin()), ss.size(), 0); + return rc == 0; +} diff --git a/src/zmq/zmqpublishnotifier.h b/src/zmq/zmqpublishnotifier.h new file mode 100644 index 00000000..a0eb26f5 --- /dev/null +++ b/src/zmq/zmqpublishnotifier.h @@ -0,0 +1,41 @@ +// Copyright (c) 2015 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_ZMQPUBLISHNOTIFIER_H +#define BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H + +#include "zmqabstractnotifier.h" + +class CZMQAbstractPublishNotifier : public CZMQAbstractNotifier +{ +public: + bool Initialize(void *pcontext); + void Shutdown(); +}; + +class CZMQPublishHashBlockNotifier : public CZMQAbstractPublishNotifier +{ +public: + bool NotifyBlock(const uint256 &hash); +}; + +class CZMQPublishHashTransactionNotifier : public CZMQAbstractPublishNotifier +{ +public: + bool NotifyTransaction(const CTransaction &transaction); +}; + +class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier +{ +public: + bool NotifyBlock(const uint256 &hash); +}; + +class CZMQPublishRawTransactionNotifier : public CZMQAbstractPublishNotifier +{ +public: + bool NotifyTransaction(const CTransaction &transaction); +}; + +#endif // BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H From da0e7aa1d7c7408079419d21fcfed3118b85a670 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 5 May 2015 13:19:19 +0200 Subject: [PATCH 04/35] QA: Add ZeroMQ RPC test --- qa/rpc-tests/zmq_test.py | 93 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100755 qa/rpc-tests/zmq_test.py diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py new file mode 100755 index 00000000..fffaf677 --- /dev/null +++ b/qa/rpc-tests/zmq_test.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python2 +# Copyright (c) 2015 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 ZMQ interface +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +import zmq +import binascii +from test_framework.mininode import hash256 + +try: + import http.client as httplib +except ImportError: + import httplib +try: + import urllib.parse as urlparse +except ImportError: + import urlparse + +class ZMQTest (BitcoinTestFramework): + + port = 28332 + + def setup_nodes(self): + self.zmqContext = zmq.Context() + self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) + self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashblock") + self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashtx") + self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % self.port) + # Note: proxies are not used to connect to local nodes + # this is because the proxy to use is based on CService.GetNetwork(), which return NET_UNROUTABLE for localhost + return start_nodes(4, self.options.tmpdir, extra_args=[ + ['-zmqpubhashtx=tcp://127.0.0.1:'+str(self.port), '-zmqpubhashblock=tcp://127.0.0.1:'+str(self.port)], + [], + [], + [] + ]) + + def run_test(self): + self.sync_all() + + genhashes = self.nodes[0].generate(1); + self.sync_all() + + print "listen..." + msg = self.zmqSubSocket.recv_multipart() + topic = str(msg[0]) + body = msg[1] + + msg = self.zmqSubSocket.recv_multipart() + topic = str(msg[0]) + body = msg[1] + blkhash = binascii.hexlify(body) + + assert_equal(genhashes[0], blkhash) #blockhash from generate must be equal to the hash received over zmq + + n = 10 + genhashes = self.nodes[1].generate(n); + self.sync_all() + + zmqHashes = [] + for x in range(0,n*2): + msg = self.zmqSubSocket.recv_multipart() + topic = str(msg[0]) + body = msg[1] + if topic == "hashblock": + zmqHashes.append(binascii.hexlify(body)) + + for x in range(0,n): + assert_equal(genhashes[x], zmqHashes[x]) #blockhash from generate must be equal to the hash received over zmq + + #test tx from a second node + hashRPC = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.0) + self.sync_all() + + #now we should receive a zmq msg because the tx was broadcastet + msg = self.zmqSubSocket.recv_multipart() + topic = str(msg[0]) + body = msg[1] + hashZMQ = "" + if topic == "hashtx": + hashZMQ = binascii.hexlify(body) + + assert_equal(hashRPC, hashZMQ) #blockhash from generate must be equal to the hash received over zmq + + +if __name__ == '__main__': + ZMQTest ().main () From 0388c23a768f12dc47c1d2cdd49ee0f66577644b Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 17 Sep 2015 14:30:46 +0200 Subject: [PATCH 05/35] depends: fix platform specific packages variable prefix instead of postfix --- depends/packages/packages.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index ee577e88..034f951e 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,7 +1,7 @@ zcash_packages := libsnark libgmp libsodium packages := boost openssl $(zcash_packages) googletest googlemock -packages_darwin:=zeromq -packages_linux:=zeromq +darwin_packages:=zeromq +linux_packages:=zeromq native_packages := native_ccache wallet_packages=bdb From 8b99caa3e6826262dfd0fcf3c93bc2da728b3474 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 30 Aug 2016 19:46:14 +1200 Subject: [PATCH 06/35] Add ZMQ libs to zcash-gtest --- src/Makefile.gtest.include | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index bb12b052..3f076161 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -44,6 +44,9 @@ zcash_gtest_CPPFLAGS = -DMULTICORE -fopenmp -DBINARY_OUTPUT -DCURVE_ALT_BN128 -D zcash_gtest_LDADD = -lgtest -lgmock $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) +if ENABLE_ZMQ +zcash_gtest_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) +endif if ENABLE_WALLET zcash_gtest_LDADD += $(LIBBITCOIN_WALLET) endif From 5c7f84cf2696fed54d9e7005e29a5ac188c24cef Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 17 Sep 2015 16:32:00 +0200 Subject: [PATCH 07/35] [travis] add zmq python module --- .travis.yml | 5 +++-- qa/rpc-tests/zmq_test.py | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0537d69a..56dc118e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,11 +33,11 @@ matrix: - compiler: ": Win32" env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" - compiler: ": 32-bit + dash" - env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" + env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python-zmq" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" - compiler: ": Win64" env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" - compiler: ": bitcoind" - env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" + env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc python-zmq" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" - compiler: ": No wallet" env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": Cross-Mac" @@ -46,6 +46,7 @@ matrix: - compiler: gcc install: - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi + - if [ -n "$PACKAGES" ]; then travis_retry sudo rm -f /etc/apt/sources.list.d/travis_ci_zeromq3-source.list; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi before_script: - unset CC; unset CXX diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py index fffaf677..e949b61f 100755 --- a/qa/rpc-tests/zmq_test.py +++ b/qa/rpc-tests/zmq_test.py @@ -32,8 +32,6 @@ class ZMQTest (BitcoinTestFramework): self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashblock") self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashtx") self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % self.port) - # Note: proxies are not used to connect to local nodes - # this is because the proxy to use is based on CService.GetNetwork(), which return NET_UNROUTABLE for localhost return start_nodes(4, self.options.tmpdir, extra_args=[ ['-zmqpubhashtx=tcp://127.0.0.1:'+str(self.port), '-zmqpubhashblock=tcp://127.0.0.1:'+str(self.port)], [], @@ -41,6 +39,8 @@ class ZMQTest (BitcoinTestFramework): [] ]) + return nodes + def run_test(self): self.sync_all() From 5088de4bb8cca2b83ce98ba9c3f94a36fd84064a Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 29 Sep 2015 17:01:43 -0400 Subject: [PATCH 08/35] travis: install a recent libzmq and pyzmq for tests --- .travis.yml | 6 +++--- qa/rpc-tests/zmq_test.py | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 56dc118e..3b919b32 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,11 +33,11 @@ matrix: - compiler: ": Win32" env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" - compiler: ": 32-bit + dash" - env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python-zmq" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" + env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python-zmq" PPA="ppa:chris-lea/zeromq" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" - compiler: ": Win64" env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" - compiler: ": bitcoind" - env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc python-zmq" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" + env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc python-zmq" PPA="ppa:chris-lea/zeromq" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" - compiler: ": No wallet" env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": Cross-Mac" @@ -45,8 +45,8 @@ matrix: exclude: - compiler: gcc install: + - if [ -n "$PACKAGES" ]; then sudo rm -f /etc/apt/sources.list.d/travis_ci_zeromq3-source.list; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi - - if [ -n "$PACKAGES" ]; then travis_retry sudo rm -f /etc/apt/sources.list.d/travis_ci_zeromq3-source.list; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi before_script: - unset CC; unset CXX diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py index e949b61f..bcb13232 100755 --- a/qa/rpc-tests/zmq_test.py +++ b/qa/rpc-tests/zmq_test.py @@ -39,8 +39,6 @@ class ZMQTest (BitcoinTestFramework): [] ]) - return nodes - def run_test(self): self.sync_all() From b197605e0825b0ddf5c10ec18a6b13fcb06ee9c9 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Tue, 29 Sep 2015 10:18:07 -0700 Subject: [PATCH 09/35] zmq: require version 4.x or newer of libzmq Signed-off-by: Johnathan Corgan --- configure.ac | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 3d312ca8..73a414b9 100644 --- a/configure.ac +++ b/configure.ac @@ -158,7 +158,7 @@ AC_ARG_ENABLE([zmq], AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], []) -# Enable debug +# Enable debug AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], [use debug compiler flags and macros (default is no)])], @@ -169,11 +169,11 @@ if test "x$enable_debug" = xyes; then if test "x$GCC" = xyes; then CFLAGS="-g3 -O0 -DDEBUG" fi - + if test "x$GXX" = xyes; then CXXFLAGS="-g3 -O0 -DDEBUG" fi -fi +fi ## TODO: Remove these hard-coded paths and flags. They are here for the sake of ## compatibility with the legacy buildsystem. @@ -867,10 +867,10 @@ fi AC_MSG_CHECKING([whether to build ZMQ support]) if test "x$use_zmq" = "xyes"; then AC_MSG_RESULT([yes]) - PKG_CHECK_MODULES([ZMQ],[libzmq], + PKG_CHECK_MODULES([ZMQ],[libzmq >= 4], [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], [AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) - AC_MSG_WARN([libzmq not found, disabling]) + AC_MSG_WARN([libzmq version 4.x or greater not found, disabling]) use_zmq=no]) else AC_MSG_RESULT([no, --disable-zmq used]) From 9540b0c61a09be2c4a34107591c0d70aa9d7a832 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Tue, 29 Sep 2015 10:48:45 -0700 Subject: [PATCH 10/35] zmq: update and cleanup build-unix, release-notes, and zmq docs Signed-off-by: Johnathan Corgan --- doc/zmq.md | 53 ++++++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/doc/zmq.md b/doc/zmq.md index fd04f6d9..358d29d0 100644 --- a/doc/zmq.md +++ b/doc/zmq.md @@ -1,7 +1,7 @@ # Block and Transaction Broadcasting With ZeroMQ [ZeroMQ](http://zeromq.org/) is a lightweight wrapper around TCP -connections, inter-process communications, and shared-memory, +connections, inter-process communication, and shared-memory, providing various message-oriented semantics such as publish/subcribe, request/reply, and push/pull. @@ -14,17 +14,18 @@ requesting blockchain related data. However, there exists only a limited service to notify external software of events like the arrival of new blocks or transactions. -The ZeroMQ facility implements a notification interface through a -set of specific notifiers. Currently there are notifiers that publish +The ZeroMQ facility implements a notification interface through a set +of specific notifiers. Currently there are notifiers that publish blocks and transactions. This read-only facility requires only the -connection of a corresponding ZeroMQ subscriber port in receiving +connection of a corresponding ZeroMQ subscriber port in receiving software; it is not authenticated nor is there any two-way protocol involvement. Therefore, subscribers should validate the received data since it may be out of date, incomplete or even invalid. -ZeroMQ sockets are self-connecting and self-healing; that is, connects -made between two endpoints will be automatically restored after an -outage, and either end may be freely started or stopped in any order. +ZeroMQ sockets are self-connecting and self-healing; that is, +connections made between two endpoints will be automatically restored +after an outage, and either end may be freely started or stopped in +any order. Because ZeroMQ is message oriented, subscribers receive transactions and blocks all-at-once and do not need to implement any sort of @@ -32,13 +33,13 @@ buffering or reassembly. ## Prerequisites -The ZeroMQ feature in Bitcoin Core uses only a very small part of the -ZeroMQ C API, and is thus compatible with any version of ZeroMQ -from 2.1 onward, including all versions in the 3.x and 4.x release -series. Typically, it is packaged by distributions as something like -*libzmq-dev*. +The ZeroMQ feature in Bitcoin Core requires ZeroMQ API version 4.x or +newer. Typically, it is packaged by distributions as something like +*libzmq3-dev*. The C++ wrapper for ZeroMQ is *not* needed. -The C++ wrapper for ZeroMQ is *not* needed. +In order to run the example Python client scripts in contrib/ one must +also install *python-zmq*, though this is not necessary for daemon +operation. ## Enabling @@ -60,17 +61,19 @@ Currently, the following notifications are supported: -zmqpubrawblock=address -zmqpubrawtx=address -The socket type is PUB and the address must be a valid ZeroMQ -socket address. The same address can be used in more than one notification. +The socket type is PUB and the address must be a valid ZeroMQ socket +address. The same address can be used in more than one notification. For instance: - $ bitcoind -zmqpubhashtx=tcp://127.0.0.1:28332 -zmqpubrawtx=ipc:///tmp/bitcoind.tx.raw + $ bitcoind -zmqpubhashtx=tcp://127.0.0.1:28332 \ + -zmqpubrawtx=ipc:///tmp/bitcoind.tx.raw Each PUB notification has a topic and body, where the header -corresponds to the notification type. For instance, for the notification -`-zmqpubhashtx` the topic is `hashtx` (no null terminator) and the body is the -hexadecimal transaction hash (32 bytes). +corresponds to the notification type. For instance, for the +notification `-zmqpubhashtx` the topic is `hashtx` (no null +terminator) and the body is the hexadecimal transaction hash (32 +bytes). These options can also be provided in bitcoin.conf. @@ -78,9 +81,9 @@ ZeroMQ endpoint specifiers for TCP (and others) are documented in the [ZeroMQ API](http://api.zeromq.org). Client side, then, the ZeroMQ subscriber socket must have the -ZMQ_SUBSCRIBE option set to one or either of these prefixes (for instance, just `hash`); without -doing so will result in no messages arriving. Please see `contrib/zmq/zmq_sub.py` -for a working example. +ZMQ_SUBSCRIBE option set to one or either of these prefixes (for +instance, just `hash`); without doing so will result in no messages +arriving. Please see `contrib/zmq/zmq_sub.py` for a working example. ## Remarks @@ -93,6 +96,6 @@ No authentication or authorization is done on connecting clients; it is assumed that the ZeroMQ port is exposed only to trusted entities, using other means such as firewalling. -Note that when the block chain tip changes, a reorganisation may occur and just -the tip will be notified. It is up to the subscriber to retrieve the chain -from the last known block to the new tip. +Note that when the block chain tip changes, a reorganisation may occur +and just the tip will be notified. It is up to the subscriber to +retrieve the chain from the last known block to the new tip. From 1afb84314b8b735ee8993bf69fb9bdf15f4fac42 Mon Sep 17 00:00:00 2001 From: paveljanik Date: Wed, 30 Sep 2015 08:40:20 +0200 Subject: [PATCH 11/35] [Trivial] start the help texts with lowercase Zcash: Also include AC_HELP_STRING -> AS_HELP_STRING (ostensibly from merging bitcoin/bitcoin#6317 but the change only occurs in the merge commit ca5e2a18648cdc0f2a756e7d549f509adce25b00, not the PR itself). --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 73a414b9..316373f5 100644 --- a/configure.ac +++ b/configure.ac @@ -151,8 +151,8 @@ AC_ARG_ENABLE([glibc-back-compat], [use_glibc_compat=no]) AC_ARG_ENABLE([zmq], - [AC_HELP_STRING([--disable-zmq], - [Disable ZMQ notifications])], + [AS_HELP_STRING([--disable-zmq], + [disable ZMQ notifications])], [use_zmq=$enableval], [use_zmq=yes]) From effe8a5f9d9e8afbe16164e015bf861e01c4f0f5 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Sat, 3 Oct 2015 12:21:55 -0700 Subject: [PATCH 12/35] autotools: move checking for zmq library to common area in configure.ac * Fixes #6679 * Tested with --disable-zmq * Tested with and without pkgconfig * Tested with and without zmq installed Signed-off-by: Johnathan Corgan --- configure.ac | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/configure.ac b/configure.ac index 316373f5..68de3800 100644 --- a/configure.ac +++ b/configure.ac @@ -693,6 +693,16 @@ if test x$use_pkgconfig = xyes; then if test x$use_qr != xno; then BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) fi + + if test "x$use_zmq" = "xyes"; then + PKG_CHECK_MODULES([ZMQ],[libzmq >= 4], + [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], + [AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) + AC_MSG_WARN([libzmq version 4.x or greater not found, disabling]) + use_zmq=no]) + else + AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) + fi ] ) else @@ -705,6 +715,20 @@ else AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),) AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing)) + if test "x$use_zmq" = "xyes"; then + AC_CHECK_HEADER([zmq.h], + [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], + [AC_MSG_WARN([zmq.h not found, disabling zmq support]) + use_zmq=no + AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions])]) + AC_CHECK_LIB([zmq],[zmq_ctx_shutdown],ZMQ_LIBS=-lzmq, + [AC_MSG_WARN([libzmq >= 4.0 not found, disabling zmq support]) + use_zmq=no + AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions])]) + else + AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) + fi + BITCOIN_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],[PROTOBUF_LIBS=-lprotobuf], BITCOIN_QT_FAIL(libprotobuf not found))) if test x$use_qr != xno; then BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],[QR_LIBS=-lqrencode], [have_qrencode=no])]) @@ -863,20 +887,6 @@ if test x$bitcoin_enable_qt != xno; then fi fi -# conditional search for and use libzmq -AC_MSG_CHECKING([whether to build ZMQ support]) -if test "x$use_zmq" = "xyes"; then - AC_MSG_RESULT([yes]) - PKG_CHECK_MODULES([ZMQ],[libzmq >= 4], - [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], - [AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) - AC_MSG_WARN([libzmq version 4.x or greater not found, disabling]) - use_zmq=no]) -else - AC_MSG_RESULT([no, --disable-zmq used]) - AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) -fi - AM_CONDITIONAL([ENABLE_ZMQ], [test "x$use_zmq" = "xyes"]) AC_MSG_CHECKING([whether to build test_bitcoin]) From d5f4dc15a9144d38d2fd2d5d94ad54ab653f41c9 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Mon, 5 Oct 2015 20:09:04 -0700 Subject: [PATCH 13/35] zmq: update docs to reflect feature is compiled in automatically if possible Signed-off-by: Johnathan Corgan --- doc/zmq.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/zmq.md b/doc/zmq.md index 358d29d0..484b005c 100644 --- a/doc/zmq.md +++ b/doc/zmq.md @@ -43,14 +43,14 @@ operation. ## Enabling -By default, the ZeroMQ port functionality is enabled. Two steps are -required to enable--compiling in the ZeroMQ code, and configuring -runtime operation on the command-line or configuration file. +By default, the ZeroMQ feature is automatically compiled in if the +necessary prerequisites are found. To disable, use --disable-zmq +during the *configure* step of building bitcoind: - $ ./configure --enable-zmq (other options) + $ ./configure --disable-zmq (other options) -This will produce a binary that is capable of providing the ZeroMQ -facility, but will not do so until also configured properly. +To actually enable operation, one must set the appropriate options on +the commandline or in the configuration file. ## Usage From 007148fafa213846243291f7be4cb551db35f342 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 8 Oct 2015 00:00:03 -0400 Subject: [PATCH 14/35] build: Make use of ZMQ_CFLAGS --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 54743878..ff3d51ef 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -240,7 +240,7 @@ libbitcoin_server_a_SOURCES = \ if ENABLE_ZMQ LIBBITCOIN_ZMQ=libbitcoin_zmq.a -libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) +libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS) libbitcoin_zmq_a_SOURCES = \ zmq/zmqabstractnotifier.cpp \ zmq/zmqnotificationinterface.cpp \ From 678b614ab50d8b3c46ff97f3eaa882e9bc0b563a Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Mon, 12 Oct 2015 13:39:47 -0700 Subject: [PATCH 15/35] zmq: point API link to 4.0 as that is what we are conforming to [Trivial] Signed-off-by: Johnathan Corgan --- doc/zmq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/zmq.md b/doc/zmq.md index 484b005c..53e557e3 100644 --- a/doc/zmq.md +++ b/doc/zmq.md @@ -78,7 +78,7 @@ bytes). These options can also be provided in bitcoin.conf. ZeroMQ endpoint specifiers for TCP (and others) are documented in the -[ZeroMQ API](http://api.zeromq.org). +[ZeroMQ API](http://api.zeromq.org/4-0:_start). Client side, then, the ZeroMQ subscriber socket must have the ZMQ_SUBSCRIBE option set to one or either of these prefixes (for From 5015d2b27f50ff5fb4de01f76af5ded75f4dd65e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Sun, 1 Nov 2015 18:09:17 +0000 Subject: [PATCH 16/35] Fix ZMQ Notification initialization and shutdown Moves the call Initialize() from init.cpp to CreateWithArguments() and handles the return value. Moves the call Shutdown() from init.cpp to destructor. Changes Initialize() and Shutdown() to protected members. --- src/init.cpp | 2 -- src/zmq/zmqnotificationinterface.cpp | 11 ++++++++--- src/zmq/zmqnotificationinterface.h | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 3fc30a28..700f20b9 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -208,7 +208,6 @@ void Shutdown() #if ENABLE_ZMQ if (pzmqNotificationInterface) { UnregisterValidationInterface(pzmqNotificationInterface); - pzmqNotificationInterface->Shutdown(); delete pzmqNotificationInterface; pzmqNotificationInterface = NULL; } @@ -1170,7 +1169,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs); if (pzmqNotificationInterface) { - pzmqNotificationInterface->Initialize(); RegisterValidationInterface(pzmqNotificationInterface); } #endif diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index 71ccb59a..8b5d5947 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -21,8 +21,7 @@ CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(NULL) CZMQNotificationInterface::~CZMQNotificationInterface() { - // ensure Shutdown if Initialize is called - assert(!pcontext); + Shutdown(); for (std::list::iterator i=notifiers.begin(); i!=notifiers.end(); ++i) { @@ -59,6 +58,12 @@ CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const { notificationInterface = new CZMQNotificationInterface(); notificationInterface->notifiers = notifiers; + + if (!notificationInterface->Initialize()) + { + delete notificationInterface; + notificationInterface = NULL; + } } return notificationInterface; @@ -99,7 +104,7 @@ bool CZMQNotificationInterface::Initialize() return false; } - return false; + return true; } // Called during shutdown sequence diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h index afc0b8d2..fcf6333a 100644 --- a/src/zmq/zmqnotificationinterface.h +++ b/src/zmq/zmqnotificationinterface.h @@ -18,10 +18,11 @@ public: static CZMQNotificationInterface* CreateWithArguments(const std::map &args); +protected: bool Initialize(); void Shutdown(); -protected: // CValidationInterface + // CValidationInterface void SyncTransaction(const CTransaction &tx, const CBlock *pblock); void UpdatedBlockTip(const uint256 &newHashTip); From 6702d371c548c5b314948cc31690c8c04ba2d083 Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 11 Nov 2015 17:53:34 +0800 Subject: [PATCH 17/35] [depends] zeromq 4.0.7 --- depends/packages/zeromq.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 24e8e5f1..7b866e9c 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -1,8 +1,8 @@ package=zeromq -$(package)_version=4.0.4 +$(package)_version=4.0.7 $(package)_download_path=http://download.zeromq.org $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=1ef71d46e94f33e27dd5a1661ed626cd39be4d2d6967792a275040e34457d399 +$(package)_sha256_hash=e00b2967e074990d0538361cc79084a0a92892df2c6e7585da34e4c61ee47b03 define $(package)_set_vars $(package)_config_opts=--without-documentation --disable-shared From 6a793d9c2744c279547a1be8d6423204edf1c775 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 16 Sep 2015 16:42:23 +0200 Subject: [PATCH 18/35] use CBlockIndex* insted of uint256 for UpdatedBlockTip signal - removes mapBlockIndex find operation - theoretically allows removing the cs_main lock during zqm notification while introducing a new file position lock --- src/main.cpp | 2 +- src/validationinterface.h | 4 ++-- src/zmq/zmqabstractnotifier.cpp | 2 +- src/zmq/zmqabstractnotifier.h | 4 +++- src/zmq/zmqnotificationinterface.cpp | 4 ++-- src/zmq/zmqnotificationinterface.h | 3 ++- src/zmq/zmqpublishnotifier.cpp | 12 +++++------- src/zmq/zmqpublishnotifier.h | 6 ++++-- 8 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 70be4445..74344696 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2707,7 +2707,7 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) { pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip)); } // Notify external listeners about the new tip. - GetMainSignals().UpdatedBlockTip(hashNewTip); + GetMainSignals().UpdatedBlockTip(pindexNewTip); uiInterface.NotifyBlockTip(hashNewTip); } } while(pindexMostWork != chainActive.Tip()); diff --git a/src/validationinterface.h b/src/validationinterface.h index 70489cb3..1855dacd 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -31,7 +31,7 @@ void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL); class CValidationInterface { protected: - virtual void UpdatedBlockTip(const uint256 &newHashTip) {} + virtual void UpdatedBlockTip(const CBlockIndex *pindex) {} virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {} virtual void EraseFromWallet(const uint256 &hash) {} virtual void ChainTip(const CBlockIndex *pindex, const CBlock *pblock, ZCIncrementalMerkleTree tree, bool added) {} @@ -47,7 +47,7 @@ protected: struct CMainSignals { /** Notifies listeners of updated block chain tip */ - boost::signals2::signal UpdatedBlockTip; + boost::signals2::signal UpdatedBlockTip; /** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */ boost::signals2::signal SyncTransaction; /** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */ diff --git a/src/zmq/zmqabstractnotifier.cpp b/src/zmq/zmqabstractnotifier.cpp index 744ec592..9f5cb3ba 100644 --- a/src/zmq/zmqabstractnotifier.cpp +++ b/src/zmq/zmqabstractnotifier.cpp @@ -11,7 +11,7 @@ CZMQAbstractNotifier::~CZMQAbstractNotifier() assert(!psocket); } -bool CZMQAbstractNotifier::NotifyBlock(const uint256 &/*hash*/) +bool CZMQAbstractNotifier::NotifyBlock(const CBlockIndex * /*CBlockIndex*/) { return true; } diff --git a/src/zmq/zmqabstractnotifier.h b/src/zmq/zmqabstractnotifier.h index 626d1ddf..77cf5141 100644 --- a/src/zmq/zmqabstractnotifier.h +++ b/src/zmq/zmqabstractnotifier.h @@ -7,7 +7,9 @@ #include "zmqconfig.h" +class CBlockIndex; class CZMQAbstractNotifier; + typedef CZMQAbstractNotifier* (*CZMQNotifierFactory)(); class CZMQAbstractNotifier @@ -30,7 +32,7 @@ public: virtual bool Initialize(void *pcontext) = 0; virtual void Shutdown() = 0; - virtual bool NotifyBlock(const uint256 &hash); + virtual bool NotifyBlock(const CBlockIndex *pindex); virtual bool NotifyTransaction(const CTransaction &transaction); protected: diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index 8b5d5947..09fe3aeb 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -125,12 +125,12 @@ void CZMQNotificationInterface::Shutdown() } } -void CZMQNotificationInterface::UpdatedBlockTip(const uint256 &hash) +void CZMQNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindex) { for (std::list::iterator i = notifiers.begin(); i!=notifiers.end(); ) { CZMQAbstractNotifier *notifier = *i; - if (notifier->NotifyBlock(hash)) + if (notifier->NotifyBlock(pindex)) { i++; } diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h index fcf6333a..3ccfaf34 100644 --- a/src/zmq/zmqnotificationinterface.h +++ b/src/zmq/zmqnotificationinterface.h @@ -9,6 +9,7 @@ #include #include +class CBlockIndex; class CZMQAbstractNotifier; class CZMQNotificationInterface : public CValidationInterface @@ -24,7 +25,7 @@ protected: // CValidationInterface void SyncTransaction(const CTransaction &tx, const CBlock *pblock); - void UpdatedBlockTip(const uint256 &newHashTip); + void UpdatedBlockTip(const CBlockIndex *pindex); private: CZMQNotificationInterface(); diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 0a6d7d0d..4c3eb8f2 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -116,8 +116,9 @@ void CZMQAbstractPublishNotifier::Shutdown() psocket = 0; } -bool CZMQPublishHashBlockNotifier::NotifyBlock(const uint256 &hash) +bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) { + uint256 hash = pindex->GetBlockHash(); LogPrint("zmq", "Publish hash block %s\n", hash.GetHex()); char data[32]; for (unsigned int i = 0; i < 32; i++) @@ -137,18 +138,15 @@ bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &t return rc == 0; } -bool CZMQPublishRawBlockNotifier::NotifyBlock(const uint256 &hash) +bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) { - LogPrint("zmq", "Publish raw block %s\n", hash.GetHex()); + LogPrint("zmq", "Publish raw block %s\n", pindex->GetBlockHash().GetHex()); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); { LOCK(cs_main); - CBlock block; - CBlockIndex* pblockindex = mapBlockIndex[hash]; - - if(!ReadBlockFromDisk(block, pblockindex)) + if(!ReadBlockFromDisk(block, pindex)) { zmqError("Can't read block from disk"); return false; diff --git a/src/zmq/zmqpublishnotifier.h b/src/zmq/zmqpublishnotifier.h index a0eb26f5..44d5cbea 100644 --- a/src/zmq/zmqpublishnotifier.h +++ b/src/zmq/zmqpublishnotifier.h @@ -7,6 +7,8 @@ #include "zmqabstractnotifier.h" +class CBlockIndex; + class CZMQAbstractPublishNotifier : public CZMQAbstractNotifier { public: @@ -17,7 +19,7 @@ public: class CZMQPublishHashBlockNotifier : public CZMQAbstractPublishNotifier { public: - bool NotifyBlock(const uint256 &hash); + bool NotifyBlock(const CBlockIndex *pindex); }; class CZMQPublishHashTransactionNotifier : public CZMQAbstractPublishNotifier @@ -29,7 +31,7 @@ public: class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier { public: - bool NotifyBlock(const uint256 &hash); + bool NotifyBlock(const CBlockIndex *pindex); }; class CZMQPublishRawTransactionNotifier : public CZMQAbstractPublishNotifier From 57c6ef01d99b8ade03b4c3956b9fcc74d2c14ea6 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Thu, 19 Nov 2015 12:34:19 +1100 Subject: [PATCH 19/35] init: amend ZMQ flag names --- src/init.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 700f20b9..a52603f6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -384,9 +384,9 @@ std::string HelpMessage(HelpMessageMode mode) #if ENABLE_ZMQ strUsage += HelpMessageGroup(_("ZeroMQ notification options:")); strUsage += HelpMessageOpt("-zmqpubhashblock=
", _("Enable publish hash block in
")); - strUsage += HelpMessageOpt("-zmqpubhashtransaction=
", _("Enable publish hash transaction in
")); + strUsage += HelpMessageOpt("-zmqpubhashtx=
", _("Enable publish hash transaction in
")); strUsage += HelpMessageOpt("-zmqpubrawblock=
", _("Enable publish raw block in
")); - strUsage += HelpMessageOpt("-zmqpubrawtransaction=
", _("Enable publish raw transaction in
")); + strUsage += HelpMessageOpt("-zmqpubrawtx=
", _("Enable publish raw transaction in
")); #endif strUsage += HelpMessageGroup(_("Debugging/Testing options:")); From 6550e97224f2ac1e22396c6440c5ab78fb9f8adb Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Thu, 19 Nov 2015 13:17:36 +1100 Subject: [PATCH 20/35] init: add zmq to debug categories --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index a52603f6..0ee047e5 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -402,7 +402,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0)); } string debugCategories = "addrman, alert, bench, coindb, db, estimatefee, lock, mempool, net, partitioncheck, pow, proxy, prune, " - "rand, reindex, rpc, selectcoins, zrpc, zrpcunsafe (implies zrpc)"; // Don't translate these and qt below + "rand, reindex, rpc, selectcoins, zmq, zrpc, zrpcunsafe (implies zrpc)"; // Don't translate these and qt below if (mode == HMM_BITCOIN_QT) debugCategories += ", qt"; strUsage += HelpMessageOpt("-debug=", strprintf(_("Output debugging information (default: %u, supplying is optional)"), 0) + ". " + From 63303d025dec4af812274d3342d3ff781b30fc92 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Thu, 19 Nov 2015 13:27:18 +1100 Subject: [PATCH 21/35] zmq: prepend zmq to debug messages --- src/zmq/zmqnotificationinterface.cpp | 6 +++--- src/zmq/zmqpublishnotifier.cpp | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index 09fe3aeb..be2aec7d 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -12,7 +12,7 @@ void zmqError(const char *str) { - LogPrint("zmq", "Error: %s, errno=%s\n", str, zmq_strerror(errno)); + LogPrint("zmq", "zmq: Error: %s, errno=%s\n", str, zmq_strerror(errno)); } CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(NULL) @@ -72,7 +72,7 @@ CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const // Called at startup to conditionally set up ZMQ socket(s) bool CZMQNotificationInterface::Initialize() { - LogPrint("zmq", "Initialize notification interface\n"); + LogPrint("zmq", "zmq: Initialize notification interface\n"); assert(!pcontext); pcontext = zmq_init(1); @@ -110,7 +110,7 @@ bool CZMQNotificationInterface::Initialize() // Called during shutdown sequence void CZMQNotificationInterface::Shutdown() { - LogPrint("zmq", "Shutdown notification interface\n"); + LogPrint("zmq", "zmq: Shutdown notification interface\n"); if (pcontext) { for (std::list::iterator i=notifiers.begin(); i!=notifiers.end(); ++i) diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 4c3eb8f2..81f6e808 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -77,7 +77,7 @@ bool CZMQAbstractPublishNotifier::Initialize(void *pcontext) } else { - LogPrint("zmq", " Reuse socket for address %s\n", address); + LogPrint("zmq", "zmq: Reusing socket for address %s\n", address); psocket = i->second->psocket; mapPublishNotifiers.insert(std::make_pair(address, this)); @@ -119,7 +119,7 @@ void CZMQAbstractPublishNotifier::Shutdown() bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) { uint256 hash = pindex->GetBlockHash(); - LogPrint("zmq", "Publish hash block %s\n", hash.GetHex()); + LogPrint("zmq", "zmq: Publish hashblock %s\n", hash.GetHex()); char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; @@ -130,7 +130,7 @@ bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction) { uint256 hash = transaction.GetHash(); - LogPrint("zmq", "Publish hash transaction %s\n", hash.GetHex()); + LogPrint("zmq", "zmq: Publish hashtx %s\n", hash.GetHex()); char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; @@ -140,7 +140,7 @@ bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &t bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) { - LogPrint("zmq", "Publish raw block %s\n", pindex->GetBlockHash().GetHex()); + LogPrint("zmq", "zmq: Publish rawblock %s\n", pindex->GetBlockHash().GetHex()); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); { @@ -162,7 +162,7 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction) { uint256 hash = transaction.GetHash(); - LogPrint("zmq", "Publish raw transaction %s\n", hash.GetHex()); + LogPrint("zmq", "zmq: Publish rawtx %s\n", hash.GetHex()); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << transaction; int rc = zmq_send_multipart(psocket, "rawtx", 5, &(*ss.begin()), ss.size(), 0); From d4cca6a3208ddc6268de08ea24bdcdb25bc6e4e3 Mon Sep 17 00:00:00 2001 From: mrbandrews Date: Mon, 29 Feb 2016 13:34:09 -0500 Subject: [PATCH 22/35] Fixes ZMQ startup with bad arguments. --- src/zmq/zmqnotificationinterface.cpp | 1 - src/zmq/zmqpublishnotifier.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index be2aec7d..4df7550d 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -100,7 +100,6 @@ bool CZMQNotificationInterface::Initialize() if (i!=notifiers.end()) { - Shutdown(); return false; } diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 81f6e808..338c0dc9 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -68,6 +68,7 @@ bool CZMQAbstractPublishNotifier::Initialize(void *pcontext) if (rc!=0) { zmqError("Failed to bind address"); + zmq_close(psocket); return false; } From a9445db62f6825ff30d22f2752eeaf95da699c99 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 31 Jan 2017 14:10:25 +0100 Subject: [PATCH 23/35] Fix python syntax in ZMQ RPC test Extracted from bitcoin/bitcoin#7335 commit 7777994846cdb9b9cf69e391a33eeed30393bbcf --- qa/rpc-tests/zmq_test.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py index bcb13232..88532541 100755 --- a/qa/rpc-tests/zmq_test.py +++ b/qa/rpc-tests/zmq_test.py @@ -11,7 +11,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * import zmq import binascii -from test_framework.mininode import hash256 try: import http.client as httplib @@ -42,7 +41,7 @@ class ZMQTest (BitcoinTestFramework): def run_test(self): self.sync_all() - genhashes = self.nodes[0].generate(1); + genhashes = self.nodes[0].generate(1) self.sync_all() print "listen..." @@ -58,7 +57,7 @@ class ZMQTest (BitcoinTestFramework): assert_equal(genhashes[0], blkhash) #blockhash from generate must be equal to the hash received over zmq n = 10 - genhashes = self.nodes[1].generate(n); + genhashes = self.nodes[1].generate(n) self.sync_all() zmqHashes = [] @@ -76,7 +75,7 @@ class ZMQTest (BitcoinTestFramework): hashRPC = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.0) self.sync_all() - #now we should receive a zmq msg because the tx was broadcastet + # now we should receive a zmq msg because the tx was broadcast msg = self.zmqSubSocket.recv_multipart() topic = str(msg[0]) body = msg[1] From c7cb3c13ea3bcbc6bc7054e16bd77c51b85e3eaf Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 31 Jan 2017 14:12:19 +0100 Subject: [PATCH 24/35] [qa] py2: Unfiddle strings into bytes explicitly in ZMQ RPC test Extracted from bitcoin/bitcoin#7853 commit faa41ee204124da19dcf1e5b8a3aef1e216bf5e6 --- qa/rpc-tests/test_framework/util.py | 13 +++++++++++++ qa/rpc-tests/zmq_test.py | 22 +++++++++++----------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index bfb9bddf..5d03403e 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -1,6 +1,8 @@ # Copyright (c) 2014 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. + + # # Helpful routines for regression testing # @@ -9,6 +11,8 @@ import os import sys +from binascii import hexlify, unhexlify +from base64 import b64encode from decimal import Decimal, ROUND_DOWN import json import random @@ -32,6 +36,15 @@ def check_json_precision(): if satoshis != 2000000000000003: raise RuntimeError("JSON encode/decode loses precision") +def bytes_to_hex_str(byte_str): + return hexlify(byte_str).decode('ascii') + +def hex_str_to_bytes(hex_str): + return unhexlify(hex_str.encode('ascii')) + +def str_to_b64str(string): + return b64encode(string.encode('utf-8')).decode('ascii') + def sync_blocks(rpc_connections, wait=1): """ Wait until everybody has the same block count diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py index 88532541..3a8d62ef 100755 --- a/qa/rpc-tests/zmq_test.py +++ b/qa/rpc-tests/zmq_test.py @@ -28,8 +28,8 @@ class ZMQTest (BitcoinTestFramework): def setup_nodes(self): self.zmqContext = zmq.Context() self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) - self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashblock") - self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashtx") + self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashblock") + self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashtx") self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % self.port) return start_nodes(4, self.options.tmpdir, extra_args=[ ['-zmqpubhashtx=tcp://127.0.0.1:'+str(self.port), '-zmqpubhashblock=tcp://127.0.0.1:'+str(self.port)], @@ -46,13 +46,13 @@ class ZMQTest (BitcoinTestFramework): print "listen..." msg = self.zmqSubSocket.recv_multipart() - topic = str(msg[0]) + topic = msg[0] body = msg[1] msg = self.zmqSubSocket.recv_multipart() - topic = str(msg[0]) + topic = msg[0] body = msg[1] - blkhash = binascii.hexlify(body) + blkhash = bytes_to_hex_str(body) assert_equal(genhashes[0], blkhash) #blockhash from generate must be equal to the hash received over zmq @@ -63,10 +63,10 @@ class ZMQTest (BitcoinTestFramework): zmqHashes = [] for x in range(0,n*2): msg = self.zmqSubSocket.recv_multipart() - topic = str(msg[0]) + topic = msg[0] body = msg[1] - if topic == "hashblock": - zmqHashes.append(binascii.hexlify(body)) + if topic == b"hashblock": + zmqHashes.append(bytes_to_hex_str(body)) for x in range(0,n): assert_equal(genhashes[x], zmqHashes[x]) #blockhash from generate must be equal to the hash received over zmq @@ -77,11 +77,11 @@ class ZMQTest (BitcoinTestFramework): # now we should receive a zmq msg because the tx was broadcast msg = self.zmqSubSocket.recv_multipart() - topic = str(msg[0]) + topic = msg[0] body = msg[1] hashZMQ = "" - if topic == "hashtx": - hashZMQ = binascii.hexlify(body) + if topic == b"hashtx": + hashZMQ = bytes_to_hex_str(body) assert_equal(hashRPC, hashZMQ) #blockhash from generate must be equal to the hash received over zmq From abf8020443f597cbe6bf896b0571e0601543654a Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 29 Mar 2016 11:34:25 +0200 Subject: [PATCH 25/35] [ZMQ] refactor message string --- src/zmq/zmqpublishnotifier.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 338c0dc9..70767289 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -8,6 +8,11 @@ static std::multimap mapPublishNotifiers; +static const char *MSG_HASHBLOCK = "hashblock"; +static const char *MSG_HASHTX = "hashtx"; +static const char *MSG_RAWBLOCK = "rawblock"; +static const char *MSG_RAWTX = "rawtx"; + // Internal function to send multipart message static int zmq_send_multipart(void *sock, const void* data, size_t size, ...) { @@ -124,7 +129,7 @@ bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; - int rc = zmq_send_multipart(psocket, "hashblock", 9, data, 32, 0); + int rc = zmq_send_multipart(psocket, MSG_HASHBLOCK, 9, data, 32, 0); return rc == 0; } @@ -135,7 +140,7 @@ bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &t char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; - int rc = zmq_send_multipart(psocket, "hashtx", 6, data, 32, 0); + int rc = zmq_send_multipart(psocket, MSG_HASHTX, 6, data, 32, 0); return rc == 0; } @@ -156,7 +161,7 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) ss << block; } - int rc = zmq_send_multipart(psocket, "rawblock", 8, &(*ss.begin()), ss.size(), 0); + int rc = zmq_send_multipart(psocket, MSG_RAWBLOCK, 8, &(*ss.begin()), ss.size(), 0); return rc == 0; } @@ -166,6 +171,6 @@ bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &tr LogPrint("zmq", "zmq: Publish rawtx %s\n", hash.GetHex()); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << transaction; - int rc = zmq_send_multipart(psocket, "rawtx", 5, &(*ss.begin()), ss.size(), 0); + int rc = zmq_send_multipart(psocket, MSG_RAWTX, 5, &(*ss.begin()), ss.size(), 0); return rc == 0; } From 3ba2e19e2b3eb094e162c59f2e7b3428d1e44524 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 29 Mar 2016 14:30:02 +0200 Subject: [PATCH 26/35] [ZMQ] append a message sequence number to every ZMQ notification --- contrib/zmq/zmq_sub.py | 14 +++++++++----- doc/zmq.md | 5 +++++ qa/rpc-tests/zmq_test.py | 13 +++++++++++++ src/zmq/zmqpublishnotifier.cpp | 29 +++++++++++++++++++++-------- src/zmq/zmqpublishnotifier.h | 12 ++++++++++++ 5 files changed, 60 insertions(+), 13 deletions(-) diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py index decf29d4..6268123d 100755 --- a/contrib/zmq/zmq_sub.py +++ b/contrib/zmq/zmq_sub.py @@ -3,6 +3,7 @@ import array import binascii import zmq +import struct port = 28332 @@ -19,18 +20,21 @@ try: msg = zmqSubSocket.recv_multipart() topic = str(msg[0]) body = msg[1] - + sequence = "Unknown"; + if len(msg[-1]) == 4: + msgSequence = struct.unpack('GetBlockHash(); @@ -129,8 +146,7 @@ bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; - int rc = zmq_send_multipart(psocket, MSG_HASHBLOCK, 9, data, 32, 0); - return rc == 0; + return SendMessage(MSG_HASHBLOCK, data, 32); } bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction) @@ -140,8 +156,7 @@ bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &t char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; - int rc = zmq_send_multipart(psocket, MSG_HASHTX, 6, data, 32, 0); - return rc == 0; + return SendMessage(MSG_HASHTX, data, 32); } bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) @@ -161,8 +176,7 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) ss << block; } - int rc = zmq_send_multipart(psocket, MSG_RAWBLOCK, 8, &(*ss.begin()), ss.size(), 0); - return rc == 0; + return SendMessage(MSG_RAWBLOCK, &(*ss.begin()), ss.size()); } bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction) @@ -171,6 +185,5 @@ bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &tr LogPrint("zmq", "zmq: Publish rawtx %s\n", hash.GetHex()); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << transaction; - int rc = zmq_send_multipart(psocket, MSG_RAWTX, 5, &(*ss.begin()), ss.size(), 0); - return rc == 0; + return SendMessage(MSG_RAWTX, &(*ss.begin()), ss.size()); } diff --git a/src/zmq/zmqpublishnotifier.h b/src/zmq/zmqpublishnotifier.h index 44d5cbea..22f02a3d 100644 --- a/src/zmq/zmqpublishnotifier.h +++ b/src/zmq/zmqpublishnotifier.h @@ -11,7 +11,19 @@ class CBlockIndex; class CZMQAbstractPublishNotifier : public CZMQAbstractNotifier { +private: + uint32_t nSequence; //! upcounting per message sequence number + public: + + /* send zmq multipart message + parts: + * command + * data + * message sequence number + */ + bool SendMessage(const char *command, const void* data, size_t size); + bool Initialize(void *pcontext); void Shutdown(); }; From c3c55e10e8496f7b9552ec36f62e6152b408514f Mon Sep 17 00:00:00 2001 From: fanquake Date: Tue, 3 May 2016 20:52:10 +0800 Subject: [PATCH 27/35] [depends] ZeroMQ 4.1.4 --- depends/packages/zeromq.mk | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 7b866e9c..5c66b175 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -1,11 +1,11 @@ package=zeromq -$(package)_version=4.0.7 +$(package)_version=4.1.4 $(package)_download_path=http://download.zeromq.org $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=e00b2967e074990d0538361cc79084a0a92892df2c6e7585da34e4c61ee47b03 +$(package)_sha256_hash=e99f44fde25c2e4cb84ce440f87ca7d3fe3271c2b8cfbc67d55e4de25e6fe378 define $(package)_set_vars - $(package)_config_opts=--without-documentation --disable-shared + $(package)_config_opts=--without-documentation --disable-shared --without-libsodium $(package)_config_opts_linux=--with-pic endef @@ -14,11 +14,11 @@ define $(package)_config_cmds endef define $(package)_build_cmds - $(MAKE) -C src + $(MAKE) libzmq.la endef define $(package)_stage_cmds - $(MAKE) -C src DESTDIR=$($(package)_staging_dir) install + $(MAKE) DESTDIR=$($(package)_staging_dir) install-libLTLIBRARIES install-includeHEADERS install-pkgconfigDATA endef define $(package)_postprocess_cmds From 00bcf2230dcc2e0c7ca66a951270795e4fe474aa Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 22 Jun 2016 17:56:07 +0800 Subject: [PATCH 28/35] [depends] ZeroMQ 4.1.5 --- configure.ac | 9 ++++++++ depends/packages/packages.mk | 4 +--- depends/packages/zeromq.mk | 15 +++++++++---- ...d3957725acd34aa8b8d011585812f3369411.patch | 22 +++++++++++++++++++ ...45c12e0b100cd38acecc16ce7db02905e27c.patch | 22 +++++++++++++++++++ 5 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 depends/patches/zeromq/9114d3957725acd34aa8b8d011585812f3369411.patch create mode 100644 depends/patches/zeromq/9e6745c12e0b100cd38acecc16ce7db02905e27c.patch diff --git a/configure.ac b/configure.ac index 68de3800..1b24b1ff 100644 --- a/configure.ac +++ b/configure.ac @@ -729,6 +729,15 @@ else AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) fi + if test "x$use_zmq" = "xyes"; then + dnl Assume libzmq was built for static linking + case $host in + *mingw*) + ZMQ_CFLAGS="$ZMQ_CFLAGS -DZMQ_STATIC" + ;; + esac + fi + BITCOIN_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],[PROTOBUF_LIBS=-lprotobuf], BITCOIN_QT_FAIL(libprotobuf not found))) if test x$use_qr != xno; then BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],[QR_LIBS=-lqrencode], [have_qrencode=no])]) diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 034f951e..28c7afb2 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,7 +1,5 @@ zcash_packages := libsnark libgmp libsodium -packages := boost openssl $(zcash_packages) googletest googlemock -darwin_packages:=zeromq -linux_packages:=zeromq +packages := boost openssl zeromq $(zcash_packages) googletest googlemock native_packages := native_ccache wallet_packages=bdb diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 5c66b175..30bb3b45 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -1,14 +1,21 @@ package=zeromq -$(package)_version=4.1.4 -$(package)_download_path=http://download.zeromq.org +$(package)_version=4.1.5 +$(package)_download_path=https://github.com/zeromq/zeromq4-1/releases/download/v$($(package)_version)/ $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=e99f44fde25c2e4cb84ce440f87ca7d3fe3271c2b8cfbc67d55e4de25e6fe378 +$(package)_sha256_hash=04aac57f081ffa3a2ee5ed04887be9e205df3a7ddade0027460b8042432bdbcf +$(package)_patches=9114d3957725acd34aa8b8d011585812f3369411.patch 9e6745c12e0b100cd38acecc16ce7db02905e27c.patch define $(package)_set_vars - $(package)_config_opts=--without-documentation --disable-shared --without-libsodium + $(package)_config_opts=--without-documentation --disable-shared --without-libsodium --disable-curve $(package)_config_opts_linux=--with-pic endef +define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/9114d3957725acd34aa8b8d011585812f3369411.patch && \ + patch -p1 < $($(package)_patch_dir)/9e6745c12e0b100cd38acecc16ce7db02905e27c.patch && \ + ./autogen.sh +endef + define $(package)_config_cmds $($(package)_autoconf) endef diff --git a/depends/patches/zeromq/9114d3957725acd34aa8b8d011585812f3369411.patch b/depends/patches/zeromq/9114d3957725acd34aa8b8d011585812f3369411.patch new file mode 100644 index 00000000..f704b3d9 --- /dev/null +++ b/depends/patches/zeromq/9114d3957725acd34aa8b8d011585812f3369411.patch @@ -0,0 +1,22 @@ +From 9114d3957725acd34aa8b8d011585812f3369411 Mon Sep 17 00:00:00 2001 +From: Jeroen Ooms +Date: Tue, 20 Oct 2015 13:10:38 +0200 +Subject: [PATCH] enable static libraries on mingw + +--- + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index 393505b..e92131a 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -265,7 +265,7 @@ case "${host_os}" in + libzmq_dso_visibility="no" + + if test "x$enable_static" = "xyes"; then +- AC_MSG_ERROR([Building static libraries is not supported under MinGW32]) ++ CPPFLAGS="-DZMQ_STATIC" + fi + + # Set FD_SETSIZE to 1024 \ No newline at end of file diff --git a/depends/patches/zeromq/9e6745c12e0b100cd38acecc16ce7db02905e27c.patch b/depends/patches/zeromq/9e6745c12e0b100cd38acecc16ce7db02905e27c.patch new file mode 100644 index 00000000..9aff2c17 --- /dev/null +++ b/depends/patches/zeromq/9e6745c12e0b100cd38acecc16ce7db02905e27c.patch @@ -0,0 +1,22 @@ +From 9e6745c12e0b100cd38acecc16ce7db02905e27c Mon Sep 17 00:00:00 2001 +From: David Millard +Date: Tue, 10 May 2016 13:53:53 -0700 +Subject: [PATCH] Fix autotools for static MinGW builds + +--- + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index 5a0fa14..def6ea7 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -259,7 +259,7 @@ case "${host_os}" in + libzmq_dso_visibility="no" + + if test "x$enable_static" = "xyes"; then +- CPPFLAGS="-DZMQ_STATIC" ++ CPPFLAGS="-DZMQ_STATIC $CPPFLAGS" + fi + + # Set FD_SETSIZE to 1024 \ No newline at end of file From 5dfea488e4c672f05971eff6da1bfce863f83b6c Mon Sep 17 00:00:00 2001 From: isle2983 Date: Sun, 11 Sep 2016 15:26:53 -0600 Subject: [PATCH 29/35] [copyright] add MIT License copyright header to zmq_sub.py --- contrib/zmq/zmq_sub.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py index 6268123d..3dea5e3c 100755 --- a/contrib/zmq/zmq_sub.py +++ b/contrib/zmq/zmq_sub.py @@ -1,4 +1,7 @@ #!/usr/bin/env python2 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. import array import binascii From 4fbc46c2ff557ee03d47a2b857d83cfd087c41c6 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 31 Jan 2017 14:48:34 +0100 Subject: [PATCH 30/35] Bitcoin -> Zcash in ZMQ docs --- doc/zmq.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/zmq.md b/doc/zmq.md index 1e115534..7601ebac 100644 --- a/doc/zmq.md +++ b/doc/zmq.md @@ -5,8 +5,8 @@ connections, inter-process communication, and shared-memory, providing various message-oriented semantics such as publish/subcribe, request/reply, and push/pull. -The Bitcoin Core daemon can be configured to act as a trusted "border -router", implementing the bitcoin wire protocol and relay, making +The Zcash daemon can be configured to act as a trusted "border +router", implementing the zcash wire protocol and relay, making consensus decisions, maintaining the local blockchain database, broadcasting locally generated transactions into the network, and providing a queryable RPC interface to interact on a polled basis for @@ -33,7 +33,7 @@ buffering or reassembly. ## Prerequisites -The ZeroMQ feature in Bitcoin Core requires ZeroMQ API version 4.x or +The ZeroMQ feature in Zcash requires ZeroMQ API version 4.x or newer. Typically, it is packaged by distributions as something like *libzmq3-dev*. The C++ wrapper for ZeroMQ is *not* needed. @@ -45,7 +45,7 @@ operation. By default, the ZeroMQ feature is automatically compiled in if the necessary prerequisites are found. To disable, use --disable-zmq -during the *configure* step of building bitcoind: +during the *configure* step of building zcashd: $ ./configure --disable-zmq (other options) @@ -66,8 +66,8 @@ address. The same address can be used in more than one notification. For instance: - $ bitcoind -zmqpubhashtx=tcp://127.0.0.1:28332 \ - -zmqpubrawtx=ipc:///tmp/bitcoind.tx.raw + $ zcashd -zmqpubhashtx=tcp://127.0.0.1:28332 \ + -zmqpubrawtx=ipc:///tmp/zcashd.tx.raw Each PUB notification has a topic and body, where the header corresponds to the notification type. For instance, for the @@ -75,7 +75,7 @@ notification `-zmqpubhashtx` the topic is `hashtx` (no null terminator) and the body is the hexadecimal transaction hash (32 bytes). -These options can also be provided in bitcoin.conf. +These options can also be provided in zcash.conf. ZeroMQ endpoint specifiers for TCP (and others) are documented in the [ZeroMQ API](http://api.zeromq.org/4-0:_start). @@ -87,9 +87,9 @@ arriving. Please see `contrib/zmq/zmq_sub.py` for a working example. ## Remarks -From the perspective of bitcoind, the ZeroMQ socket is write-only; PUB +From the perspective of zcashd, the ZeroMQ socket is write-only; PUB sockets don't even have a read function. Thus, there is no state -introduced into bitcoind directly. Furthermore, no information is +introduced into zcashd directly. Furthermore, no information is broadcast that wasn't already received from the public P2P network. No authentication or authorization is done on connecting clients; it @@ -102,5 +102,5 @@ retrieve the chain from the last known block to the new tip. There are several possibilities that ZMQ notification can get lost during transmission depending on the communication type your are -using. Bitcoind appends an up-counting sequence number to each +using. Zcashd appends an up-counting sequence number to each notification which allows listeners to detect lost notifications. From 05e6ead8da45e61b08807c51762ed0422c99239f Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Mon, 6 Feb 2017 13:15:22 +0000 Subject: [PATCH 31/35] Add ZeroMQ license to contrib/debian/copyright --- contrib/debian/copyright | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/contrib/debian/copyright b/contrib/debian/copyright index 04daeb02..fc94e239 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -100,6 +100,19 @@ Files: depends/sources/miniupnpc-*.tar.gz Copyright: 2005-2016 Thomas BERNARD License: BSD-3clause +Files: depends/sources/zeromq-*.tar.gz +Copyright: + 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2007-2014 iMatix Corporation + 2009-2011 250bpm s.r.o. + 2010-2011 Miru Limited + 2011 VMware, Inc. + 2012 Spotify AB + 2013 Ericsson AB + 2014 AppDynamics Inc. + 2015-2016 Brocade Communications Systems Inc. +License: LGPL-with-ZeroMQ-exception + Files: depends/sources/google*.tar.gz Copyright: 2008 Google Inc. License: BSD-3clause-Google @@ -1140,3 +1153,32 @@ Comment: License: PUB-DOM This work is in the public domain. + +License: LGPL-with-ZeroMQ-exception + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + . + On Debian systems the GNU Lesser General Public License (LGPL) is + located in '/usr/share/common-licenses/LGPL'. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + -------------------------------------------------------------------------------- + SPECIAL EXCEPTION GRANTED BY COPYRIGHT HOLDERS + . + As a special exception, copyright holders give you permission to link this + library with independent modules to produce an executable, regardless of + the license terms of these independent modules, and to copy and distribute + the resulting executable under terms of your choice, provided that you also + meet, for each linked independent module, the terms and conditions of + the license of that module. An independent module is a module which is not + derived from or based on this library. If you modify this library, you must + extend this exception to your version of the library. + + Note: this exception relieves you of any obligations under sections 4 and 5 + of this license, and section 6 of the GNU General Public License. +Comment: + You should have received a copy of the GNU General Public License + along with this program. If not, see . From 602407de953dcb1e07a24cbb49f42104dc375c17 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Mon, 6 Feb 2017 14:10:13 +0000 Subject: [PATCH 32/35] [depends] ZeroMQ 4.2.1 --- depends/packages/zeromq.mk | 17 +++++--------- ...d3957725acd34aa8b8d011585812f3369411.patch | 22 ------------------- ...45c12e0b100cd38acecc16ce7db02905e27c.patch | 22 ------------------- 3 files changed, 5 insertions(+), 56 deletions(-) delete mode 100644 depends/patches/zeromq/9114d3957725acd34aa8b8d011585812f3369411.patch delete mode 100644 depends/patches/zeromq/9e6745c12e0b100cd38acecc16ce7db02905e27c.patch diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 30bb3b45..4b335c54 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -1,27 +1,20 @@ package=zeromq -$(package)_version=4.1.5 -$(package)_download_path=https://github.com/zeromq/zeromq4-1/releases/download/v$($(package)_version)/ +$(package)_version=4.2.1 +$(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)/ $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=04aac57f081ffa3a2ee5ed04887be9e205df3a7ddade0027460b8042432bdbcf -$(package)_patches=9114d3957725acd34aa8b8d011585812f3369411.patch 9e6745c12e0b100cd38acecc16ce7db02905e27c.patch +$(package)_sha256_hash=27d1e82a099228ee85a7ddb2260f40830212402c605a4a10b5e5498a7e0e9d03 define $(package)_set_vars - $(package)_config_opts=--without-documentation --disable-shared --without-libsodium --disable-curve + $(package)_config_opts=--without-documentation --disable-shared --disable-curve $(package)_config_opts_linux=--with-pic endef -define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/9114d3957725acd34aa8b8d011585812f3369411.patch && \ - patch -p1 < $($(package)_patch_dir)/9e6745c12e0b100cd38acecc16ce7db02905e27c.patch && \ - ./autogen.sh -endef - define $(package)_config_cmds $($(package)_autoconf) endef define $(package)_build_cmds - $(MAKE) libzmq.la + $(MAKE) src/libzmq.la endef define $(package)_stage_cmds diff --git a/depends/patches/zeromq/9114d3957725acd34aa8b8d011585812f3369411.patch b/depends/patches/zeromq/9114d3957725acd34aa8b8d011585812f3369411.patch deleted file mode 100644 index f704b3d9..00000000 --- a/depends/patches/zeromq/9114d3957725acd34aa8b8d011585812f3369411.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 9114d3957725acd34aa8b8d011585812f3369411 Mon Sep 17 00:00:00 2001 -From: Jeroen Ooms -Date: Tue, 20 Oct 2015 13:10:38 +0200 -Subject: [PATCH] enable static libraries on mingw - ---- - configure.ac | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 393505b..e92131a 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -265,7 +265,7 @@ case "${host_os}" in - libzmq_dso_visibility="no" - - if test "x$enable_static" = "xyes"; then -- AC_MSG_ERROR([Building static libraries is not supported under MinGW32]) -+ CPPFLAGS="-DZMQ_STATIC" - fi - - # Set FD_SETSIZE to 1024 \ No newline at end of file diff --git a/depends/patches/zeromq/9e6745c12e0b100cd38acecc16ce7db02905e27c.patch b/depends/patches/zeromq/9e6745c12e0b100cd38acecc16ce7db02905e27c.patch deleted file mode 100644 index 9aff2c17..00000000 --- a/depends/patches/zeromq/9e6745c12e0b100cd38acecc16ce7db02905e27c.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 9e6745c12e0b100cd38acecc16ce7db02905e27c Mon Sep 17 00:00:00 2001 -From: David Millard -Date: Tue, 10 May 2016 13:53:53 -0700 -Subject: [PATCH] Fix autotools for static MinGW builds - ---- - configure.ac | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 5a0fa14..def6ea7 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -259,7 +259,7 @@ case "${host_os}" in - libzmq_dso_visibility="no" - - if test "x$enable_static" = "xyes"; then -- CPPFLAGS="-DZMQ_STATIC" -+ CPPFLAGS="-DZMQ_STATIC $CPPFLAGS" - fi - - # Set FD_SETSIZE to 1024 \ No newline at end of file From 7c8845eddae095568bb15505c4736d52d9ac752f Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 8 Feb 2017 22:18:17 +0000 Subject: [PATCH 33/35] Clarify that user only needs libzmq if not using depends system --- doc/zmq.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/zmq.md b/doc/zmq.md index 7601ebac..92e051db 100644 --- a/doc/zmq.md +++ b/doc/zmq.md @@ -34,7 +34,8 @@ buffering or reassembly. ## Prerequisites The ZeroMQ feature in Zcash requires ZeroMQ API version 4.x or -newer. Typically, it is packaged by distributions as something like +newer, which you will need to install if you are not using the depends +system. Typically, it is packaged by distributions as something like *libzmq3-dev*. The C++ wrapper for ZeroMQ is *not* needed. In order to run the example Python client scripts in contrib/ one must From edcec148a86ddb7aee9b6f05f9985027d15e5890 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 8 Feb 2017 22:18:48 +0000 Subject: [PATCH 34/35] Bump suggested ZMQ Debian package to 4.1 series --- doc/zmq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/zmq.md b/doc/zmq.md index 92e051db..e23c0937 100644 --- a/doc/zmq.md +++ b/doc/zmq.md @@ -36,7 +36,7 @@ buffering or reassembly. The ZeroMQ feature in Zcash requires ZeroMQ API version 4.x or newer, which you will need to install if you are not using the depends system. Typically, it is packaged by distributions as something like -*libzmq3-dev*. The C++ wrapper for ZeroMQ is *not* needed. +*libzmq5-dev*. The C++ wrapper for ZeroMQ is *not* needed. In order to run the example Python client scripts in contrib/ one must also install *python-zmq*, though this is not necessary for daemon From 9bbc220641254c820c407a7cc81cb3a834660344 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 17 Sep 2015 15:45:14 +0200 Subject: [PATCH 35/35] fix rpc-tests.sh `${testScripts[@]}` now does split up `testscript --agument` in two elements pushed to the array (`testscript` and `--agument`). --- qa/pull-tester/rpc-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index eb30517a..057675ba 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -58,7 +58,7 @@ testScriptsExt=( ); if [ "x$ENABLE_ZMQ" = "x1" ]; then - testScripts=( ${testScripts[@]} 'zmq_test.py' ) + testScripts+=('zmq_test.py') fi extArg="-extended"