Skip to content

Commit 89f6f75

Browse files
authored
Implement zmq notifications for chainlocked blocks (#2899)
* Unify zmq message order * Implement `zmqpubhashchainlock` and `zmqpubrawchainlock`
1 parent 66a2cde commit 89f6f75

File tree

9 files changed

+128
-39
lines changed

9 files changed

+128
-39
lines changed

contrib/zmq/zmq_sub.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,14 @@ def __init__(self):
4343

4444
self.zmqSubSocket = self.zmqContext.socket(zmq.SUB)
4545
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashblock")
46+
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashchainlock")
4647
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtx")
4748
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtxlock")
4849
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashgovernancevote")
4950
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashgovernanceobject")
5051
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashinstantsenddoublespend")
5152
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawblock")
53+
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawchainlock")
5254
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtx")
5355
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtxlock")
5456
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawgovernancevote")
@@ -69,38 +71,44 @@ async def handle(self) :
6971
if topic == b"hashblock":
7072
print('- HASH BLOCK ('+sequence+') -')
7173
print(binascii.hexlify(body).decode("utf-8"))
74+
elif topic == b"hashchainlock":
75+
print('- HASH CHAINLOCK ('+sequence+') -')
76+
print(binascii.hexlify(body).decode("utf-8"))
7277
elif topic == b"hashtx":
7378
print ('- HASH TX ('+sequence+') -')
7479
print(binascii.hexlify(body).decode("utf-8"))
7580
elif topic == b"hashtxlock":
7681
print('- HASH TX LOCK ('+sequence+') -')
7782
print(binascii.hexlify(body).decode("utf-8"))
83+
elif topic == b"hashgovernancevote":
84+
print('- HASH GOVERNANCE VOTE ('+sequence+') -')
85+
print(binascii.hexlify(body).decode("utf-8"))
86+
elif topic == b"hashgovernanceobject":
87+
print('- HASH GOVERNANCE OBJECT ('+sequence+') -')
88+
print(binascii.hexlify(body).decode("utf-8"))
89+
elif topic == b"hashinstantsenddoublespend":
90+
print('- HASH IS DOUBLE SPEND ('+sequence+') -')
91+
print(binascii.hexlify(body).decode("utf-8"))
7892
elif topic == b"rawblock":
7993
print('- RAW BLOCK HEADER ('+sequence+') -')
8094
print(binascii.hexlify(body[:80]).decode("utf-8"))
95+
elif topic == b"rawchainlock":
96+
print('- RAW CHAINLOCK ('+sequence+') -')
97+
print(binascii.hexlify(body[:80]).decode("utf-8"))
8198
elif topic == b"rawtx":
8299
print('- RAW TX ('+sequence+') -')
83100
print(binascii.hexlify(body).decode("utf-8"))
84101
elif topic == b"rawtxlock":
85102
print('- RAW TX LOCK ('+sequence+') -')
86103
print(binascii.hexlify(body).decode("utf-8"))
87-
elif topic == b"rawinstantsenddoublespend":
88-
print('- RAW IS DOUBLE SPEND ('+sequence+') -')
89-
print(binascii.hexlify(body).decode("utf-8"))
90-
elif topic == b"hashgovernancevote":
91-
print('- HASH GOVERNANCE VOTE ('+sequence+') -')
92-
print(binascii.hexlify(body).decode("utf-8"))
93-
elif topic == b"hashgovernanceobject":
94-
print('- HASH GOVERNANCE OBJECT ('+sequence+') -')
95-
print(binascii.hexlify(body).decode("utf-8"))
96104
elif topic == b"rawgovernancevote":
97105
print('- RAW GOVERNANCE VOTE ('+sequence+') -')
98106
print(binascii.hexlify(body).decode("utf-8"))
99107
elif topic == b"rawgovernanceobject":
100108
print('- RAW GOVERNANCE OBJECT ('+sequence+') -')
101109
print(binascii.hexlify(body).decode("utf-8"))
102-
elif topic == b"hashinstantsenddoublespend":
103-
print('- HASH IS DOUBLE SPEND ('+sequence+') -')
110+
elif topic == b"rawinstantsenddoublespend":
111+
print('- RAW IS DOUBLE SPEND ('+sequence+') -')
104112
print(binascii.hexlify(body).decode("utf-8"))
105113
# schedule ourselves to receive the next message
106114
asyncio.ensure_future(self.handle())

contrib/zmq/zmq_sub3.4.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,14 @@ def __init__(self):
4747

4848
self.zmqSubSocket = self.zmqContext.socket(zmq.SUB)
4949
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashblock")
50+
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashchainlock")
5051
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtx")
5152
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtxlock")
5253
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashgovernancevote")
5354
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashgovernanceobject")
5455
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashinstantsenddoublespend")
5556
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawblock")
57+
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawchainlock")
5658
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtx")
5759
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtxlock")
5860
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawgovernancevote")
@@ -72,38 +74,44 @@ def handle(self) :
7274
if topic == b"hashblock":
7375
print('- HASH BLOCK ('+sequence+') -')
7476
print(binascii.hexlify(body).decode("utf-8"))
77+
elif topic == b"hashchainlock":
78+
print('- HASH CHAINLOCK ('+sequence+') -')
79+
print(binascii.hexlify(body).decode("utf-8"))
7580
elif topic == b"hashtx":
7681
print ('- HASH TX ('+sequence+') -')
7782
print(binascii.hexlify(body).decode("utf-8"))
7883
elif topic == b"hashtxlock":
7984
print('- HASH TX LOCK ('+sequence+') -')
8085
print(binascii.hexlify(body).decode("utf-8"))
86+
elif topic == b"hashgovernancevote":
87+
print('- HASH GOVERNANCE VOTE ('+sequence+') -')
88+
print(binascii.hexlify(body).decode("utf-8"))
89+
elif topic == b"hashgovernanceobject":
90+
print('- HASH GOVERNANCE OBJECT ('+sequence+') -')
91+
print(binascii.hexlify(body).decode("utf-8"))
92+
elif topic == b"hashinstantsenddoublespend":
93+
print('- HASH IS DOUBLE SPEND ('+sequence+') -')
94+
print(binascii.hexlify(body).decode("utf-8"))
8195
elif topic == b"rawblock":
8296
print('- RAW BLOCK HEADER ('+sequence+') -')
8397
print(binascii.hexlify(body[:80]).decode("utf-8"))
98+
elif topic == b"rawchainlock":
99+
print('- RAW CHAINLOCK ('+sequence+') -')
100+
print(binascii.hexlify(body[:80]).decode("utf-8"))
84101
elif topic == b"rawtx":
85102
print('- RAW TX ('+sequence+') -')
86103
print(binascii.hexlify(body).decode("utf-8"))
87104
elif topic == b"rawtxlock":
88105
print('- RAW TX LOCK ('+sequence+') -')
89106
print(binascii.hexlify(body).decode("utf-8"))
90-
elif topic == b"rawinstantsenddoublespend":
91-
print('- RAW IS DOUBLE SPEND ('+sequence+') -')
92-
print(binascii.hexlify(body).decode("utf-8"))
93-
elif topic == b"hashgovernancevote":
94-
print('- HASH GOVERNANCE VOTE ('+sequence+') -')
95-
print(binascii.hexlify(body).decode("utf-8"))
96-
elif topic == b"hashgovernanceobject":
97-
print('- HASH GOVERNANCE OBJECT ('+sequence+') -')
98-
print(binascii.hexlify(body).decode("utf-8"))
99107
elif topic == b"rawgovernancevote":
100108
print('- RAW GOVERNANCE VOTE ('+sequence+') -')
101109
print(binascii.hexlify(body).decode("utf-8"))
102110
elif topic == b"rawgovernanceobject":
103111
print('- RAW GOVERNANCE OBJECT ('+sequence+') -')
104112
print(binascii.hexlify(body).decode("utf-8"))
105-
elif topic == b"hashinstantsenddoublespend":
106-
print('- HASH IS DOUBLE SPEND ('+sequence+') -')
113+
elif topic == b"rawinstantsenddoublespend":
114+
print('- RAW IS DOUBLE SPEND ('+sequence+') -')
107115
print(binascii.hexlify(body).decode("utf-8"))
108116
# schedule ourselves to receive the next message
109117
asyncio.ensure_future(self.handle())

doc/zmq.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,20 @@ the command line or in the configuration file.
5656

5757
Currently, the following notifications are supported:
5858

59+
-zmqpubhashblock=address
60+
-zmqpubhashchainlock=address
5961
-zmqpubhashtx=address
6062
-zmqpubhashtxlock=address
61-
-zmqpubhashblock=address
63+
-zmqpubhashgovernancevote=address
64+
-zmqpubhashgovernanceobject=address
65+
-zmqpubhashinstantsenddoublespend=address
6266
-zmqpubrawblock=address
67+
-zmqpubrawchainlock=address
6368
-zmqpubrawtx=address
6469
-zmqpubrawtxlock=address
65-
-zmqpubhashgovernancevote=address
66-
-zmqpubhashgovernanceobject=address
6770
-zmqpubrawgovernancevote=address
68-
-zmqpubhashgovernanceobject=address
71+
-zmqpubrawgovernanceobject=address
6972
-zmqpubrawinstantsenddoublespend=address
70-
-zmqpubhashinstantsenddoublespend=address
7173

7274
The socket type is PUB and the address must be a valid ZeroMQ socket
7375
address. The same address can be used in more than one notification.

src/zmq/zmqabstractnotifier.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ bool CZMQAbstractNotifier::NotifyBlock(const CBlockIndex * /*CBlockIndex*/)
1616
return true;
1717
}
1818

19+
bool CZMQAbstractNotifier::NotifyChainLock(const CBlockIndex * /*CBlockIndex*/)
20+
{
21+
return true;
22+
}
23+
1924
bool CZMQAbstractNotifier::NotifyTransaction(const CTransaction &/*transaction*/)
2025
{
2126
return true;

src/zmq/zmqabstractnotifier.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class CZMQAbstractNotifier
3535
virtual void Shutdown() = 0;
3636

3737
virtual bool NotifyBlock(const CBlockIndex *pindex);
38+
virtual bool NotifyChainLock(const CBlockIndex *pindex);
3839
virtual bool NotifyTransaction(const CTransaction &transaction);
3940
virtual bool NotifyTransactionLock(const CTransaction &transaction);
4041
virtual bool NotifyGovernanceVote(const CGovernanceVote &vote);

src/zmq/zmqnotificationinterface.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,14 @@ CZMQNotificationInterface* CZMQNotificationInterface::Create()
3636
std::list<CZMQAbstractNotifier*> notifiers;
3737

3838
factories["pubhashblock"] = CZMQAbstractNotifier::Create<CZMQPublishHashBlockNotifier>;
39+
factories["pubhashchainlock"] = CZMQAbstractNotifier::Create<CZMQPublishHashChainLockNotifier>;
3940
factories["pubhashtx"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionNotifier>;
4041
factories["pubhashtxlock"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionLockNotifier>;
4142
factories["pubhashgovernancevote"] = CZMQAbstractNotifier::Create<CZMQPublishHashGovernanceVoteNotifier>;
4243
factories["pubhashgovernanceobject"] = CZMQAbstractNotifier::Create<CZMQPublishHashGovernanceObjectNotifier>;
4344
factories["pubhashinstantsenddoublespend"] = CZMQAbstractNotifier::Create<CZMQPublishHashInstantSendDoubleSpendNotifier>;
4445
factories["pubrawblock"] = CZMQAbstractNotifier::Create<CZMQPublishRawBlockNotifier>;
46+
factories["pubrawchainlock"] = CZMQAbstractNotifier::Create<CZMQPublishRawChainLockNotifier>;
4547
factories["pubrawtx"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionNotifier>;
4648
factories["pubrawtxlock"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionLockNotifier>;
4749
factories["pubrawgovernancevote"] = CZMQAbstractNotifier::Create<CZMQPublishRawGovernanceVoteNotifier>;
@@ -152,6 +154,23 @@ void CZMQNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, co
152154
}
153155
}
154156

157+
void CZMQNotificationInterface::NotifyChainLock(const CBlockIndex *pindex)
158+
{
159+
for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); )
160+
{
161+
CZMQAbstractNotifier *notifier = *i;
162+
if (notifier->NotifyChainLock(pindex))
163+
{
164+
i++;
165+
}
166+
else
167+
{
168+
notifier->Shutdown();
169+
i = notifiers.erase(i);
170+
}
171+
}
172+
}
173+
155174
void CZMQNotificationInterface::SyncTransaction(const CTransaction& tx, const CBlockIndex* pindex, int posInBlock)
156175
{
157176
for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); )

src/zmq/zmqnotificationinterface.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class CZMQNotificationInterface : public CValidationInterface
2626
// CValidationInterface
2727
void SyncTransaction(const CTransaction& tx, const CBlockIndex *pindex, int posInBlock) override;
2828
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override;
29+
void NotifyChainLock(const CBlockIndex *pindex) override;
2930
void NotifyTransactionLock(const CTransaction &tx) override;
3031
void NotifyGovernanceVote(const CGovernanceVote& vote) override;
3132
void NotifyGovernanceObject(const CGovernanceObject& object) override;

src/zmq/zmqpublishnotifier.cpp

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,20 @@
1010

1111
static std::multimap<std::string, CZMQAbstractPublishNotifier*> mapPublishNotifiers;
1212

13-
static const char *MSG_HASHBLOCK = "hashblock";
14-
static const char *MSG_HASHTX = "hashtx";
15-
static const char *MSG_HASHTXLOCK = "hashtxlock";
16-
static const char *MSG_HASHGVOTE = "hashgovernancevote";
17-
static const char *MSG_HASHGOBJ = "hashgovernanceobject";
18-
static const char *MSG_HASHISCON = "hashinstantsenddoublespend";
19-
static const char *MSG_RAWBLOCK = "rawblock";
20-
static const char *MSG_RAWTX = "rawtx";
21-
static const char *MSG_RAWTXLOCK = "rawtxlock";
22-
static const char *MSG_RAWGVOTE = "rawgovernancevote";
23-
static const char *MSG_RAWGOBJ = "rawgovernanceobject";
24-
static const char *MSG_RAWISCON = "rawinstantsenddoublespend";
13+
static const char *MSG_HASHBLOCK = "hashblock";
14+
static const char *MSG_HASHCHAINLOCK = "hashchainlock";
15+
static const char *MSG_HASHTX = "hashtx";
16+
static const char *MSG_HASHTXLOCK = "hashtxlock";
17+
static const char *MSG_HASHGVOTE = "hashgovernancevote";
18+
static const char *MSG_HASHGOBJ = "hashgovernanceobject";
19+
static const char *MSG_HASHISCON = "hashinstantsenddoublespend";
20+
static const char *MSG_RAWBLOCK = "rawblock";
21+
static const char *MSG_RAWCHAINLOCK = "rawchainlock";
22+
static const char *MSG_RAWTX = "rawtx";
23+
static const char *MSG_RAWTXLOCK = "rawtxlock";
24+
static const char *MSG_RAWGVOTE = "rawgovernancevote";
25+
static const char *MSG_RAWGOBJ = "rawgovernanceobject";
26+
static const char *MSG_RAWISCON = "rawinstantsenddoublespend";
2527

2628
// Internal function to send multipart message
2729
static int zmq_send_multipart(void *sock, const void* data, size_t size, ...)
@@ -159,6 +161,16 @@ bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
159161
return SendMessage(MSG_HASHBLOCK, data, 32);
160162
}
161163

164+
bool CZMQPublishHashChainLockNotifier::NotifyChainLock(const CBlockIndex *pindex)
165+
{
166+
uint256 hash = pindex->GetBlockHash();
167+
LogPrint("zmq", "zmq: Publish hashchainlock %s\n", hash.GetHex());
168+
char data[32];
169+
for (unsigned int i = 0; i < 32; i++)
170+
data[31 - i] = hash.begin()[i];
171+
return SendMessage(MSG_HASHCHAINLOCK, data, 32);
172+
}
173+
162174
bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction)
163175
{
164176
uint256 hash = transaction.GetHash();
@@ -234,6 +246,27 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
234246
return SendMessage(MSG_RAWBLOCK, &(*ss.begin()), ss.size());
235247
}
236248

249+
bool CZMQPublishRawChainLockNotifier::NotifyChainLock(const CBlockIndex *pindex)
250+
{
251+
LogPrint("zmq", "zmq: Publish rawchainlock %s\n", pindex->GetBlockHash().GetHex());
252+
253+
const Consensus::Params& consensusParams = Params().GetConsensus();
254+
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
255+
{
256+
LOCK(cs_main);
257+
CBlock block;
258+
if(!ReadBlockFromDisk(block, pindex, consensusParams))
259+
{
260+
zmqError("Can't read block from disk");
261+
return false;
262+
}
263+
264+
ss << block;
265+
}
266+
267+
return SendMessage(MSG_RAWCHAINLOCK, &(*ss.begin()), ss.size());
268+
}
269+
237270
bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction)
238271
{
239272
uint256 hash = transaction.GetHash();

src/zmq/zmqpublishnotifier.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ class CZMQPublishHashBlockNotifier : public CZMQAbstractPublishNotifier
3636
bool NotifyBlock(const CBlockIndex *pindex) override;
3737
};
3838

39+
class CZMQPublishHashChainLockNotifier : public CZMQAbstractPublishNotifier
40+
{
41+
public:
42+
bool NotifyChainLock(const CBlockIndex *pindex) override;
43+
};
44+
3945
class CZMQPublishHashTransactionNotifier : public CZMQAbstractPublishNotifier
4046
{
4147
public:
@@ -72,6 +78,12 @@ class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier
7278
bool NotifyBlock(const CBlockIndex *pindex) override;
7379
};
7480

81+
class CZMQPublishRawChainLockNotifier : public CZMQAbstractPublishNotifier
82+
{
83+
public:
84+
bool NotifyChainLock(const CBlockIndex *pindex) override;
85+
};
86+
7587
class CZMQPublishRawTransactionNotifier : public CZMQAbstractPublishNotifier
7688
{
7789
public:

0 commit comments

Comments
 (0)