Dash Core  0.12.2.1
P2P Digital Currency
zmqnotificationinterface.cpp
Go to the documentation of this file.
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.
4 
6 #include "zmqpublishnotifier.h"
7 
8 #include "version.h"
9 #include "validation.h"
10 #include "streams.h"
11 #include "util.h"
12 
13 void zmqError(const char *str)
14 {
15  LogPrint("zmq", "zmq: Error: %s, errno=%s\n", str, zmq_strerror(errno));
16 }
17 
19 {
20 }
21 
23 {
24  Shutdown();
25 
26  for (std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); i!=notifiers.end(); ++i)
27  {
28  delete *i;
29  }
30 }
31 
32 CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const std::map<std::string, std::string> &args)
33 {
34  CZMQNotificationInterface* notificationInterface = NULL;
35  std::map<std::string, CZMQNotifierFactory> factories;
36  std::list<CZMQAbstractNotifier*> notifiers;
37 
38  factories["pubhashblock"] = CZMQAbstractNotifier::Create<CZMQPublishHashBlockNotifier>;
39  factories["pubhashtx"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionNotifier>;
40  factories["pubhashtxlock"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionLockNotifier>;
41  factories["pubrawblock"] = CZMQAbstractNotifier::Create<CZMQPublishRawBlockNotifier>;
42  factories["pubrawtx"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionNotifier>;
43  factories["pubrawtxlock"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionLockNotifier>;
44 
45  for (std::map<std::string, CZMQNotifierFactory>::const_iterator i=factories.begin(); i!=factories.end(); ++i)
46  {
47  std::map<std::string, std::string>::const_iterator j = args.find("-zmq" + i->first);
48  if (j!=args.end())
49  {
50  CZMQNotifierFactory factory = i->second;
51  std::string address = j->second;
52  CZMQAbstractNotifier *notifier = factory();
53  notifier->SetType(i->first);
54  notifier->SetAddress(address);
55  notifiers.push_back(notifier);
56  }
57  }
58 
59  if (!notifiers.empty())
60  {
61  notificationInterface = new CZMQNotificationInterface();
62  notificationInterface->notifiers = notifiers;
63 
64  if (!notificationInterface->Initialize())
65  {
66  delete notificationInterface;
67  notificationInterface = NULL;
68  }
69  }
70 
71  return notificationInterface;
72 }
73 
74 // Called at startup to conditionally set up ZMQ socket(s)
76 {
77  LogPrint("zmq", "zmq: Initialize notification interface\n");
78  assert(!pcontext);
79 
80  pcontext = zmq_init(1);
81 
82  if (!pcontext)
83  {
84  zmqError("Unable to initialize context");
85  return false;
86  }
87 
88  std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin();
89  for (; i!=notifiers.end(); ++i)
90  {
91  CZMQAbstractNotifier *notifier = *i;
92  if (notifier->Initialize(pcontext))
93  {
94  LogPrint("zmq", " Notifier %s ready (address = %s)\n", notifier->GetType(), notifier->GetAddress());
95  }
96  else
97  {
98  LogPrint("zmq", " Notifier %s failed (address = %s)\n", notifier->GetType(), notifier->GetAddress());
99  break;
100  }
101  }
102 
103  if (i!=notifiers.end())
104  {
105  return false;
106  }
107 
108  return true;
109 }
110 
111 // Called during shutdown sequence
113 {
114  LogPrint("zmq", "zmq: Shutdown notification interface\n");
115  if (pcontext)
116  {
117  for (std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); i!=notifiers.end(); ++i)
118  {
119  CZMQAbstractNotifier *notifier = *i;
120  LogPrint("zmq", " Shutdown notifier %s at %s\n", notifier->GetType(), notifier->GetAddress());
121  notifier->Shutdown();
122  }
123  zmq_ctx_destroy(pcontext);
124 
125  pcontext = 0;
126  }
127 }
128 
129 void CZMQNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
130 {
131  if (fInitialDownload || pindexNew == pindexFork) // In IBD or blocks were disconnected without any new ones
132  return;
133 
134  for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); )
135  {
136  CZMQAbstractNotifier *notifier = *i;
137  if (notifier->NotifyBlock(pindexNew))
138  {
139  i++;
140  }
141  else
142  {
143  notifier->Shutdown();
144  i = notifiers.erase(i);
145  }
146  }
147 }
148 
150 {
151  for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); )
152  {
153  CZMQAbstractNotifier *notifier = *i;
154  if (notifier->NotifyTransaction(tx))
155  {
156  i++;
157  }
158  else
159  {
160  notifier->Shutdown();
161  i = notifiers.erase(i);
162  }
163  }
164 }
165 
167 {
168  for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); )
169  {
170  CZMQAbstractNotifier *notifier = *i;
171  if (notifier->NotifyTransactionLock(tx))
172  {
173  i++;
174  }
175  else
176  {
177  notifier->Shutdown();
178  i = notifiers.erase(i);
179  }
180  }
181 }
virtual bool NotifyTransaction(const CTransaction &transaction)
void NotifyTransactionLock(const CTransaction &tx)
void SetAddress(const std::string &a)
void SyncTransaction(const CTransaction &tx, const CBlock *pblock)
virtual bool Initialize(void *pcontext)=0
std::string GetType() const
virtual bool NotifyBlock(const CBlockIndex *pindex)
static CZMQNotificationInterface * CreateWithArguments(const std::map< std::string, std::string > &args)
static int LogPrint(const char *category, const char *format)
Definition: util.h:126
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
virtual bool NotifyTransactionLock(const CTransaction &transaction)
virtual void Shutdown()=0
void zmqError(const char *str)
CZMQAbstractNotifier *(* CZMQNotifierFactory)()
void SetType(const std::string &t)
Definition: block.h:73
std::string GetAddress() const
std::list< CZMQAbstractNotifier * > notifiers