mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-01 09:35:52 -05:00
Update zmq notification documentation and sample consumer
This commit is contained in:
parent
68c3c7e1bd
commit
759d94e70f
2 changed files with 35 additions and 13 deletions
|
@ -11,7 +11,8 @@
|
|||
-zmqpubrawtx=tcp://127.0.0.1:28332 \
|
||||
-zmqpubrawblock=tcp://127.0.0.1:28332 \
|
||||
-zmqpubhashtx=tcp://127.0.0.1:28332 \
|
||||
-zmqpubhashblock=tcp://127.0.0.1:28332
|
||||
-zmqpubhashblock=tcp://127.0.0.1:28332 \
|
||||
-zmqpubsequence=tcp://127.0.0.1:28332
|
||||
|
||||
We use the asyncio library here. `self.handle()` installs itself as a
|
||||
future at the end of the function. Since it never returns with the event
|
||||
|
@ -47,16 +48,14 @@ class ZMQHandler():
|
|||
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtx")
|
||||
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawblock")
|
||||
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtx")
|
||||
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "sequence")
|
||||
self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % port)
|
||||
|
||||
async def handle(self) :
|
||||
msg = await self.zmqSubSocket.recv_multipart()
|
||||
topic = msg[0]
|
||||
body = msg[1]
|
||||
topic, body, seq = await self.zmqSubSocket.recv_multipart()
|
||||
sequence = "Unknown"
|
||||
if len(msg[-1]) == 4:
|
||||
msgSequence = struct.unpack('<I', msg[-1])[-1]
|
||||
sequence = str(msgSequence)
|
||||
if len(seq) == 4:
|
||||
sequence = str(struct.unpack('<I', seq)[-1])
|
||||
if topic == b"hashblock":
|
||||
print('- HASH BLOCK ('+sequence+') -')
|
||||
print(binascii.hexlify(body))
|
||||
|
@ -69,6 +68,12 @@ class ZMQHandler():
|
|||
elif topic == b"rawtx":
|
||||
print('- RAW TX ('+sequence+') -')
|
||||
print(binascii.hexlify(body))
|
||||
elif topic == b"sequence":
|
||||
hash = binascii.hexlify(body[:32])
|
||||
label = chr(body[32])
|
||||
mempool_sequence = None if len(body) != 32+1+8 else struct.unpack("<Q", body[32+1:])[0]
|
||||
print('- SEQUENCE ('+sequence+') -')
|
||||
print(hash, label, mempool_sequence)
|
||||
# schedule ourselves to receive the next message
|
||||
asyncio.ensure_future(self.handle())
|
||||
|
||||
|
|
29
doc/zmq.md
29
doc/zmq.md
|
@ -63,6 +63,7 @@ Currently, the following notifications are supported:
|
|||
-zmqpubhashblock=address
|
||||
-zmqpubrawblock=address
|
||||
-zmqpubrawtx=address
|
||||
-zmqpubsequence=address
|
||||
|
||||
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.
|
||||
|
@ -74,6 +75,7 @@ The option to set the PUB socket's outbound message high water mark
|
|||
-zmqpubhashblockhwm=n
|
||||
-zmqpubrawblockhwm=n
|
||||
-zmqpubrawtxhwm=n
|
||||
-zmqpubsequencehwm=address
|
||||
|
||||
The high water mark value must be an integer greater than or equal to 0.
|
||||
|
||||
|
@ -87,7 +89,15 @@ Each PUB notification has a topic and body, where the header
|
|||
corresponds to the notification type. For instance, for the
|
||||
notification `-zmqpubhashtx` the topic is `hashtx` (no null
|
||||
terminator) and the body is the transaction hash (32
|
||||
bytes).
|
||||
bytes) for all but `sequence` topic. For `sequence`, the body
|
||||
is structured as the following based on the type of message:
|
||||
|
||||
<32-byte hash>C : Blockhash connected
|
||||
<32-byte hash>D : Blockhash disconnected
|
||||
<32-byte hash>R<8-byte LE uint> : Transactionhash removed from mempool for non-block inclusion reason
|
||||
<32-byte hash>A<8-byte LE uint> : Transactionhash added mempool
|
||||
|
||||
Where the 8-byte uints correspond to the mempool sequence number.
|
||||
|
||||
These options can also be provided in bitcoin.conf.
|
||||
|
||||
|
@ -124,13 +134,20 @@ No authentication or authorization is done on connecting clients; it
|
|||
is assumed that the ZeroMQ port is exposed only to trusted entities,
|
||||
using other means such as firewalling.
|
||||
|
||||
Note that when the block chain tip changes, a reorganisation may occur
|
||||
and just the tip will be notified. It is up to the subscriber to
|
||||
retrieve the chain from the last known block to the new tip. Also note
|
||||
that no notification occurs if the tip was in the active chain - this
|
||||
is the case after calling invalidateblock RPC.
|
||||
Note that for `*block` topics, when the block chain tip changes,
|
||||
a reorganisation may occur and just the tip will be notified.
|
||||
It is up to the subscriber to retrieve the chain from the last known
|
||||
block to the new tip. Also note that no notification will occur if the tip
|
||||
was in the active chain--as would be the case after calling invalidateblock RPC.
|
||||
In contrast, the `sequence` topic publishes all block connections and
|
||||
disconnections.
|
||||
|
||||
There are several possibilities that ZMQ notification can get lost
|
||||
during transmission depending on the communication type you are
|
||||
using. Bitcoind appends an up-counting sequence number to each
|
||||
notification which allows listeners to detect lost notifications.
|
||||
|
||||
The `sequence` topic refers specifically to the mempool sequence
|
||||
number, which is also published along with all mempool events. This
|
||||
is a different sequence value than in ZMQ itself in order to allow a total
|
||||
ordering of mempool events to be constructed.
|
||||
|
|
Loading…
Add table
Reference in a new issue