// Called at startup to conditionally set up ZMQ socket(s) bool CZMQNotificationInterface::Initialize() { LogPrint("zmq", "zmq: Initialize notification interface\n"); assert(!pcontext); pcontext = zmq_init(1); if (!pcontext) { zmqError("Unable to initialize context"); return false; } std::list<CZMQAbstractNotifier*>::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()) { return false; } return true; }
CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const std::map<std::string, std::string> &args) { CZMQNotificationInterface* notificationInterface = NULL; std::map<std::string, CZMQNotifierFactory> factories; std::list<CZMQAbstractNotifier*> notifiers; factories["pubhashblock"] = CZMQAbstractNotifier::Create<CZMQPublishHashBlockNotifier>; factories["pubhashtx"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionNotifier>; factories["pubrawblock"] = CZMQAbstractNotifier::Create<CZMQPublishRawBlockNotifier>; factories["pubrawtx"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionNotifier>; for (std::map<std::string, CZMQNotifierFactory>::const_iterator i=factories.begin(); i!=factories.end(); ++i) { std::map<std::string, std::string>::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; }
void CZMQNotificationInterface::NotifySyscoinUpdate(const char *value, const char *topic) { for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i != notifiers.end(); ) { CZMQAbstractNotifier *notifier = *i; std::string strTopic(topic); // look for topic in notifier list, if finds it, sends an update if (notifier->GetType() != "pub" + strTopic) { i++; continue; } if (notifier->NotifySyscoinUpdate(value, topic)) { i++; } else { notifier->Shutdown(); i = notifiers.erase(i); } } }
CZMQNotificationInterface* CZMQNotificationInterface::Create() { CZMQNotificationInterface* notificationInterface = NULL; std::map<std::string, CZMQNotifierFactory> factories; std::list<CZMQAbstractNotifier*> notifiers; factories["pubhashblock"] = CZMQAbstractNotifier::Create<CZMQPublishHashBlockNotifier>; factories["pubhashtx"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionNotifier>; factories["pubhashtxlock"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionLockNotifier>; factories["pubrawblock"] = CZMQAbstractNotifier::Create<CZMQPublishRawBlockNotifier>; factories["pubrawtx"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionNotifier>; factories["pubrawtxlock"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionLockNotifier>; factories["pubaliashistory"] = CZMQAbstractNotifier::Create<CZMQPublishRawSyscoinNotifier>; factories["pubaliasrecord"] = CZMQAbstractNotifier::Create<CZMQPublishRawSyscoinNotifier>; factories["pubaliastxhistory"] = CZMQAbstractNotifier::Create<CZMQPublishRawSyscoinNotifier>; factories["pubassetallocation"] = CZMQAbstractNotifier::Create<CZMQPublishRawSyscoinNotifier>; factories["pubassethistory"] = CZMQAbstractNotifier::Create<CZMQPublishRawSyscoinNotifier>; factories["pubassetrecord"] = CZMQAbstractNotifier::Create<CZMQPublishRawSyscoinNotifier>; factories["pubcerthistory"] = CZMQAbstractNotifier::Create<CZMQPublishRawSyscoinNotifier>; factories["pubcertrecord"] = CZMQAbstractNotifier::Create<CZMQPublishRawSyscoinNotifier>; factories["pubescrowbid"] = CZMQAbstractNotifier::Create<CZMQPublishRawSyscoinNotifier>; factories["pubescrowfeedback"] = CZMQAbstractNotifier::Create<CZMQPublishRawSyscoinNotifier>; factories["pubescrowrecord"] = CZMQAbstractNotifier::Create<CZMQPublishRawSyscoinNotifier>; factories["pubofferhistory"] = CZMQAbstractNotifier::Create<CZMQPublishRawSyscoinNotifier>; factories["pubofferrecord"] = CZMQAbstractNotifier::Create<CZMQPublishRawSyscoinNotifier>; for (std::map<std::string, CZMQNotifierFactory>::const_iterator i=factories.begin(); i!=factories.end(); ++i) { std::string arg("-zmq" + i->first); if (IsArgSet(arg)) { CZMQNotifierFactory factory = i->second; std::string address = GetArg(arg, ""); CZMQAbstractNotifier *notifier = factory(); notifier->SetType(i->first); notifier->SetAddress(address); notifiers.push_back(notifier); } } if (!notifiers.empty()) { notificationInterface = new CZMQNotificationInterface(); notificationInterface->notifiers = notifiers; if (!notificationInterface->Initialize()) { delete notificationInterface; notificationInterface = NULL; } } return notificationInterface; }
void CZMQNotificationInterface::SyncTransaction(const CTransaction &tx, const CBlock *pblock) { for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); ) { CZMQAbstractNotifier *notifier = *i; if (notifier->NotifyTransaction(tx)) { i++; } else { notifier->Shutdown(); i = notifiers.erase(i); } } }
void CZMQNotificationInterface::UpdatedBlockTip(const uint256 &hash) { for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); ) { CZMQAbstractNotifier *notifier = *i; if (notifier->NotifyBlock(hash)) { i++; } else { notifier->Shutdown(); i = notifiers.erase(i); } } }
// Called during shutdown sequence void CZMQNotificationInterface::Shutdown() { LogPrint("zmq", "Shutdown notification interface\n"); if (pcontext) { for (std::list<CZMQAbstractNotifier*>::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 CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) { if (fInitialDownload || pindexNew == pindexFork) // In IBD or blocks were disconnected without any new ones return; for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); ) { CZMQAbstractNotifier *notifier = *i; if (notifier->NotifyBlock(pindexNew)) { i++; } else { notifier->Shutdown(); i = notifiers.erase(i); } } }
void CZMQNotificationInterface::BlockChecked(const CBlock& block, const CValidationState& state) { if (state.IsInvalid()) { return; } for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); ) { CZMQAbstractNotifier *notifier = *i; if (notifier->NotifyBlock(block)) { i++; } else { notifier->Shutdown(); i = notifiers.erase(i); } } }