Skip to content

Commit bbb3cef

Browse files
committed
translate zmq
1 parent 20d8c9a commit bbb3cef

File tree

1 file changed

+234
-0
lines changed

1 file changed

+234
-0
lines changed

docs/nodes/usage/zmq.md

+234
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,238 @@
11
---
22
sidebar_position: 3
33
---
4+
45
# ZMQ Instructions
6+
7+
Introducing How to Use ZMQ Functionality and How to Configure It
8+
9+
## Introduction to ZMQ
10+
11+
ZeroMQ is a lightweight messaging queue solution that provides publish-subscribe services via TCP links, inter-process
12+
communication (IPC), and shared memory. ZeroMQ is known for being lightweight, high-performance, low-latency, supporting
13+
multiple languages, multiple operating systems, and various messaging patterns.
14+
15+
While the node P2P protocol in MVC can itself serve as a trusted messaging propagation route to facilitate communication
16+
within the MVC network, make consensus decisions, broadcast transactions, etc., in some scenarios, a more flexible
17+
messaging queue solution is needed. Applications that need to listen for events like mempool transactions and new blocks
18+
require real-time and high availability, which are more cumbersome to implement via the P2P protocol and not as
19+
user-friendly for clients.
20+
21+
Therefore, we have introduced ZeroMQ as a messaging queue solution to provide more flexible messaging services. ZeroMQ
22+
allows for real-time notifications by subscribing to events of interest, such as listening for new blocks and mempool
23+
transactions.
24+
25+
## Features of MVC Node ZMQ Push
26+
27+
The ZeroMQ functionality implements a specific set of notification interfaces, primarily including notifiers for new
28+
blocks and new transactions. Node ZMQ is read-only, requiring only connection to the corresponding ZeroMQ subscription
29+
port in the receiving software; it does not perform authentication nor does it involve bidirectional protocols.
30+
Therefore, subscribers should verify the received data (e.g., using merkle proofs, making secondary node RPC
31+
verifications, etc.), as this data might be outdated, incomplete, or even invalid.
32+
33+
ZeroMQ sockets are self-connecting and self-healing; that is, the connection between two endpoints will automatically
34+
resume after an interruption, and either end can freely start or stop in any order.
35+
36+
Additionally, because ZeroMQ is message-oriented, the transactions and blocks received by subscribers are one-time
37+
occurrences and do not require any buffering or reassembly.
38+
39+
## Enabling ZMQ Functionality When Building the Node
40+
41+
When compiling the node, you can specify whether to enable ZMQ functionality. If you need to enable ZMQ, you will need
42+
to install the libzmq3-dev dependency library on the build machine. The official default binary package already includes
43+
support for ZMQ. If you are compiling the node yourself and wish to include ZMQ functionality, you can refer to the
44+
following compile option:
45+
46+
```bash
47+
$ ./configure --disable-zmq (other options)
48+
```
49+
50+
If you are using the default binary package, no additional steps are necessary; you can start the node directly as the
51+
ZMQ functionality is already installed in the node.
52+
53+
## ZMQ Configuration
54+
55+
ZMQ functionality needs to be configured in the node's configuration file. You can freely choose the port number and the
56+
types of events to subscribe to. Configure the following in the mvc.conf file (refer to the ZMQ-related content
57+
in [Startup Options](../installation/start-up-command.md)):
58+
59+
```text
60+
61+
-zmqpubhashtx=address
62+
-zmqpubhashblock=address
63+
-zmqpubrawblock=address
64+
-zmqpubrawtx=address
65+
-zmqpubinvalidtx=address
66+
-zmqpubdiscardedfrommempool=address
67+
-zmqpubremovedfrommempoolblock=address
68+
69+
-zmqpubhashtx2=address
70+
-zmqpubhashblock2=address
71+
-zmqpubrawblock2=address
72+
-zmqpubrawtx2=address
73+
74+
```
75+
76+
The socket type is PUB, and the address starts with "tcp://" or "ipc://". If you do not need notifications for a
77+
particular event, you do not need to configure an address for that event. The same address can be used to listen to
78+
multiple channels. For example:
79+
80+
```bash
81+
$ mvcd -zmqpubhashtx=tcp://0.0.0.0:29882 -zmqpubhashblock=0.0.0.0:29882 -zmqpubrawtx=ipc:///tmp/mvcd.tx.raw
82+
```
83+
84+
Similarly, these configurations can also be set in the mvc.conf file, such as:
85+
86+
```text
87+
zmqpubhashtx=tcp://0.0.0.0:29882
88+
zmqpubhashblock=tcp://0.0.0.0:29882
89+
zmqpubrawtx=ipc:///tmp/mvcd.tx.raw
90+
```
91+
92+
Each PUB notification comes with a topic and a message body, with the notification type included in the message header.
93+
For example, the ***zmqpubhashtx*** notification's topic is "hashtx," and the message body is the transaction hash. The
94+
message body is a 32-byte hexadecimal string, which can be obtained in detail via the node's RPC interface.
95+
96+
Meanwhile, the topics for ***zmqpubdiscardedfrommempool*** and ***zmqpubremovedfrommempoolblock*** notifications are "
97+
discardedfrommempool" and "removedfrommempoolblock," respectively, and their message bodies are JSON strings:
98+
99+
```json
100+
{
101+
"txid": "hexstring",
102+
"reason": "string",
103+
"collidedWith": {
104+
"txid": "hexstring",
105+
"size": 100,
106+
"hex": "hexstring"
107+
},
108+
"blockhash": "hexstring"
109+
}
110+
```
111+
112+
The `collidedWith` field indicates which transaction this transaction conflicted with, and the `blockhash` field
113+
indicates which block this transaction was included in.
114+
115+
The `reason` field in ***zmqpubdiscardedfrommempool*** indicates why this transaction was discarded, with reasons
116+
including:
117+
118+
* expired
119+
* mempool-sizelimit-exceeded
120+
* collision-in-block-tx
121+
122+
The `reason` field in ***zmqpubremovedfrommempoolblock*** indicates why this transaction was removed from the mempool,
123+
with reasons including:
124+
125+
* reorg
126+
* included-in-block
127+
128+
***zmqpub2***
129+
(such as zmqpubhashtx2 and other suffixes ending with 2) functions similarly to their non-suffix counterparts, the only
130+
difference being that they no longer push duplicate messages. For example, the original zmqpubhashtx would push messages
131+
twice, both when entering the mempool and when being packaged into a block, whereas zmqpubhashtx2 pushes only once.
132+
Additionally, in the event of a reorganization, the entire reorganization chain is pushed, not just the tip.
133+
134+
## Remarks
135+
136+
From the perspective of `mvcd`, ZeroMQ sockets are write-only; PUB sockets do not even have a read function. Therefore,
137+
they do not directly introduce any state into MVC. Additionally, MVC does not broadcast any information that has not
138+
been received from the public P2P network.
139+
140+
When connecting clients, no authentication or authorization is performed; thus, it is crucial to ensure that the ZeroMQ
141+
ports are open only to trusted networks and are protected by firewalls or other means.
142+
143+
Please note that reorganizations can occur when the highest point of the blockchain changes, and only the highest point
144+
will be notified. Subscribers need to retrieve from the last known block to the new highest point.
145+
146+
Depending on the type of communication used, ZMQ notifications may be lost during transmission. MVC includes an
147+
incrementing sequence number in each notification, allowing listeners to detect missing notifications.
148+
149+
## Practice: Using a ZMQ Client to Listen for ZMQ Events
150+
151+
This example uses Python to demonstrate how to use a ZMQ client to listen for ZMQ events.
152+
153+
Ensure that your local system has installed the ZMQ and Python libraries and that the ZMQ port is open.
154+
155+
Install Python3 and related dependencies:
156+
157+
```bash
158+
sudo apt update
159+
sudo apt install python3
160+
sudo apt install python3-pip
161+
sudo apt install libzmq3-dev python3-zmq
162+
pip3 install pyzmq
163+
```
164+
165+
Create the following Python file ***zmq_subscriber.py***. The code below listens to the local ZMQ port, listens to the
166+
hashtx channel, and prints the data received:
167+
168+
```python
169+
# File: zmq_subscriber.py
170+
import zmq
171+
172+
# Prepare our context and subscriber socket
173+
context = zmq.Context()
174+
socket = context.socket(zmq.SUB)
175+
176+
# Connect to the publisher's socket
177+
# Adjust the address and port accordingly
178+
socket.connect("tcp://localhost:28332")
179+
180+
# Subscribe to all messages
181+
socket.setsockopt_string(zmq.SUBSCRIBE, 'hashtx')
182+
183+
# Receive messages as bytes
184+
while True:
185+
message = socket.recv() # Use recv instead of recv_string
186+
try:
187+
# Attempt to decode as UTF-8, or handle as binary data
188+
print("Received:", message.decode('utf-8'))
189+
except UnicodeDecodeError:
190+
hex_message = message.hex() # Convert bytes to hex string
191+
print("Received:", hex_message)
192+
```
193+
194+
If the program is correctly configured and running successfully, you will see the following output:
195+
196+
```bash
197+
Received: hashtx
198+
Received: 679b984049c2b8aeff04291f32415b9346429867e6ae69b4b9569b52fa85ea42
199+
Received: 3fab0700
200+
Received: hashtx
201+
Received: fbe397992b8ce963792a65c91aa9a32c8afb836e15b464ecf7fffd8af450baa9
202+
Received: 40ab0700
203+
Received: hashtx
204+
Received: f2153a5a34707f57c21f6c3dc335a30c095be59a53ed5cd0df0af0383d2677db
205+
Received: 41ab0700
206+
Received: hashtx
207+
Received: 365ec39e879ccf6b70a64432064a98f782b1998cd26dccc0ad630b503e95edb6
208+
Received: 42ab0700
209+
Received: hashtx
210+
Received: 94dda55fc6fe14c05bdb31feead994d6dd9bbec6ea5b95842dadfe9d490f8841
211+
Received: 43ab0700
212+
Received: hashtx
213+
Received: b3cfde1630610903c17a73bb871c008c3f3cc7bcdbeed2185f55ec3a96901ef9
214+
Received: 44ab0700
215+
Received: hashtx
216+
Received: fb1937d2fe7f1b5bc0252acb88bde3123fdc32800f385562c02ed3bbb5f7fd3b
217+
Received: 45ab0700
218+
Received: hashtx
219+
Received: 03123d1aa0f40965eecede4c1dd7531df7dfc87c55ac06264b0d7c90203acdc7
220+
Received: 46ab0700
221+
Received: hashtx
222+
Received: 0b8ddf99ea66f522319f8f8e7aa6c439b44c3b1fff79a41c58356447a7283654
223+
Received: 47ab0700
224+
Received: hashtx
225+
Received: bae9ca06c4fa9dc50756aded981d36d78f301e9e80b14e6031464c36e4a8d28b
226+
Received: 48ab0700
227+
Received: hashtx
228+
Received: 5f4b4d0ff3c595188041c2a1abc00612aad3151ed845c62a9fb41a71214f4ad5
229+
Received: 49ab0700
230+
Received: hashtx
231+
Received: 078f211de0a24a37379199fdda9bdc54323e798899edfadcfeacb834fa2a54c0
232+
Received: 4aab0700
233+
```
234+
235+
The message includes messages from the hashtx channel, the message body, and the transaction hash (real transaction, can
236+
be confirmed on-chain), as well as an additional continuous sequence to detect missing messages. You can also set up to
237+
listen to other channels and print output for debugging.
238+

0 commit comments

Comments
 (0)