2014-11-18 18:06:32 +01:00
|
|
|
// 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.
|
|
|
|
|
2020-09-01 09:40:13 +02:00
|
|
|
#include <zmq/zmqpublishnotifier.h>
|
|
|
|
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <chain.h>
|
|
|
|
#include <chainparams.h>
|
|
|
|
#include <streams.h>
|
2020-09-01 09:40:13 +02:00
|
|
|
#include <validation.h>
|
|
|
|
#include <zmq/zmqutil.h>
|
|
|
|
|
2021-10-01 21:19:08 +02:00
|
|
|
#include <governance/object.h>
|
|
|
|
#include <governance/vote.h>
|
2020-09-01 09:40:13 +02:00
|
|
|
|
2021-10-02 19:32:24 +02:00
|
|
|
#include <llmq/chainlocks.h>
|
|
|
|
#include <llmq/instantsend.h>
|
|
|
|
#include <llmq/signing.h>
|
2020-09-01 09:40:13 +02:00
|
|
|
|
|
|
|
#include <zmq.h>
|
|
|
|
|
|
|
|
#include <cstdarg>
|
|
|
|
#include <cstddef>
|
|
|
|
#include <map>
|
|
|
|
#include <string>
|
|
|
|
#include <utility>
|
2014-11-18 18:06:32 +01:00
|
|
|
|
|
|
|
static std::multimap<std::string, CZMQAbstractPublishNotifier*> mapPublishNotifiers;
|
|
|
|
|
2019-05-08 11:12:54 +02:00
|
|
|
static const char *MSG_HASHBLOCK = "hashblock";
|
|
|
|
static const char *MSG_HASHCHAINLOCK = "hashchainlock";
|
|
|
|
static const char *MSG_HASHTX = "hashtx";
|
|
|
|
static const char *MSG_HASHTXLOCK = "hashtxlock";
|
|
|
|
static const char *MSG_HASHGVOTE = "hashgovernancevote";
|
|
|
|
static const char *MSG_HASHGOBJ = "hashgovernanceobject";
|
|
|
|
static const char *MSG_HASHISCON = "hashinstantsenddoublespend";
|
2020-11-17 20:41:30 +01:00
|
|
|
static const char *MSG_HASHRECSIG = "hashrecoveredsig";
|
2019-05-08 11:12:54 +02:00
|
|
|
static const char *MSG_RAWBLOCK = "rawblock";
|
|
|
|
static const char *MSG_RAWCHAINLOCK = "rawchainlock";
|
2019-05-23 11:13:58 +02:00
|
|
|
static const char *MSG_RAWCLSIG = "rawchainlocksig";
|
2019-05-08 11:12:54 +02:00
|
|
|
static const char *MSG_RAWTX = "rawtx";
|
|
|
|
static const char *MSG_RAWTXLOCK = "rawtxlock";
|
2019-05-23 11:13:58 +02:00
|
|
|
static const char *MSG_RAWTXLOCKSIG = "rawtxlocksig";
|
2019-05-08 11:12:54 +02:00
|
|
|
static const char *MSG_RAWGVOTE = "rawgovernancevote";
|
|
|
|
static const char *MSG_RAWGOBJ = "rawgovernanceobject";
|
|
|
|
static const char *MSG_RAWISCON = "rawinstantsenddoublespend";
|
2020-11-17 20:41:30 +01:00
|
|
|
static const char *MSG_RAWRECSIG = "rawrecoveredsig";
|
2016-10-17 22:09:21 +02:00
|
|
|
|
2014-11-18 18:06:32 +01:00
|
|
|
// 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");
|
2017-03-27 10:34:13 +02:00
|
|
|
va_end(args);
|
2014-11-18 18:06:32 +01:00
|
|
|
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);
|
2017-03-27 10:34:13 +02:00
|
|
|
va_end(args);
|
2014-11-18 18:06:32 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
zmq_msg_close(&msg);
|
|
|
|
|
|
|
|
if (!data)
|
|
|
|
break;
|
|
|
|
|
|
|
|
size = va_arg(args, size_t);
|
|
|
|
}
|
2017-03-27 10:34:13 +02:00
|
|
|
va_end(args);
|
2014-11-18 18:06:32 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CZMQAbstractPublishNotifier::Initialize(void *pcontext)
|
|
|
|
{
|
|
|
|
assert(!psocket);
|
|
|
|
|
|
|
|
// check if address is being used by other publish notifier
|
|
|
|
std::multimap<std::string, CZMQAbstractPublishNotifier*>::iterator i = mapPublishNotifiers.find(address);
|
|
|
|
|
|
|
|
if (i==mapPublishNotifiers.end())
|
|
|
|
{
|
|
|
|
psocket = zmq_socket(pcontext, ZMQ_PUB);
|
|
|
|
if (!psocket)
|
|
|
|
{
|
|
|
|
zmqError("Failed to create socket");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-09-08 18:39:06 +02:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Outbound message high water mark for %s at %s is %d\n", type, address, outbound_message_high_water_mark);
|
|
|
|
|
|
|
|
int rc = zmq_setsockopt(psocket, ZMQ_SNDHWM, &outbound_message_high_water_mark, sizeof(outbound_message_high_water_mark));
|
|
|
|
if (rc != 0)
|
|
|
|
{
|
|
|
|
zmqError("Failed to set outbound message high water mark");
|
|
|
|
zmq_close(psocket);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
Merge #14687: zmq: enable tcp keepalive
c276df775914e4e42993c76e172ef159e3b830d4 zmq: enable tcp keepalive (mruddy)
Pull request description:
This addresses https://github.com/bitcoin/bitcoin/issues/12754.
These changes enable node operators to address the silent dropping (by network middle boxes) of long-lived low-activity ZMQ TCP connections via further operating system level TCP keepalive configuration. For example, ZMQ sockets that publish block hashes can be affected in this way due to the length of time it sometimes takes between finding blocks (e.g.- sometimes more than an hour).
Prior to this patch, operating system level TCP keepalive configurations would not take effect since the SO_KEEPALIVE option was not enabled on the underlying socket.
There are additional ZMQ socket options related to TCP keepalive that can be set. However, I decided not to implement those options in this changeset because doing so would require adding additional bitcoin node configuration options, and would not yield a better outcome. I preferred a small, easily reviewable patch that doesn't add a bunch of new config options, with the tradeoff that the fine tuning would have to be done via well-documented operating system specific configurations.
I tested this patch by running a node with:
`./src/qt/bitcoin-qt -regtest -txindex -datadir=/tmp/node -zmqpubhashblock=tcp://127.0.0.1:28332 &`
and connecting to it with:
`python3 ./contrib/zmq/zmq_sub.py`
Without these changes, `ss -panto | grep 28332 | grep ESTAB | grep bitcoin` will report no keepalive timer information. With these changes, the output from the prior command will show keepalive timer information consistent with the configuration at the time of connection establishment, e.g.-: `timer:(keepalive,119min,0)`.
I also tested with a non-TCP transport and did not witness any adverse effects:
`./src/qt/bitcoin-qt -regtest -txindex -datadir=/tmp/node -zmqpubhashblock=ipc:///tmp/bitcoin.block &`
ACKs for top commit:
adamjonas:
Just to summarize for those looking to review - as of c276df775914e4e42993c76e172ef159e3b830d4 there are 3 tACKs (n-thumann, Haaroon, and dlogemann), 1 "looks good to me" (laanwj) with no NACKs or any show-stopping concerns raised.
jonasschnelli:
utACK c276df775914e4e42993c76e172ef159e3b830d4
Tree-SHA512: b884c2c9814e97e666546a7188c48f9de9541499a11a934bd48dd16169a900c900fa519feb3b1cb7e9915fc7539aac2829c7806b5937b4e1409b4805f3ef6cd1
2020-09-02 09:09:08 +02:00
|
|
|
const int so_keepalive_option {1};
|
|
|
|
rc = zmq_setsockopt(psocket, ZMQ_TCP_KEEPALIVE, &so_keepalive_option, sizeof(so_keepalive_option));
|
|
|
|
if (rc != 0) {
|
|
|
|
zmqError("Failed to set SO_KEEPALIVE");
|
|
|
|
zmq_close(psocket);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-09-08 18:39:06 +02:00
|
|
|
rc = zmq_bind(psocket, address.c_str());
|
|
|
|
if (rc != 0)
|
2014-11-18 18:06:32 +01:00
|
|
|
{
|
|
|
|
zmqError("Failed to bind address");
|
2016-10-17 22:09:21 +02:00
|
|
|
zmq_close(psocket);
|
2014-11-18 18:06:32 +01:00
|
|
|
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
|
|
|
|
{
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Reusing socket for address %s\n", address);
|
2019-01-21 17:18:24 +01:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Outbound message high water mark for %s at %s is %d\n", type, address, outbound_message_high_water_mark);
|
2014-11-18 18:06:32 +01:00
|
|
|
|
|
|
|
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<std::string, CZMQAbstractPublishNotifier*>::iterator iterator;
|
|
|
|
std::pair<iterator, iterator> 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)
|
|
|
|
{
|
2021-09-08 18:39:06 +02:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Close socket at address %s\n", address);
|
2014-11-18 18:06:32 +01:00
|
|
|
int linger = 0;
|
|
|
|
zmq_setsockopt(psocket, ZMQ_LINGER, &linger, sizeof(linger));
|
|
|
|
zmq_close(psocket);
|
|
|
|
}
|
|
|
|
|
2017-08-16 15:54:51 +02:00
|
|
|
psocket = nullptr;
|
2014-11-18 18:06:32 +01:00
|
|
|
}
|
|
|
|
|
2020-09-01 09:40:13 +02:00
|
|
|
bool CZMQAbstractPublishNotifier::SendZmqMessage(const char *command, const void* data, size_t size)
|
2016-10-17 22:09:21 +02:00
|
|
|
{
|
|
|
|
assert(psocket);
|
|
|
|
|
|
|
|
/* send three parts, command & data & a LE 4byte sequence number */
|
|
|
|
unsigned char msgseq[sizeof(uint32_t)];
|
|
|
|
WriteLE32(&msgseq[0], nSequence);
|
2017-08-16 15:54:51 +02:00
|
|
|
int rc = zmq_send_multipart(psocket, command, strlen(command), data, size, msgseq, (size_t)sizeof(uint32_t), nullptr);
|
2016-10-17 22:09:21 +02:00
|
|
|
if (rc == -1)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
/* increment memory only sequence number after sending */
|
|
|
|
nSequence++;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-09-16 16:42:23 +02:00
|
|
|
bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
|
2014-11-18 18:06:32 +01:00
|
|
|
{
|
2015-09-16 16:42:23 +02:00
|
|
|
uint256 hash = pindex->GetBlockHash();
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish hashblock %s\n", hash.GetHex());
|
2014-11-18 18:06:32 +01:00
|
|
|
char data[32];
|
|
|
|
for (unsigned int i = 0; i < 32; i++)
|
|
|
|
data[31 - i] = hash.begin()[i];
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_HASHBLOCK, data, 32);
|
2014-11-18 18:06:32 +01:00
|
|
|
}
|
|
|
|
|
2021-01-22 05:32:15 +01:00
|
|
|
bool CZMQPublishHashChainLockNotifier::NotifyChainLock(const CBlockIndex *pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig)
|
2019-05-08 11:12:54 +02:00
|
|
|
{
|
|
|
|
uint256 hash = pindex->GetBlockHash();
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish hashchainlock %s\n", hash.GetHex());
|
2019-05-08 11:12:54 +02:00
|
|
|
char data[32];
|
|
|
|
for (unsigned int i = 0; i < 32; i++)
|
|
|
|
data[31 - i] = hash.begin()[i];
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_HASHCHAINLOCK, data, 32);
|
2019-05-08 11:12:54 +02:00
|
|
|
}
|
|
|
|
|
2014-11-18 18:06:32 +01:00
|
|
|
bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction)
|
|
|
|
{
|
|
|
|
uint256 hash = transaction.GetHash();
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish hashtx %s\n", hash.GetHex());
|
2014-11-18 18:06:32 +01:00
|
|
|
char data[32];
|
|
|
|
for (unsigned int i = 0; i < 32; i++)
|
|
|
|
data[31 - i] = hash.begin()[i];
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_HASHTX, data, 32);
|
2014-11-18 18:06:32 +01:00
|
|
|
}
|
|
|
|
|
2021-01-22 05:32:15 +01:00
|
|
|
bool CZMQPublishHashTransactionLockNotifier::NotifyTransactionLock(const CTransactionRef& transaction, const std::shared_ptr<const llmq::CInstantSendLock>& islock)
|
2016-07-15 08:38:33 +02:00
|
|
|
{
|
2021-01-22 05:32:15 +01:00
|
|
|
uint256 hash = transaction->GetHash();
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish hashtxlock %s\n", hash.GetHex());
|
2016-07-15 08:38:33 +02:00
|
|
|
char data[32];
|
|
|
|
for (unsigned int i = 0; i < 32; i++)
|
|
|
|
data[31 - i] = hash.begin()[i];
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_HASHTXLOCK, data, 32);
|
2016-07-15 08:38:33 +02:00
|
|
|
}
|
|
|
|
|
2021-01-22 05:32:15 +01:00
|
|
|
bool CZMQPublishHashGovernanceVoteNotifier::NotifyGovernanceVote(const std::shared_ptr<const CGovernanceVote>& vote)
|
2018-07-12 11:06:30 +02:00
|
|
|
{
|
2021-01-22 05:32:15 +01:00
|
|
|
uint256 hash = vote->GetHash();
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish hashgovernancevote %s\n", hash.GetHex());
|
2018-07-12 11:06:30 +02:00
|
|
|
char data[32];
|
|
|
|
for (unsigned int i = 0; i < 32; i++)
|
|
|
|
data[31 - i] = hash.begin()[i];
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_HASHGVOTE, data, 32);
|
2018-07-12 11:06:30 +02:00
|
|
|
}
|
|
|
|
|
2021-01-22 05:32:15 +01:00
|
|
|
bool CZMQPublishHashGovernanceObjectNotifier::NotifyGovernanceObject(const std::shared_ptr<const CGovernanceObject>& object)
|
2018-07-12 11:06:30 +02:00
|
|
|
{
|
2021-01-22 05:32:15 +01:00
|
|
|
uint256 hash = object->GetHash();
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish hashgovernanceobject %s\n", hash.GetHex());
|
2018-07-12 11:06:30 +02:00
|
|
|
char data[32];
|
|
|
|
for (unsigned int i = 0; i < 32; i++)
|
|
|
|
data[31 - i] = hash.begin()[i];
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_HASHGOBJ, data, 32);
|
2018-07-12 11:06:30 +02:00
|
|
|
}
|
|
|
|
|
2021-01-22 05:32:15 +01:00
|
|
|
bool CZMQPublishHashInstantSendDoubleSpendNotifier::NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx)
|
2018-09-12 13:12:44 +02:00
|
|
|
{
|
2021-01-22 05:32:15 +01:00
|
|
|
uint256 currentHash = currentTx->GetHash(), previousHash = previousTx->GetHash();
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish hashinstantsenddoublespend %s conflicts against %s\n", currentHash.ToString(), previousHash.ToString());
|
2018-09-12 13:12:44 +02:00
|
|
|
char dataCurrentHash[32], dataPreviousHash[32];
|
|
|
|
for (unsigned int i = 0; i < 32; i++) {
|
|
|
|
dataCurrentHash[31 - i] = currentHash.begin()[i];
|
|
|
|
dataPreviousHash[31 - i] = previousHash.begin()[i];
|
|
|
|
}
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_HASHISCON, dataCurrentHash, 32)
|
|
|
|
&& SendZmqMessage(MSG_HASHISCON, dataPreviousHash, 32);
|
2018-09-12 13:12:44 +02:00
|
|
|
}
|
|
|
|
|
2021-01-22 05:32:15 +01:00
|
|
|
bool CZMQPublishHashRecoveredSigNotifier::NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig> &sig)
|
2020-11-17 20:41:30 +01:00
|
|
|
{
|
2021-01-22 05:32:15 +01:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish hashrecoveredsig %s\n", sig->msgHash.ToString());
|
2020-11-17 20:41:30 +01:00
|
|
|
char data[32];
|
|
|
|
for (unsigned int i = 0; i < 32; i++)
|
2021-01-22 05:32:15 +01:00
|
|
|
data[31 - i] = sig->msgHash.begin()[i];
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_HASHRECSIG, data, 32);
|
2020-11-17 20:41:30 +01:00
|
|
|
}
|
2018-09-12 13:12:44 +02:00
|
|
|
|
2015-09-16 16:42:23 +02:00
|
|
|
bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
|
2014-11-18 18:06:32 +01:00
|
|
|
{
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish rawblock %s\n", pindex->GetBlockHash().GetHex());
|
2014-11-18 18:06:32 +01:00
|
|
|
|
2015-04-17 14:19:21 +02:00
|
|
|
const Consensus::Params& consensusParams = Params().GetConsensus();
|
2014-11-18 18:06:32 +01:00
|
|
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
|
|
|
{
|
|
|
|
LOCK(cs_main);
|
|
|
|
CBlock block;
|
2015-04-17 14:19:21 +02:00
|
|
|
if(!ReadBlockFromDisk(block, pindex, consensusParams))
|
2014-11-18 18:06:32 +01:00
|
|
|
{
|
|
|
|
zmqError("Can't read block from disk");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
ss << block;
|
|
|
|
}
|
|
|
|
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_RAWBLOCK, &(*ss.begin()), ss.size());
|
2014-11-18 18:06:32 +01:00
|
|
|
}
|
|
|
|
|
2021-01-22 05:32:15 +01:00
|
|
|
bool CZMQPublishRawChainLockNotifier::NotifyChainLock(const CBlockIndex *pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig)
|
2019-05-08 11:12:54 +02:00
|
|
|
{
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish rawchainlock %s\n", pindex->GetBlockHash().GetHex());
|
2019-05-08 11:12:54 +02:00
|
|
|
|
|
|
|
const Consensus::Params& consensusParams = Params().GetConsensus();
|
|
|
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
|
|
|
{
|
|
|
|
LOCK(cs_main);
|
|
|
|
CBlock block;
|
|
|
|
if(!ReadBlockFromDisk(block, pindex, consensusParams))
|
|
|
|
{
|
|
|
|
zmqError("Can't read block from disk");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
ss << block;
|
|
|
|
}
|
|
|
|
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_RAWCHAINLOCK, &(*ss.begin()), ss.size());
|
2019-05-08 11:12:54 +02:00
|
|
|
}
|
|
|
|
|
2021-01-22 05:32:15 +01:00
|
|
|
bool CZMQPublishRawChainLockSigNotifier::NotifyChainLock(const CBlockIndex *pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig)
|
2019-05-23 11:13:58 +02:00
|
|
|
{
|
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish rawchainlocksig %s\n", pindex->GetBlockHash().GetHex());
|
|
|
|
|
|
|
|
const Consensus::Params& consensusParams = Params().GetConsensus();
|
|
|
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
|
|
|
{
|
|
|
|
LOCK(cs_main);
|
|
|
|
CBlock block;
|
|
|
|
if(!ReadBlockFromDisk(block, pindex, consensusParams))
|
|
|
|
{
|
|
|
|
zmqError("Can't read block from disk");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
ss << block;
|
2021-01-22 05:32:15 +01:00
|
|
|
ss << *clsig;
|
2019-05-23 11:13:58 +02:00
|
|
|
}
|
|
|
|
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_RAWCLSIG, &(*ss.begin()), ss.size());
|
2019-05-23 11:13:58 +02:00
|
|
|
}
|
|
|
|
|
2014-11-18 18:06:32 +01:00
|
|
|
bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction)
|
|
|
|
{
|
|
|
|
uint256 hash = transaction.GetHash();
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish rawtx %s\n", hash.GetHex());
|
2014-11-18 18:06:32 +01:00
|
|
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
|
|
|
ss << transaction;
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_RAWTX, &(*ss.begin()), ss.size());
|
2014-11-18 18:06:32 +01:00
|
|
|
}
|
2016-07-15 08:38:33 +02:00
|
|
|
|
2021-01-22 05:32:15 +01:00
|
|
|
bool CZMQPublishRawTransactionLockNotifier::NotifyTransactionLock(const CTransactionRef& transaction, const std::shared_ptr<const llmq::CInstantSendLock>& islock)
|
2016-07-15 08:38:33 +02:00
|
|
|
{
|
2021-01-22 05:32:15 +01:00
|
|
|
uint256 hash = transaction->GetHash();
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish rawtxlock %s\n", hash.GetHex());
|
2016-07-15 08:38:33 +02:00
|
|
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
2021-01-22 05:32:15 +01:00
|
|
|
ss << *transaction;
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_RAWTXLOCK, &(*ss.begin()), ss.size());
|
2016-07-15 08:38:33 +02:00
|
|
|
}
|
2018-07-12 11:06:30 +02:00
|
|
|
|
2021-01-22 05:32:15 +01:00
|
|
|
bool CZMQPublishRawTransactionLockSigNotifier::NotifyTransactionLock(const CTransactionRef& transaction, const std::shared_ptr<const llmq::CInstantSendLock>& islock)
|
2019-05-23 11:13:58 +02:00
|
|
|
{
|
2021-01-22 05:32:15 +01:00
|
|
|
uint256 hash = transaction->GetHash();
|
2019-05-23 11:13:58 +02:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish rawtxlocksig %s\n", hash.GetHex());
|
|
|
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
2021-01-22 05:32:15 +01:00
|
|
|
ss << *transaction;
|
|
|
|
ss << *islock;
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_RAWTXLOCKSIG, &(*ss.begin()), ss.size());
|
2019-05-23 11:13:58 +02:00
|
|
|
}
|
|
|
|
|
2021-01-22 05:32:15 +01:00
|
|
|
bool CZMQPublishRawGovernanceVoteNotifier::NotifyGovernanceVote(const std::shared_ptr<const CGovernanceVote>& vote)
|
2018-07-12 11:06:30 +02:00
|
|
|
{
|
2021-01-22 05:32:15 +01:00
|
|
|
uint256 nHash = vote->GetHash();
|
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish rawgovernanceobject: hash = %s, vote = %d\n", nHash.ToString(), vote->ToString());
|
2018-07-12 11:06:30 +02:00
|
|
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
2021-01-22 05:32:15 +01:00
|
|
|
ss << *vote;
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_RAWGVOTE, &(*ss.begin()), ss.size());
|
2018-07-12 11:06:30 +02:00
|
|
|
}
|
|
|
|
|
2021-01-22 05:32:15 +01:00
|
|
|
bool CZMQPublishRawGovernanceObjectNotifier::NotifyGovernanceObject(const std::shared_ptr<const CGovernanceObject>& govobj)
|
2018-07-12 11:06:30 +02:00
|
|
|
{
|
2021-01-22 05:32:15 +01:00
|
|
|
uint256 nHash = govobj->GetHash();
|
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish rawgovernanceobject: hash = %s, type = %d\n", nHash.ToString(), govobj->GetObjectType());
|
2018-07-12 11:06:30 +02:00
|
|
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
2021-01-22 05:32:15 +01:00
|
|
|
ss << *govobj;
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_RAWGOBJ, &(*ss.begin()), ss.size());
|
2018-07-12 11:06:30 +02:00
|
|
|
}
|
2018-09-12 13:12:44 +02:00
|
|
|
|
2021-01-22 05:32:15 +01:00
|
|
|
bool CZMQPublishRawInstantSendDoubleSpendNotifier::NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx)
|
2018-09-12 13:12:44 +02:00
|
|
|
{
|
2021-01-22 05:32:15 +01:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish rawinstantsenddoublespend %s conflicts with %s\n", currentTx->GetHash().ToString(), previousTx->GetHash().ToString());
|
2018-09-12 13:12:44 +02:00
|
|
|
CDataStream ssCurrent(SER_NETWORK, PROTOCOL_VERSION), ssPrevious(SER_NETWORK, PROTOCOL_VERSION);
|
2021-01-22 05:32:15 +01:00
|
|
|
ssCurrent << *currentTx;
|
|
|
|
ssPrevious << *previousTx;
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_RAWISCON, &(*ssCurrent.begin()), ssCurrent.size())
|
|
|
|
&& SendZmqMessage(MSG_RAWISCON, &(*ssPrevious.begin()), ssPrevious.size());
|
2018-09-12 13:12:44 +02:00
|
|
|
}
|
2020-11-17 20:41:30 +01:00
|
|
|
|
2021-01-22 05:32:15 +01:00
|
|
|
bool CZMQPublishRawRecoveredSigNotifier::NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig)
|
2020-11-17 20:41:30 +01:00
|
|
|
{
|
2021-01-22 05:32:15 +01:00
|
|
|
LogPrint(BCLog::ZMQ, "zmq: Publish rawrecoveredsig %s\n", sig->msgHash.ToString());
|
2020-11-17 20:41:30 +01:00
|
|
|
|
|
|
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
2021-01-22 05:32:15 +01:00
|
|
|
ss << *sig;
|
2020-11-17 20:41:30 +01:00
|
|
|
|
2020-09-01 09:40:13 +02:00
|
|
|
return SendZmqMessage(MSG_RAWRECSIG, &(*ss.begin()), ss.size());
|
2020-11-17 20:41:30 +01:00
|
|
|
}
|
|
|
|
|