Firehose Protocol
Firehose Protocol 3.x Specification Reference
The Firehose Protocol defines a line-based text protocol for streaming blockchain block data from an instrumented node to a Firehose reader process. This document specifies versions 3.0 and 3.1 of the protocol.
Overview
The protocol operates over stdout/stderr, where the instrumented blockchain node emits specially formatted lines prefixed with FIRE . The Firehose reader process parses these lines to construct block objects that are then stored and served.
All protocol messages follow this general format:
FIRE <MESSAGE_TYPE> <FIELDS...>Protocol Versions
3.0
Standard protocol for tracer-based block extraction
3.1
Extends 3.0 with partial block support for large blocks
Message Types
The Firehose Protocol 3.x defines two message types:
INIT
Initialization handshake establishing protocol version and block type
BLOCK
Complete or partial block data transmission
FIRE INIT
The INIT message must be the first Firehose message emitted by the node. It establishes the protocol version and declares the Protobuf message type used for block payloads.
Format
Fields
version
string
Protocol version: 3.0 or 3.1
protobuf_type
string
Fully qualified Protobuf message type for the block payload
Examples
Behavior
The reader validates the protocol version is supported
The
protobuf_typeis used to construct thetype.googleapis.com/<protobuf_type>URL in the Any wrapperFor version 3.1, partial block parsing is enabled
FIRE BLOCK
The BLOCK message transmits block data. The format differs slightly between versions 3.0 and 3.1.
Version 3.0 Format
Field Count: 7 fields after FIRE BLOCK
Version 3.1 Format
Field Count: 8 fields after FIRE BLOCK
Fields
block_num
uint64
3.0, 3.1
Block number/height
block_hash
string
3.0, 3.1
Block identifier/hash
parent_num
uint64
3.0, 3.1
Parent block number
parent_hash
string
3.0, 3.1
Parent block identifier/hash
lib_num
uint64
3.0, 3.1
Last Irreversible Block number
timestamp_unix_nano
uint64
3.0, 3.1
Block timestamp in Unix nanoseconds
payload_base64
string
3.0, 3.1
Base64-encoded Protobuf block payload
Block Hash Representation
The protocol does not mandate a specific string format for block hashes. However, consistency is critical:
The chosen format (e.g., hexadecimal, base58, base64) must remain constant throughout the chain's lifetime
Both
block_hashandparent_hashmust use the same encoding formatThe
parent_hashof block N must exactly match theblock_hashof block N-1
Chain Continuity Requirement
The Firehose system relies on parent hash linking to establish block continuity and detect forks. If parent_hash does not exactly match the previous block's block_hash (as a string), the reader will fail to establish the chain relationship.
This means:
If using hex encoding, use it consistently (always lowercase or always uppercase)
If using a prefix like
0x, always include itNever change the encoding format after genesis
Recommendation for New Chains
For new chain integrations, we strongly recommend using lowercase hexadecimal without the 0x prefix:
This format is being considered as the canonical standard for future protocol versions. Adopting it now ensures forward compatibility and consistency across the Firehose ecosystem.
Examples
Version 3.0:
Version 3.1 (complete block):
Version 3.1 (partial block, not final):
Partial Blocks
Protocol version 3.1 introduces support for partial blocks, enabling transmission of large blocks in multiple chunks.
Partial Index Encoding
The partial_idx field uses a special encoding:
0 to 999
Partial block chunk at index N, more chunks to follow
1000 to 1999
Final partial block chunk at index (N - 1000)
Examples
partial_idx
Actual Index
Is Final
0
0
No
1
1
No
5
5
No
1000
0
Yes (single complete block)
1001
1
Yes (2 partials, this is last)
1005
5
Yes (6 partials, this is last)
Behavior
When
partial_idx < 1000: Reader accumulates the partial payload, expecting moreWhen
partial_idx >= 1000: Reader treats this as the final chunk and assembles the complete blockA value of
1000indicates a single complete block (equivalent to version 3.0 behavior)
Payload Format
The payload_base64 field contains a Base64-encoded Protobuf message. The message type is declared in the FIRE INIT message.
Wrapping
The decoded payload is wrapped in a google.protobuf.Any message:
Block Container
The Any-wrapped payload is then placed in a sf.bstream.v1.Block container:
Error Handling
Invalid Protocol Version
If the FIRE INIT message specifies an unsupported version, the reader should terminate with an error indicating the supported versions.
Malformed Messages
Lines that:
Don't start with
FIREHave incorrect field counts
Contain unparseable numeric values
Have invalid Base64 encoding
Should be logged and typically cause the reader to terminate, as they indicate a protocol mismatch or corrupted output.
Missing INIT
If a FIRE BLOCK message is received before FIRE INIT, the reader should terminate with an error.
Implementation Notes
Line Parsing
Check line starts with
FIREprefixExtract message type (
INITorBLOCK)Split remaining content by spaces with bounded chunks (last field accumulates all remaining content)
Parse fields according to their expected types
Numeric Parsing
All numeric fields use base-10 representation
block_num,parent_num,lib_num,timestamp_unix_nano: Parse as unsigned 64-bit integerspartial_idx: Parse as signed 64-bit integer
Base64 Decoding
Use standard Base64 encoding (RFC 4648)
The decoded bytes are the raw Protobuf message (not Any-wrapped at this stage)
Last updated
Was this helpful?
