Add ZeroMQ support. Notify blocks and transactions via ZeroMQ
[bitcoinplatinum.git] / src / zmq / zmqnotificationinterface.cpp
blob71ccb59a4a729aa9655e3d6caec810d3e2d8badc
1 // Copyright (c) 2015 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #include "zmqnotificationinterface.h"
6 #include "zmqpublishnotifier.h"
8 #include "version.h"
9 #include "main.h"
10 #include "streams.h"
11 #include "util.h"
13 void zmqError(const char *str)
15 LogPrint("zmq", "Error: %s, errno=%s\n", str, zmq_strerror(errno));
18 CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(NULL)
22 CZMQNotificationInterface::~CZMQNotificationInterface()
24 // ensure Shutdown if Initialize is called
25 assert(!pcontext);
27 for (std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); i!=notifiers.end(); ++i)
29 delete *i;
33 CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const std::map<std::string, std::string> &args)
35 CZMQNotificationInterface* notificationInterface = NULL;
36 std::map<std::string, CZMQNotifierFactory> factories;
37 std::list<CZMQAbstractNotifier*> notifiers;
39 factories["pubhashblock"] = CZMQAbstractNotifier::Create<CZMQPublishHashBlockNotifier>;
40 factories["pubhashtx"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionNotifier>;
41 factories["pubrawblock"] = CZMQAbstractNotifier::Create<CZMQPublishRawBlockNotifier>;
42 factories["pubrawtx"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionNotifier>;
44 for (std::map<std::string, CZMQNotifierFactory>::const_iterator i=factories.begin(); i!=factories.end(); ++i)
46 std::map<std::string, std::string>::const_iterator j = args.find("-zmq" + i->first);
47 if (j!=args.end())
49 CZMQNotifierFactory factory = i->second;
50 std::string address = j->second;
51 CZMQAbstractNotifier *notifier = factory();
52 notifier->SetType(i->first);
53 notifier->SetAddress(address);
54 notifiers.push_back(notifier);
58 if (!notifiers.empty())
60 notificationInterface = new CZMQNotificationInterface();
61 notificationInterface->notifiers = notifiers;
64 return notificationInterface;
67 // Called at startup to conditionally set up ZMQ socket(s)
68 bool CZMQNotificationInterface::Initialize()
70 LogPrint("zmq", "Initialize notification interface\n");
71 assert(!pcontext);
73 pcontext = zmq_init(1);
75 if (!pcontext)
77 zmqError("Unable to initialize context");
78 return false;
81 std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin();
82 for (; i!=notifiers.end(); ++i)
84 CZMQAbstractNotifier *notifier = *i;
85 if (notifier->Initialize(pcontext))
87 LogPrint("zmq", " Notifier %s ready (address = %s)\n", notifier->GetType(), notifier->GetAddress());
89 else
91 LogPrint("zmq", " Notifier %s failed (address = %s)\n", notifier->GetType(), notifier->GetAddress());
92 break;
96 if (i!=notifiers.end())
98 Shutdown();
99 return false;
102 return false;
105 // Called during shutdown sequence
106 void CZMQNotificationInterface::Shutdown()
108 LogPrint("zmq", "Shutdown notification interface\n");
109 if (pcontext)
111 for (std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); i!=notifiers.end(); ++i)
113 CZMQAbstractNotifier *notifier = *i;
114 LogPrint("zmq", " Shutdown notifier %s at %s\n", notifier->GetType(), notifier->GetAddress());
115 notifier->Shutdown();
117 zmq_ctx_destroy(pcontext);
119 pcontext = 0;
123 void CZMQNotificationInterface::UpdatedBlockTip(const uint256 &hash)
125 for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); )
127 CZMQAbstractNotifier *notifier = *i;
128 if (notifier->NotifyBlock(hash))
130 i++;
132 else
134 notifier->Shutdown();
135 i = notifiers.erase(i);
140 void CZMQNotificationInterface::SyncTransaction(const CTransaction &tx, const CBlock *pblock)
142 for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); )
144 CZMQAbstractNotifier *notifier = *i;
145 if (notifier->NotifyTransaction(tx))
147 i++;
149 else
151 notifier->Shutdown();
152 i = notifiers.erase(i);