Skip to content

Commit 7a93544

Browse files
committed
doc: Fix and clarify description of ZMQ message format
This change stresses that all ZMQ messages share the same structure and that they differ only in the format of the bodies. Previously this was not clear. Further it removes the notion of endianness of 32-byte hashes, as it was misleading, and replaces it with the term 'reversed byte order' (as opposed to natural or normal byte order produced by hashing functions). Additionally, it states that ZMQ 32-byte hashes are in the same format as in RPC. Previously it incorrectly stated that the two were in different formats.
1 parent 2549fc6 commit 7a93544

File tree

1 file changed

+50
-21
lines changed

1 file changed

+50
-21
lines changed

doc/zmq.md

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -87,40 +87,69 @@ For instance:
8787
-zmqpubrawtx=ipc:///tmp/bitcoind.tx.raw \
8888
-zmqpubhashtxhwm=10000
8989

90-
Each PUB notification has a topic and body, where the header
91-
corresponds to the notification type. For instance, for the
92-
notification `-zmqpubhashtx` the topic is `hashtx` (no null
93-
terminator). These options can also be provided in bitcoin.conf.
90+
Notification types correspond to message topics (details in next section). For instance,
91+
for the notification `-zmqpubhashtx` the topic is `hashtx`. These options can also be
92+
provided in bitcoin.conf.
9493

95-
The topics are:
94+
### Message format
9695

97-
`sequence`: the body is structured as the following based on the type of message:
96+
All ZMQ messages share the same structure with three parts: _topic_ string,
97+
message _body_, and _message sequence number_:
9898

99-
<32-byte hash>C : Blockhash connected
100-
<32-byte hash>D : Blockhash disconnected
101-
<32-byte hash>R<8-byte LE uint> : Transactionhash removed from mempool for non-block inclusion reason
102-
<32-byte hash>A<8-byte LE uint> : Transactionhash added mempool
99+
| topic | body | message sequence number |
100+
|-----------+------------------------------------------------------+--------------------------|
101+
| rawtx | <serialized transaction> | <4-byte LE uint> |
102+
| hashtx | <reversed 32-byte transaction hash> | <4-byte LE uint> |
103+
| rawblock | <serialized block> | <4-byte LE uint> |
104+
| hashblock | <reversed 32-byte block hash> | <4-byte LE uint> |
105+
| sequence | <reversed 32-byte block hash>C | <4-byte LE uint> |
106+
| sequence | <reversed 32-byte block hash>D | <4-byte LE uint> |
107+
| sequence | <reversed 32-byte transaction hash>R<8-byte LE uint> | <4-byte LE uint> |
108+
| sequence | <reversed 32-byte transaction hash>A<8-byte LE uint> | <4-byte LE uint> |
103109

104-
Where the 8-byte uints correspond to the mempool sequence number.
110+
where:
105111

106-
`rawtx`: Notifies about all transactions, both when they are added to mempool or when a new block arrives. This means a transaction could be published multiple times. First, when it enters the mempool and then again in each block that includes it. The messages are ZMQ multipart messages with three parts. The first part is the topic (`rawtx`), the second part is the serialized transaction, and the last part is a sequence number (representing the message count to detect lost messages).
112+
- message sequence number represents message count to detect lost messages, distinct for each topic
113+
- all transaction and block hashes are in _reversed byte order_ (i. e. with bytes
114+
produced by hashing function reversed), the same format as the RPC interface and block
115+
explorers use to display transaction and block hashes
107116

108-
| rawtx | <serialized transaction> | <uint32 sequence number in Little Endian>
117+
#### rawtx
109118

110-
`hashtx`: Notifies about all transactions, both when they are added to mempool or when a new block arrives. This means a transaction could be published multiple times. First, when it enters the mempool and then again in each block that includes it. The messages are ZMQ multipart messages with three parts. The first part is the topic (`hashtx`), the second part is the 32-byte transaction hash, and the last part is a sequence number (representing the message count to detect lost messages).
119+
Notifies about all transactions, both when they are added to mempool or when a new block
120+
arrives. This means a transaction could be published multiple times: first when it enters
121+
mempool and then again in each block that includes it. The body part of the message is the
122+
serialized transaction.
111123

112-
| hashtx | <32-byte transaction hash in Little Endian> | <uint32 sequence number in Little Endian>
124+
#### hashtx
113125

126+
Notifies about all transactions, both when they are added to mempool or when a new block
127+
arrives. This means a transaction could be published multiple times: first when it enters
128+
mempool and then again in each block that includes it. The body part of the mesage is the
129+
32-byte transaction hash in reversed byte order.
114130

115-
`rawblock`: Notifies when the chain tip is updated. When assumeutxo is in use, this notification will not be issued for historical blocks connected to the background validation chainstate. Messages are ZMQ multipart messages with three parts. The first part is the topic (`rawblock`), the second part is the serialized block, and the last part is a sequence number (representing the message count to detect lost messages).
131+
#### rawblock
116132

117-
| rawblock | <serialized block> | <uint32 sequence number in Little Endian>
133+
Notifies when the chain tip is updated. When assumeutxo is in use, this notification will
134+
not be issued for historical blocks connected to the background validation chainstate. The
135+
body part of the message is the serialized block.
118136

119-
`hashblock`: Notifies when the chain tip is updated. When assumeutxo is in use, this notification will not be issued for historical blocks connected to the background validation chainstate. Messages are ZMQ multipart messages with three parts. The first part is the topic (`hashblock`), the second part is the 32-byte block hash, and the last part is a sequence number (representing the message count to detect lost messages).
137+
#### hashblock
120138

121-
| hashblock | <32-byte block hash in Little Endian> | <uint32 sequence number in Little Endian>
139+
Notifies when the chain tip is updated. When assumeutxo is in use, this notification will
140+
not be issued for historical blocks connected to the background validation chainstate. The
141+
body part of the message is the 32-byte block hash in reversed byte order.
122142

123-
**_NOTE:_** Note that the 32-byte hashes are in Little Endian and not in the Big Endian format that the RPC interface and block explorers use to display transaction and block hashes.
143+
#### sequence
144+
145+
The 8-byte LE uints correspond to _mempool sequence number_ and the types of bodies are:
146+
147+
- `C` : block with this hash connected
148+
- `D` : block with this hash disconnected
149+
- `R` : transaction with this hash removed from mempool for non-block inclusion reason
150+
- `A` : transaction with this hash added to mempool
151+
152+
### Implementing ZMQ client
124153

125154
ZeroMQ endpoint specifiers for TCP (and others) are documented in the
126155
[ZeroMQ API](http://api.zeromq.org/4-0:_start).
@@ -138,7 +167,7 @@ operating system configuration and must be configured prior to connection establ
138167
For example, when running on GNU/Linux, one might use the following
139168
to lower the keepalive setting to 10 minutes:
140169

141-
sudo sysctl -w net.ipv4.tcp_keepalive_time=600
170+
sudo sysctl -w net.ipv4.tcp_keepalive_time=600
142171

143172
Setting the keepalive values appropriately for your operating environment may
144173
improve connectivity in situations where long-lived connections are silently

0 commit comments

Comments
 (0)