[ZMQ] Notify when an IS double spend is attempted (#2262)
* Implement IS Double spend notifications in zmq * copy/paste error * typo * Send both conflicting and conflicts against as ZMQ notifications * CTransaction based not hash based * @UdjinM6 requested changes
This commit is contained in:
parent
28e0476f4c
commit
1e74bcace9
@ -16,11 +16,13 @@ zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashtx")
|
|||||||
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashtxlock")
|
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashtxlock")
|
||||||
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashgovernancevote")
|
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashgovernancevote")
|
||||||
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashgovernanceobject")
|
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashgovernanceobject")
|
||||||
|
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashinstantsenddoublespend")
|
||||||
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawblock")
|
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawblock")
|
||||||
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawtx")
|
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawtx")
|
||||||
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawtxlock")
|
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawtxlock")
|
||||||
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawgovernancevote")
|
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawgovernancevote")
|
||||||
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawgovernanceobject")
|
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawgovernanceobject")
|
||||||
|
zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawinstantsenddoublespend")
|
||||||
zmqSubSocket.connect("tcp://127.0.0.1:%i" % port)
|
zmqSubSocket.connect("tcp://127.0.0.1:%i" % port)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -52,6 +54,9 @@ try:
|
|||||||
elif topic == "rawtxlock":
|
elif topic == "rawtxlock":
|
||||||
print('- RAW TX LOCK ('+sequence+') -')
|
print('- RAW TX LOCK ('+sequence+') -')
|
||||||
print(binascii.hexlify(body).decode("utf-8"))
|
print(binascii.hexlify(body).decode("utf-8"))
|
||||||
|
elif topic == "rawinstantsenddoublespend":
|
||||||
|
print('- RAW IS DOUBLE SPEND ('+sequence+') -')
|
||||||
|
print(binascii.hexlify(body).decode("utf-8"))
|
||||||
elif topic == "hashgovernancevote":
|
elif topic == "hashgovernancevote":
|
||||||
print('- HASH GOVERNANCE VOTE ('+sequence+') -')
|
print('- HASH GOVERNANCE VOTE ('+sequence+') -')
|
||||||
print(binascii.hexlify(body).decode("utf-8"))
|
print(binascii.hexlify(body).decode("utf-8"))
|
||||||
@ -64,7 +69,9 @@ try:
|
|||||||
elif topic == "rawgovernanceobject":
|
elif topic == "rawgovernanceobject":
|
||||||
print('- RAW GOVERNANCE OBJECT ('+sequence+') -')
|
print('- RAW GOVERNANCE OBJECT ('+sequence+') -')
|
||||||
print(binascii.hexlify(body).decode("utf-8"))
|
print(binascii.hexlify(body).decode("utf-8"))
|
||||||
|
elif topic == "hashinstantsenddoublespend":
|
||||||
|
print('- HASH IS DOUBLE SPEND ('+sequence+') -')
|
||||||
|
print(binascii.hexlify(body).decode("utf-8"))
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
zmqContext.destroy()
|
zmqContext.destroy()
|
||||||
|
@ -66,6 +66,8 @@ Currently, the following notifications are supported:
|
|||||||
-zmqpubhashgovernanceobject=address
|
-zmqpubhashgovernanceobject=address
|
||||||
-zmqpubrawgovernancevote=address
|
-zmqpubrawgovernancevote=address
|
||||||
-zmqpubhashgovernanceobject=address
|
-zmqpubhashgovernanceobject=address
|
||||||
|
-zmqpubrawinstantsenddoublespend=address
|
||||||
|
-zmqpubhashinstantsenddoublespend=address
|
||||||
|
|
||||||
The socket type is PUB and the address must be a valid ZeroMQ socket
|
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.
|
address. The same address can be used in more than one notification.
|
||||||
|
@ -508,9 +508,11 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||||||
strUsage += HelpMessageOpt("-zmqpubhashtxlock=<address>", _("Enable publish hash transaction (locked via InstantSend) in <address>"));
|
strUsage += HelpMessageOpt("-zmqpubhashtxlock=<address>", _("Enable publish hash transaction (locked via InstantSend) in <address>"));
|
||||||
strUsage += HelpMessageOpt("-zmqpubhashgovernancevote=<address>", _("Enable publish hash of governance votes in <address>"));
|
strUsage += HelpMessageOpt("-zmqpubhashgovernancevote=<address>", _("Enable publish hash of governance votes in <address>"));
|
||||||
strUsage += HelpMessageOpt("-zmqpubhashgovernanceobject=<address>", _("Enable publish hash of governance objects (like proposals) in <address>"));
|
strUsage += HelpMessageOpt("-zmqpubhashgovernanceobject=<address>", _("Enable publish hash of governance objects (like proposals) in <address>"));
|
||||||
|
strUsage += HelpMessageOpt("-zmqpubhashinstantsenddoublespend=<address>", _("Enable publish transaction hashes of attempted InstantSend double spend in <address>"));
|
||||||
strUsage += HelpMessageOpt("-zmqpubrawblock=<address>", _("Enable publish raw block in <address>"));
|
strUsage += HelpMessageOpt("-zmqpubrawblock=<address>", _("Enable publish raw block in <address>"));
|
||||||
strUsage += HelpMessageOpt("-zmqpubrawtx=<address>", _("Enable publish raw transaction in <address>"));
|
strUsage += HelpMessageOpt("-zmqpubrawtx=<address>", _("Enable publish raw transaction in <address>"));
|
||||||
strUsage += HelpMessageOpt("-zmqpubrawtxlock=<address>", _("Enable publish raw transaction (locked via InstantSend) in <address>"));
|
strUsage += HelpMessageOpt("-zmqpubrawtxlock=<address>", _("Enable publish raw transaction (locked via InstantSend) in <address>"));
|
||||||
|
strUsage += HelpMessageOpt("-zmqpubrawinstantsenddoublespend=<address>", _("Enable publish raw transactions of attempted InstantSend double spend in <address>"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
|
strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
|
||||||
|
@ -117,7 +117,13 @@ bool CInstantSend::ProcessTxLockRequest(const CTxLockRequest& txLockRequest, CCo
|
|||||||
if(hash != txLockRequest.GetHash()) {
|
if(hash != txLockRequest.GetHash()) {
|
||||||
LogPrint("instantsend", "CInstantSend::ProcessTxLockRequest -- Double spend attempt! %s\n", txin.prevout.ToStringShort());
|
LogPrint("instantsend", "CInstantSend::ProcessTxLockRequest -- Double spend attempt! %s\n", txin.prevout.ToStringShort());
|
||||||
// do not fail here, let it go and see which one will get the votes to be locked
|
// do not fail here, let it go and see which one will get the votes to be locked
|
||||||
// TODO: notify zmq+script
|
// NOTIFY ZMQ
|
||||||
|
CTransaction txCurrent = *txLockRequest.tx; // currently processed tx
|
||||||
|
auto itPrevious = mapTxLockCandidates.find(hash);
|
||||||
|
if (itPrevious != mapTxLockCandidates.end() && itPrevious->second.txLockRequest) {
|
||||||
|
CTransaction txPrevious = *itPrevious->second.txLockRequest.tx; // previously locked one
|
||||||
|
GetMainSignals().NotifyInstantSendDoubleSpendAttempt(txCurrent, txPrevious);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) {
|
|||||||
g_signals.NewPoWValidBlock.connect(boost::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2));
|
g_signals.NewPoWValidBlock.connect(boost::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2));
|
||||||
g_signals.NotifyGovernanceObject.connect(boost::bind(&CValidationInterface::NotifyGovernanceObject, pwalletIn, _1));
|
g_signals.NotifyGovernanceObject.connect(boost::bind(&CValidationInterface::NotifyGovernanceObject, pwalletIn, _1));
|
||||||
g_signals.NotifyGovernanceVote.connect(boost::bind(&CValidationInterface::NotifyGovernanceVote, pwalletIn, _1));
|
g_signals.NotifyGovernanceVote.connect(boost::bind(&CValidationInterface::NotifyGovernanceVote, pwalletIn, _1));
|
||||||
|
g_signals.NotifyInstantSendDoubleSpendAttempt.connect(boost::bind(&CValidationInterface::NotifyInstantSendDoubleSpendAttempt, pwalletIn, _1, _2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
|
void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
|
||||||
@ -46,6 +47,7 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
|
|||||||
g_signals.AcceptedBlockHeader.disconnect(boost::bind(&CValidationInterface::AcceptedBlockHeader, pwalletIn, _1));
|
g_signals.AcceptedBlockHeader.disconnect(boost::bind(&CValidationInterface::AcceptedBlockHeader, pwalletIn, _1));
|
||||||
g_signals.NotifyGovernanceObject.disconnect(boost::bind(&CValidationInterface::NotifyGovernanceObject, pwalletIn, _1));
|
g_signals.NotifyGovernanceObject.disconnect(boost::bind(&CValidationInterface::NotifyGovernanceObject, pwalletIn, _1));
|
||||||
g_signals.NotifyGovernanceVote.disconnect(boost::bind(&CValidationInterface::NotifyGovernanceVote, pwalletIn, _1));
|
g_signals.NotifyGovernanceVote.disconnect(boost::bind(&CValidationInterface::NotifyGovernanceVote, pwalletIn, _1));
|
||||||
|
g_signals.NotifyInstantSendDoubleSpendAttempt.disconnect(boost::bind(&CValidationInterface::NotifyInstantSendDoubleSpendAttempt, pwalletIn, _1, _2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnregisterAllValidationInterfaces() {
|
void UnregisterAllValidationInterfaces() {
|
||||||
@ -64,4 +66,5 @@ void UnregisterAllValidationInterfaces() {
|
|||||||
g_signals.AcceptedBlockHeader.disconnect_all_slots();
|
g_signals.AcceptedBlockHeader.disconnect_all_slots();
|
||||||
g_signals.NotifyGovernanceObject.disconnect_all_slots();
|
g_signals.NotifyGovernanceObject.disconnect_all_slots();
|
||||||
g_signals.NotifyGovernanceVote.disconnect_all_slots();
|
g_signals.NotifyGovernanceVote.disconnect_all_slots();
|
||||||
|
g_signals.NotifyInstantSendDoubleSpendAttempt.disconnect_all_slots();
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ protected:
|
|||||||
virtual void NotifyTransactionLock(const CTransaction &tx) {}
|
virtual void NotifyTransactionLock(const CTransaction &tx) {}
|
||||||
virtual void NotifyGovernanceVote(const CGovernanceVote &vote) {}
|
virtual void NotifyGovernanceVote(const CGovernanceVote &vote) {}
|
||||||
virtual void NotifyGovernanceObject(const CGovernanceObject &object) {}
|
virtual void NotifyGovernanceObject(const CGovernanceObject &object) {}
|
||||||
|
virtual void NotifyInstantSendDoubleSpendAttempt(const CTransaction ¤tTx, const CTransaction &previousTx) {}
|
||||||
virtual void SetBestChain(const CBlockLocator &locator) {}
|
virtual void SetBestChain(const CBlockLocator &locator) {}
|
||||||
virtual bool UpdatedTransaction(const uint256 &hash) { return false;}
|
virtual bool UpdatedTransaction(const uint256 &hash) { return false;}
|
||||||
virtual void Inventory(const uint256 &hash) {}
|
virtual void Inventory(const uint256 &hash) {}
|
||||||
@ -77,6 +78,8 @@ struct CMainSignals {
|
|||||||
boost::signals2::signal<void (const CGovernanceVote &)> NotifyGovernanceVote;
|
boost::signals2::signal<void (const CGovernanceVote &)> NotifyGovernanceVote;
|
||||||
/** Notifies listeners of a new governance object. */
|
/** Notifies listeners of a new governance object. */
|
||||||
boost::signals2::signal<void (const CGovernanceObject &)> NotifyGovernanceObject;
|
boost::signals2::signal<void (const CGovernanceObject &)> NotifyGovernanceObject;
|
||||||
|
/** Notifies listeners of a attempted InstantSend double spend*/
|
||||||
|
boost::signals2::signal<void(const CTransaction ¤tTx, const CTransaction &previousTx)> NotifyInstantSendDoubleSpendAttempt;
|
||||||
/** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
|
/** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
|
||||||
boost::signals2::signal<bool (const uint256 &)> UpdatedTransaction;
|
boost::signals2::signal<bool (const uint256 &)> UpdatedTransaction;
|
||||||
/** Notifies listeners of a new active block chain. */
|
/** Notifies listeners of a new active block chain. */
|
||||||
|
@ -35,3 +35,8 @@ bool CZMQAbstractNotifier::NotifyGovernanceObject(const CGovernanceObject& /*obj
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CZMQAbstractNotifier::NotifyInstantSendDoubleSpendAttempt(const CTransaction& /*currentTx*/, const CTransaction& /*previousTx*/)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -39,6 +39,7 @@ public:
|
|||||||
virtual bool NotifyTransactionLock(const CTransaction &transaction);
|
virtual bool NotifyTransactionLock(const CTransaction &transaction);
|
||||||
virtual bool NotifyGovernanceVote(const CGovernanceVote &vote);
|
virtual bool NotifyGovernanceVote(const CGovernanceVote &vote);
|
||||||
virtual bool NotifyGovernanceObject(const CGovernanceObject &object);
|
virtual bool NotifyGovernanceObject(const CGovernanceObject &object);
|
||||||
|
virtual bool NotifyInstantSendDoubleSpendAttempt(const CTransaction ¤tTx, const CTransaction &previousTx);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#include "governance-object.h"
|
#include "governance-object.h"
|
||||||
#include "governance-vote.h"
|
#include "governance-vote.h"
|
||||||
|
|
||||||
|
#include "instantx.h"
|
||||||
|
|
||||||
void zmqError(const char *str);
|
void zmqError(const char *str);
|
||||||
|
|
||||||
#endif // BITCOIN_ZMQ_ZMQCONFIG_H
|
#endif // BITCOIN_ZMQ_ZMQCONFIG_H
|
||||||
|
@ -40,11 +40,13 @@ CZMQNotificationInterface* CZMQNotificationInterface::Create()
|
|||||||
factories["pubhashtxlock"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionLockNotifier>;
|
factories["pubhashtxlock"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionLockNotifier>;
|
||||||
factories["pubhashgovernancevote"] = CZMQAbstractNotifier::Create<CZMQPublishHashGovernanceVoteNotifier>;
|
factories["pubhashgovernancevote"] = CZMQAbstractNotifier::Create<CZMQPublishHashGovernanceVoteNotifier>;
|
||||||
factories["pubhashgovernanceobject"] = CZMQAbstractNotifier::Create<CZMQPublishHashGovernanceObjectNotifier>;
|
factories["pubhashgovernanceobject"] = CZMQAbstractNotifier::Create<CZMQPublishHashGovernanceObjectNotifier>;
|
||||||
|
factories["pubhashinstantsenddoublespend"] = CZMQAbstractNotifier::Create<CZMQPublishHashInstantSendDoubleSpendNotifier>;
|
||||||
factories["pubrawblock"] = CZMQAbstractNotifier::Create<CZMQPublishRawBlockNotifier>;
|
factories["pubrawblock"] = CZMQAbstractNotifier::Create<CZMQPublishRawBlockNotifier>;
|
||||||
factories["pubrawtx"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionNotifier>;
|
factories["pubrawtx"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionNotifier>;
|
||||||
factories["pubrawtxlock"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionLockNotifier>;
|
factories["pubrawtxlock"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionLockNotifier>;
|
||||||
factories["pubrawgovernancevote"] = CZMQAbstractNotifier::Create<CZMQPublishRawGovernanceVoteNotifier>;
|
factories["pubrawgovernancevote"] = CZMQAbstractNotifier::Create<CZMQPublishRawGovernanceVoteNotifier>;
|
||||||
factories["pubrawgovernanceobject"] = CZMQAbstractNotifier::Create<CZMQPublishRawGovernanceObjectNotifier>;
|
factories["pubrawgovernanceobject"] = CZMQAbstractNotifier::Create<CZMQPublishRawGovernanceObjectNotifier>;
|
||||||
|
factories["pubrawinstantsenddoublespend"] = CZMQAbstractNotifier::Create<CZMQPublishRawInstantSendDoubleSpendNotifier>;
|
||||||
|
|
||||||
for (std::map<std::string, CZMQNotifierFactory>::const_iterator i=factories.begin(); i!=factories.end(); ++i)
|
for (std::map<std::string, CZMQNotifierFactory>::const_iterator i=factories.begin(); i!=factories.end(); ++i)
|
||||||
{
|
{
|
||||||
@ -217,3 +219,16 @@ void CZMQNotificationInterface::NotifyGovernanceObject(const CGovernanceObject &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CZMQNotificationInterface::NotifyInstantSendDoubleSpendAttempt(const CTransaction ¤tTx, const CTransaction &previousTx)
|
||||||
|
{
|
||||||
|
for (auto it = notifiers.begin(); it != notifiers.end();) {
|
||||||
|
CZMQAbstractNotifier *notifier = *it;
|
||||||
|
if (notifier->NotifyInstantSendDoubleSpendAttempt(currentTx, previousTx)) {
|
||||||
|
++it;
|
||||||
|
} else {
|
||||||
|
notifier->Shutdown();
|
||||||
|
it = notifiers.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -29,6 +29,7 @@ protected:
|
|||||||
void NotifyTransactionLock(const CTransaction &tx) override;
|
void NotifyTransactionLock(const CTransaction &tx) override;
|
||||||
void NotifyGovernanceVote(const CGovernanceVote& vote) override;
|
void NotifyGovernanceVote(const CGovernanceVote& vote) override;
|
||||||
void NotifyGovernanceObject(const CGovernanceObject& object) override;
|
void NotifyGovernanceObject(const CGovernanceObject& object) override;
|
||||||
|
void NotifyInstantSendDoubleSpendAttempt(const CTransaction ¤tTx, const CTransaction &previousTx) override;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -15,11 +15,13 @@ static const char *MSG_HASHTX = "hashtx";
|
|||||||
static const char *MSG_HASHTXLOCK = "hashtxlock";
|
static const char *MSG_HASHTXLOCK = "hashtxlock";
|
||||||
static const char *MSG_HASHGVOTE = "hashgovernancevote";
|
static const char *MSG_HASHGVOTE = "hashgovernancevote";
|
||||||
static const char *MSG_HASHGOBJ = "hashgovernanceobject";
|
static const char *MSG_HASHGOBJ = "hashgovernanceobject";
|
||||||
|
static const char *MSG_HASHISCON = "hashinstantsenddoublespend";
|
||||||
static const char *MSG_RAWBLOCK = "rawblock";
|
static const char *MSG_RAWBLOCK = "rawblock";
|
||||||
static const char *MSG_RAWTX = "rawtx";
|
static const char *MSG_RAWTX = "rawtx";
|
||||||
static const char *MSG_RAWTXLOCK = "rawtxlock";
|
static const char *MSG_RAWTXLOCK = "rawtxlock";
|
||||||
static const char *MSG_RAWGVOTE = "rawgovernancevote";
|
static const char *MSG_RAWGVOTE = "rawgovernancevote";
|
||||||
static const char *MSG_RAWGOBJ = "rawgovernanceobject";
|
static const char *MSG_RAWGOBJ = "rawgovernanceobject";
|
||||||
|
static const char *MSG_RAWISCON = "rawinstantsenddoublespend";
|
||||||
|
|
||||||
// Internal function to send multipart message
|
// Internal function to send multipart message
|
||||||
static int zmq_send_multipart(void *sock, const void* data, size_t size, ...)
|
static int zmq_send_multipart(void *sock, const void* data, size_t size, ...)
|
||||||
@ -197,6 +199,20 @@ bool CZMQPublishHashGovernanceObjectNotifier::NotifyGovernanceObject(const CGove
|
|||||||
return SendMessage(MSG_HASHGOBJ, data, 32);
|
return SendMessage(MSG_HASHGOBJ, data, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CZMQPublishHashInstantSendDoubleSpendNotifier::NotifyInstantSendDoubleSpendAttempt(const CTransaction ¤tTx, const CTransaction &previousTx)
|
||||||
|
{
|
||||||
|
uint256 currentHash = currentTx.GetHash(), previousHash = previousTx.GetHash();
|
||||||
|
LogPrint("zmq", "zmq: Publish hashinstantsenddoublespend %s conflicts against %s\n", currentHash.ToString(), previousHash.ToString());
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
return SendMessage(MSG_HASHISCON, dataCurrentHash, 32)
|
||||||
|
&& SendMessage(MSG_HASHISCON, dataPreviousHash, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
|
bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
|
||||||
{
|
{
|
||||||
LogPrint("zmq", "zmq: Publish rawblock %s\n", pindex->GetBlockHash().GetHex());
|
LogPrint("zmq", "zmq: Publish rawblock %s\n", pindex->GetBlockHash().GetHex());
|
||||||
@ -253,3 +269,13 @@ bool CZMQPublishRawGovernanceObjectNotifier::NotifyGovernanceObject(const CGover
|
|||||||
ss << govobj;
|
ss << govobj;
|
||||||
return SendMessage(MSG_RAWGOBJ, &(*ss.begin()), ss.size());
|
return SendMessage(MSG_RAWGOBJ, &(*ss.begin()), ss.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CZMQPublishRawInstantSendDoubleSpendNotifier::NotifyInstantSendDoubleSpendAttempt(const CTransaction ¤tTx, const CTransaction &previousTx)
|
||||||
|
{
|
||||||
|
LogPrint("zmq", "zmq: Publish rawinstantsenddoublespend %s conflicts with %s\n", currentTx.GetHash().ToString(), previousTx.GetHash().ToString());
|
||||||
|
CDataStream ssCurrent(SER_NETWORK, PROTOCOL_VERSION), ssPrevious(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
ssCurrent << currentTx;
|
||||||
|
ssPrevious << previousTx;
|
||||||
|
return SendMessage(MSG_RAWISCON, &(*ssCurrent.begin()), ssCurrent.size())
|
||||||
|
&& SendMessage(MSG_RAWISCON, &(*ssPrevious.begin()), ssPrevious.size());
|
||||||
|
}
|
||||||
|
@ -60,6 +60,12 @@ public:
|
|||||||
bool NotifyGovernanceObject(const CGovernanceObject &object) override;
|
bool NotifyGovernanceObject(const CGovernanceObject &object) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CZMQPublishHashInstantSendDoubleSpendNotifier : public CZMQAbstractPublishNotifier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool NotifyInstantSendDoubleSpendAttempt(const CTransaction ¤tTx, const CTransaction &previousTx) override;
|
||||||
|
};
|
||||||
|
|
||||||
class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier
|
class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -89,4 +95,10 @@ class CZMQPublishRawGovernanceObjectNotifier : public CZMQAbstractPublishNotifie
|
|||||||
public:
|
public:
|
||||||
bool NotifyGovernanceObject(const CGovernanceObject &object) override;
|
bool NotifyGovernanceObject(const CGovernanceObject &object) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CZMQPublishRawInstantSendDoubleSpendNotifier : public CZMQAbstractPublishNotifier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool NotifyInstantSendDoubleSpendAttempt(const CTransaction ¤tTx, const CTransaction &previousTx) override;
|
||||||
|
};
|
||||||
#endif // BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H
|
#endif // BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H
|
||||||
|
Loading…
Reference in New Issue
Block a user