blockfetch

package
v0.188.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 14, 2026 License: Apache-2.0 Imports: 12 Imported by: 7

README

BlockFetch Protocol

The BlockFetch protocol retrieves blocks by hash from a peer node. It is used in node-to-node communication to fetch full block bodies after discovering headers via ChainSync.

Protocol Identifiers

Property Value
Protocol Name block-fetch
Protocol ID 3
Mode Node-to-Node

State Machine

┌──────┐  RequestRange   ┌──────┐
│ Idle │ ───────────────►│ Busy │
└──┬───┘                 └──┬───┘
   │                        │
   │ ClientDone             │ StartBatch
   │                        │ NoBlocks
   │                        │
   ▼                        ▼
┌──────┐              ┌───────────┐
│ Done │◄─────────────│ Streaming │◄───┐
└──────┘              └─────┬─────┘    │
                            │          │
                            │ Block    │
                            └──────────┘
                            │
                            │ BatchDone
                            ▼
                       ┌──────┐
                       │ Idle │
                       └──────┘

States

State ID Agency Description
Idle 1 Client Waiting for block range request
Busy 2 Server Processing range request
Streaming 3 Server Streaming blocks to client
Done 4 None Terminal state

Messages

Message Type ID Direction Description
RequestRange 0 Client → Server Request blocks in range
ClientDone 1 Client → Server Terminate protocol
StartBatch 2 Server → Client Begin streaming blocks
NoBlocks 3 Server → Client No blocks available for range
Block 4 Server → Client Single block in batch
BatchDone 5 Server → Client End of block batch

State Transitions

From Idle (Client Agency)
Message New State
RequestRange Busy
ClientDone Done
From Busy (Server Agency)
Message New State
StartBatch Streaming
NoBlocks Idle
From Streaming (Server Agency)
Message New State
Block Streaming
BatchDone Idle

Timeouts

State Timeout Description
Busy 60 seconds Server must start batch or respond no blocks
Streaming 60 seconds Server must send next block in batch

Limits

Limit Value Description
Max Recv Queue Size 512 Maximum receive queue messages
Default Recv Queue Size 384 Default queue size
Streaming Max Pending Bytes 2.5 MB Max pending bytes in Streaming state
Idle/Busy Max Pending Bytes 64 KB Max pending bytes in Idle/Busy states

Configuration Options

blockfetch.NewConfig(
    blockfetch.WithBlockFunc(blockCallback),
    blockfetch.WithBlockRawFunc(blockRawCallback),
    blockfetch.WithBatchDoneFunc(batchDoneCallback),
    blockfetch.WithRequestRangeFunc(requestRangeCallback),
    blockfetch.WithBatchStartTimeout(5 * time.Second),
    blockfetch.WithBlockTimeout(60 * time.Second),
    blockfetch.WithRecvQueueSize(384),
)

Usage Example

// Request a range of blocks
startPoint := Point{Slot: 1000, Hash: startHash}
endPoint := Point{Slot: 2000, Hash: endHash}

client.RequestRange(startPoint, endPoint)

// Blocks arrive via BlockFunc callback
// BatchDoneFunc called when range complete

Block Format

Blocks are wrapped in CBOR with a type identifier:

type WrappedBlock struct {
    Type     uint   // Block type identifier (era)
    RawBlock []byte // Raw CBOR block data
}

Notes

  • Used in conjunction with ChainSync (headers) + BlockFetch (bodies)
  • Blocks are streamed in order from start to end point
  • Large receive queue supports high-throughput block streaming
  • The Streaming state has a higher pending byte limit for efficiency

Documentation

Overview

Package blockfetch implements the Ouroboros Block Fetch mini-protocol. It provides client and server implementations for requesting and serving blocks over the network according to the Cardano Ouroboros specification.

Package blockfetch implements the Ouroboros block-fetch mini-protocol.

AI Navigation Guide

This package is a good reference for understanding the protocol package structure. All protocol packages follow similar patterns.

Key Files

  • blockfetch.go: Protocol definition with ProtocolName, ProtocolId, StateMap
  • client.go: Client implementation for requesting blocks
  • server.go: Server implementation for serving blocks
  • messages.go: Message types with CBOR encoding

Protocol Structure Pattern

All mini-protocol packages follow this structure:

  1. {protocol}.go defines: - ProtocolName, ProtocolId constants - StateMap for state machine transitions - Protocol struct embedding protocol.Protocol

  2. client.go provides: - Client struct with connection handling - NewClient() constructor - Request methods (e.g., RequestBlock, RequestRange)

  3. server.go provides: - Server struct - Handler registration - Response methods

  4. messages.go defines: - Message type constants - Message structs with CBOR tags - Constructor functions (NewMsg*)

State Machine

BlockFetch states: Idle -> Busy -> Streaming -> Idle

Client requests a range of blocks, server streams them back.

Index

Constants

View Source
const BusyMaxPendingMessageBytes = StreamingMaxPendingMessageBytes

BusyMaxPendingMessageBytes is the maximum allowed pending message bytes in the Busy state. This must match StreamingMaxPendingMessageBytes because MsgBlock can arrive while the protocol state machine is still in Busy (before recvLoop processes MsgStartBatch to transition to Streaming), creating a race between muxerRecvLoop limit checks and state transitions.

View Source
const BusyTimeout = 60 * time.Second

BusyTimeout is the timeout for the server to start a batch or respond no blocks.

View Source
const DefaultRecvQueueSize = 384

DefaultRecvQueueSize is the default receive queue size.

View Source
const IdleMaxPendingMessageBytes = 65535

IdleMaxPendingMessageBytes is the maximum allowed pending message bytes in the Idle state. Only control messages (MsgRequestRange, MsgClientDone) are sent in this state, so the limit can be small.

View Source
const MaxRecvQueueSize = 512

MaxRecvQueueSize is the maximum allowed receive queue size (messages).

View Source
const MessageTypeBatchDone = 5

MessageTypeBatchDone is the message type for indicating the end of a batch.

View Source
const MessageTypeBlock = 4

MessageTypeBlock is the message type for sending a block.

View Source
const MessageTypeClientDone = 1

MessageTypeClientDone is the message type for client completion.

View Source
const MessageTypeNoBlocks = 3

MessageTypeNoBlocks is the message type for indicating no blocks are available.

View Source
const MessageTypeRequestRange = 0

MessageTypeRequestRange is the message type for requesting a range of blocks.

View Source
const MessageTypeStartBatch = 2

MessageTypeStartBatch is the message type for starting a batch.

View Source
const ProtocolId uint16 = 3

ProtocolId is the unique protocol identifier for Block Fetch.

View Source
const ProtocolName = "block-fetch"

ProtocolName is the name of the Block Fetch protocol.

View Source
const StreamingMaxPendingMessageBytes = 2500000

StreamingMaxPendingMessageBytes is the maximum allowed pending message bytes when in the Streaming state

View Source
const StreamingTimeout = 60 * time.Second

StreamingTimeout is the timeout for the server to send the next block in a batch.

Variables

View Source
var StateBusy = protocol.NewState(2, "Busy")

StateBusy represents the Busy state in the Block Fetch protocol.

View Source
var StateDone = protocol.NewState(4, "Done")

StateDone represents the Done state in the Block Fetch protocol.

View Source
var StateIdle = protocol.NewState(1, "Idle")

StateIdle represents the Idle state in the Block Fetch protocol.

View Source
var StateMap = protocol.StateMap{
	StateIdle: protocol.StateMapEntry{
		Agency:                  protocol.AgencyClient,
		PendingMessageByteLimit: IdleMaxPendingMessageBytes,
		Transitions: []protocol.StateTransition{
			{
				MsgType:  MessageTypeRequestRange,
				NewState: StateBusy,
			},
			{
				MsgType:  MessageTypeClientDone,
				NewState: StateDone,
			},
		},
	},
	StateBusy: protocol.StateMapEntry{
		Agency:                  protocol.AgencyServer,
		PendingMessageByteLimit: BusyMaxPendingMessageBytes,
		Timeout:                 BusyTimeout,
		Transitions: []protocol.StateTransition{
			{
				MsgType:  MessageTypeStartBatch,
				NewState: StateStreaming,
			},
			{
				MsgType:  MessageTypeNoBlocks,
				NewState: StateIdle,
			},
		},
	},
	StateStreaming: protocol.StateMapEntry{
		Agency:                  protocol.AgencyServer,
		PendingMessageByteLimit: StreamingMaxPendingMessageBytes,
		Timeout:                 StreamingTimeout,
		Transitions: []protocol.StateTransition{
			{
				MsgType:  MessageTypeBlock,
				NewState: StateStreaming,
			},
			{
				MsgType:  MessageTypeBatchDone,
				NewState: StateIdle,
			},
		},
	},
	StateDone: protocol.StateMapEntry{
		Agency: protocol.AgencyNone,
	},
}

StateMap defines the state transitions and agency for the Block Fetch protocol.

View Source
var StateStreaming = protocol.NewState(3, "Streaming")

StateStreaming represents the Streaming state in the Block Fetch protocol.

Functions

func NewMsgFromCbor

func NewMsgFromCbor(msgType uint, data []byte) (protocol.Message, error)

NewMsgFromCbor decodes a protocol message from CBOR data based on the message type.

Types

type BatchDoneFunc added in v0.104.0

type BatchDoneFunc func(CallbackContext) error

BatchDoneFunc is a callback invoked when a batch is complete.

type BlockFetch

type BlockFetch struct {
	Client *Client // Block Fetch client
	Server *Server // Block Fetch server
}

BlockFetch provides a combined client and server for the Block Fetch protocol.

func New

func New(protoOptions protocol.ProtocolOptions, cfg *Config) *BlockFetch

New creates a new BlockFetch instance with the given protocol options and configuration.

type BlockFetchOptionFunc

type BlockFetchOptionFunc func(*Config)

BlockFetchOptionFunc is a function that modifies a BlockFetch Config.

func WithBatchDoneFunc added in v0.104.0

func WithBatchDoneFunc(batchDoneFunc BatchDoneFunc) BlockFetchOptionFunc

WithBatchDoneFunc sets the BatchDoneFunc callback in the Config.

func WithBatchStartTimeout

func WithBatchStartTimeout(timeout time.Duration) BlockFetchOptionFunc

WithBatchStartTimeout sets the batch start timeout in the Config.

func WithBlockFunc

func WithBlockFunc(blockFunc BlockFunc) BlockFetchOptionFunc

WithBlockFunc sets the BlockFunc callback in the Config.

func WithBlockRawFunc added in v0.108.0

func WithBlockRawFunc(blockRawFunc BlockRawFunc) BlockFetchOptionFunc

WithBlockRawFunc sets the BlockRawFunc callback in the Config.

func WithBlockTimeout

func WithBlockTimeout(timeout time.Duration) BlockFetchOptionFunc

WithBlockTimeout sets the block timeout in the Config.

func WithPipeline added in v0.154.0

WithPipeline sets the block processing pipeline in the Config. When a pipeline is configured, received blocks are submitted to the pipeline for parallel decoding, validation, and ordered application instead of being processed synchronously through callbacks.

func WithRecvQueueSize added in v0.114.0

func WithRecvQueueSize(size int) BlockFetchOptionFunc

WithRecvQueueSize specifies the size of the received messages queue in the Config. Validation is deferred to NewConfig; invalid values are caught there.

func WithRequestRangeFunc added in v0.66.0

func WithRequestRangeFunc(
	requestRangeFunc RequestRangeFunc,
) BlockFetchOptionFunc

WithRequestRangeFunc sets the RequestRangeFunc callback in the Config.

type BlockFunc

type BlockFunc func(CallbackContext, uint, ledger.Block) error

BlockFunc is a callback for handling decoded blocks.

type BlockRawFunc added in v0.108.0

type BlockRawFunc func(CallbackContext, uint, []byte) error

BlockRawFunc is a callback for handling raw block data.

type CallbackContext added in v0.78.0

type CallbackContext struct {
	ConnectionId connection.ConnectionId // Connection ID
	Client       *Client                 // Client instance (if applicable)
	Server       *Server                 // Server instance (if applicable)
}

CallbackContext provides context for Block Fetch callbacks.

type Client

type Client struct {
	*protocol.Protocol
	// contains filtered or unexported fields
}

Client implements the Block Fetch protocol client, which requests blocks from a server.

func NewClient

func NewClient(protoOptions protocol.ProtocolOptions, cfg *Config) *Client

NewClient creates a new Block Fetch protocol client with the given options and configuration.

func (*Client) GetBlock

func (c *Client) GetBlock(point pcommon.Point) (ledger.Block, error)

GetBlock requests and returns a single block specified by the provided point. This is a synchronous call that returns the block or an error.

func (*Client) GetBlockRange

func (c *Client) GetBlockRange(start pcommon.Point, end pcommon.Point) error

GetBlockRange starts an async process to fetch all blocks in the specified range (inclusive). The provided callbacks are used for each block and when the batch is done.

func (*Client) ProtocolInstance added in v0.160.2

func (c *Client) ProtocolInstance() *protocol.Protocol

func (*Client) Start added in v0.73.3

func (c *Client) Start()

Start begins the Block Fetch client protocol. Safe to call multiple times.

func (*Client) Stop

func (c *Client) Stop() error

Stop stops the Block Fetch client protocol and sends a ClientDone message.

type Config

type Config struct {
	BlockFunc           BlockFunc               // Callback for decoded blocks
	BlockRawFunc        BlockRawFunc            // Callback for raw block data
	BatchDoneFunc       BatchDoneFunc           // Callback when a batch is done
	RequestRangeFunc    RequestRangeFunc        // Callback for range requests
	BatchStartTimeout   time.Duration           // Timeout for starting a batch
	BlockTimeout        time.Duration           // Timeout for receiving a block
	RecvQueueSize       int                     // Size of the receive queue
	SkipBlockValidation bool                    // Skip block validation during parsing
	Pipeline            *pipeline.BlockPipeline // Pipeline enables the block processing pipeline for batch operations
}

Config holds configuration options for the Block Fetch protocol.

func NewConfig

func NewConfig(options ...BlockFetchOptionFunc) (Config, error)

NewConfig creates a new Config for Block Fetch, applying any provided option functions. It returns an error if the resulting configuration is invalid.

type MsgBatchDone

type MsgBatchDone struct {
	protocol.MessageBase
}

MsgBatchDone indicates the end of a batch of blocks.

func NewMsgBatchDone

func NewMsgBatchDone() *MsgBatchDone

NewMsgBatchDone creates a new MsgBatchDone message.

type MsgBlock

type MsgBlock struct {
	protocol.MessageBase
	WrappedBlock []byte // CBOR-encoded wrapped block
}

MsgBlock contains a block sent from the server to the client.

func NewMsgBlock

func NewMsgBlock(wrappedBlock []byte) *MsgBlock

NewMsgBlock creates a new MsgBlock with the given wrapped block data.

func (MsgBlock) MarshalCBOR added in v0.66.0

func (m MsgBlock) MarshalCBOR() ([]byte, error)

MarshalCBOR encodes the MsgBlock as CBOR.

type MsgClientDone

type MsgClientDone struct {
	protocol.MessageBase
}

MsgClientDone indicates the client is done with block fetching.

func NewMsgClientDone

func NewMsgClientDone() *MsgClientDone

NewMsgClientDone creates a new MsgClientDone message.

type MsgNoBlocks

type MsgNoBlocks struct {
	protocol.MessageBase
}

MsgNoBlocks indicates that no blocks are available for the requested range.

func NewMsgNoBlocks

func NewMsgNoBlocks() *MsgNoBlocks

NewMsgNoBlocks creates a new MsgNoBlocks message.

type MsgRequestRange

type MsgRequestRange struct {
	protocol.MessageBase
	Start pcommon.Point // Start point of the range
	End   pcommon.Point // End point of the range
}

MsgRequestRange represents a request for a range of blocks.

func NewMsgRequestRange

func NewMsgRequestRange(
	start pcommon.Point,
	end pcommon.Point,
) *MsgRequestRange

NewMsgRequestRange creates a new MsgRequestRange with the given start and end points.

type MsgStartBatch

type MsgStartBatch struct {
	protocol.MessageBase
}

MsgStartBatch indicates the start of a batch of blocks.

func NewMsgStartBatch

func NewMsgStartBatch() *MsgStartBatch

NewMsgStartBatch creates a new MsgStartBatch message.

type RequestRangeFunc added in v0.66.0

type RequestRangeFunc func(CallbackContext, pcommon.Point, pcommon.Point) error

RequestRangeFunc is a callback for handling block range requests.

type Server

type Server struct {
	*protocol.Protocol
	// contains filtered or unexported fields
}

Server implements the Block Fetch protocol server, which serves blocks to clients.

func NewServer

func NewServer(protoOptions protocol.ProtocolOptions, cfg *Config) *Server

NewServer creates a new Block Fetch protocol server with the given options and configuration.

func (*Server) BatchDone added in v0.66.0

func (s *Server) BatchDone() error

BatchDone sends a BatchDone message to the client, indicating the end of a batch.

func (*Server) Block added in v0.66.0

func (s *Server) Block(blockType uint, blockData []byte) error

Block sends a Block message to the client with the given block type and data.

func (*Server) NoBlocks added in v0.66.0

func (s *Server) NoBlocks() error

NoBlocks sends a NoBlocks message to the client, indicating no blocks are available.

func (*Server) ProtocolInstance added in v0.160.2

func (s *Server) ProtocolInstance() *protocol.Protocol

func (*Server) StartBatch added in v0.66.0

func (s *Server) StartBatch() error

StartBatch sends a StartBatch message to the client, indicating the start of a batch.

type WrappedBlock

type WrappedBlock struct {
	cbor.StructAsArray
	Type     uint            // Block type identifier
	RawBlock cbor.RawMessage // Raw block data
}

WrappedBlock is a CBOR structure containing a block type and raw block data.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL