موضوعاتِ ZMQ

TensorCash سطح pub/sub ‏ZMQ در Bitcoin Core را بی‌تغییر به ارث می‌برد. ناشر (publisher) روی آدرسی bind می‌شود (به‌طور پیش‌فرض tcp://127.0.0.1:28332)؛ subscriberها وصل می‌شوند و در پیشوندهای موضوع مشترک می‌شوند. هر اعلان یک پیام multipart سه‌فریمی است، و چیدمان بدنهٔ هر موضوع در ادامه فهرست شده است.

5 موضوع · مبدأ: inherit

این صفحه pub/sub به‌ارث‌رسیده از Bitcoin Core را پوشش می‌دهد. کانال اعتبارسنجی نود به تأییدکننده یک جریان جداگانهٔ ZMQ PUSH/PULL است که payloadهای آن از طرح‌واره‌های FlatBuffer استفاده می‌کنند: proof.fbs، validation.fbs و blockheader.fbs.

پاکت فریم

Publisher binds; subscribers connect and SUBSCRIBE to topic prefixes. Topic strings are matched as byte prefixes — SUBSCRIBE "hash" receives both hashblock and hashtx.

فریمفیلدنوعتوضیح
0topicutf-8 stringOne of the topic names below.
1bodyper-topicDefined by the topic. See frames[1] per topic.
2sequence_counteruint32 little-endianMonotonically increasing per-topic counter. Subscribers detect dropped messages by checking for gaps. Resets on bcore restart.

موضوعات

hashblock

-zmqpubhashblock=<address>

Best-block-tip changed (new block connected to the active chain).

A block is connected to the main chain. Fires once per UpdatedBlockTip callback.

فریمفیلدنوعتوضیح
1block_hash32 bytes, little-endian (display-reversed)The connecting block's hash. Note Bitcoin Core's display convention reverses byte order — the wire bytes are little-endian; tooling that prints hex usually reverses them for display.

منبع: services/core-node/bcore/src/zmq/zmqpublishnotifier.cpp:228

hashtx

-zmqpubhashtx=<address>

Transaction entered the mempool or was confirmed in a block.

Fires for every TransactionAddedToMempool and BlockConnected event; may emit duplicates for the same hash if a tx is re-broadcast or re-mined after a reorg.

فریمفیلدنوعتوضیح
1tx_hash32 bytes, little-endian (display-reversed)The transaction hash (txid).

منبع: services/core-node/bcore/src/zmq/zmqpublishnotifier.cpp:239

rawblock

-zmqpubrawblock=<address>

Full serialized block on best-tip change.

Same trigger as hashblock — but the body is the full block, not just its hash. Heavier; only enable if a subscriber actually needs full block bytes (e.g. an indexer that does not have its own bcore peer).

فریمفیلدنوعتوضیح
1block_serializedvariable-length bytesThe block, serialized using Bitcoin Core's standard block serialization (CBlock::Serialize). Includes the header, tx count (var_int), and all transactions in order.

منبع: services/core-node/bcore/src/zmq/zmqpublishnotifier.cpp:252

rawtx

-zmqpubrawtx=<address>

Full serialized transaction.

Same trigger as hashtx — body is the full serialized transaction (CTransaction::Serialize). Subscribers can fully decode without round-tripping to JSON-RPC.

فریمفیلدنوعتوضیح
1tx_serializedvariable-length bytesThe transaction, serialized with Bitcoin Core's standard transaction serialization. Witness data included when present.

منبع: services/core-node/bcore/src/zmq/zmqpublishnotifier.cpp:261

sequence

-zmqpubsequence=<address>

Mempool + block connect/disconnect event stream.

Block-connect, block-disconnect, mempool-accept, and mempool-remove events. The body's event byte tells subscribers which type. Useful for indexers that need a single ordered event stream rather than the separate hashblock/hashtx topics.

فریمفیلدنوعتوضیح
1hash + event_byte (+ optional mempool_seq)32-byte hash || 1-byte event || optional 8-byte LE mempool_sequenceBody layout depends on the event: • 'C' (block connect) — hash || 'C' • 'D' (block disconnect) — hash || 'D' • 'A' (mempool accept) — hash || 'A' || mempool_sequence (uint64 LE) • 'R' (mempool remove) — hash || 'R' || mempool_sequence (uint64 LE) The 32-byte hash is little-endian on the wire (same convention as the hash topics). mempool_sequence is a separate per-mempool counter — distinct from the topic-level sequence_counter in frame 2.

منبع: services/core-node/bcore/src/zmq/zmqpublishnotifier.cpp:264

نمونه‌های subscriber

Python (pyzmq)

import struct
import zmq

ctx = zmq.Context()
sock = ctx.socket(zmq.SUB)
sock.connect("tcp://127.0.0.1:28332")
sock.setsockopt(zmq.SUBSCRIBE, b"hashblock")
while True:
    topic, body, seq_le = sock.recv_multipart()
    (seq,) = struct.unpack("<I", seq_le)
    # block_hash bytes are little-endian; reverse for display hex
    display_hash = body[::-1].hex()
    print(f"seq={seq} {topic.decode()}: {display_hash}")

Node.js (zeromq.js)

import zmq from "zeromq";

const sock = new zmq.Subscriber();
sock.connect("tcp://127.0.0.1:28332");
sock.subscribe("rawtx");
for await (const [topic, body, seqLe] of sock) {
  const seq = seqLe.readUInt32LE(0);
  console.log(`seq=${seq} ${topic.toString()} ${body.length} bytes`);
}