protocol

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: 4

README

Ouroboros Mini-Protocols

This directory contains implementations of the Ouroboros mini-protocols used for communication between Cardano nodes and clients.

Protocol Overview

Protocol ID Mode Purpose
Handshake 0 NtN/NtC Version negotiation
ChainSync 2/5 NtN/NtC Blockchain synchronization
BlockFetch 3 NtN Block retrieval
TxSubmission 4 NtN Transaction propagation
LocalTxSubmission 6 NtC Local transaction submission
LocalStateQuery 7 NtC Ledger state queries
KeepAlive 8 NtN Connection liveness
LocalTxMonitor 9 NtC Mempool monitoring
PeerSharing 10 NtN Peer discovery
MessageSubmission 11 NtN DMQ message propagation (sig-submission-v2)
LocalMessageSubmission 14 NtC Local DMQ submission
LocalMessageNotification 15 NtC Local DMQ notifications
LeiosNotify 18 NtN Leios notifications
LeiosFetch 19 NtN Leios data retrieval
LeiosVotes 20 NtN Leios vote diffusion

Mode Key:

  • NtN: Node-to-Node (between full nodes)
  • NtC: Node-to-Client (between node and wallet/application)

Protocol Architecture

State Machines

Each protocol is defined by a state machine with:

  • States: Named protocol states with numeric IDs
  • Agency: Which party (Client/Server) can send messages in each state
  • Transitions: Valid message types that trigger state changes
  • Timeouts: Optional deadlines for state transitions
Agency Model

The Ouroboros protocol uses an agency model where only one party can send messages at a time:

  • Client Agency: Client sends, server waits
  • Server Agency: Server sends, client waits
  • None: Terminal state (Done)
Common Patterns

Acquire/Release Pattern (LocalStateQuery, LocalTxMonitor):

Idle → Acquiring → Acquired → (query) → Acquired → Release → Idle

Request/Reply Pattern (BlockFetch, PeerSharing):

Idle → Request → Busy → Reply → Idle

Streaming Pattern (ChainSync, BlockFetch):

Idle → Request → Streaming → (data)* → Done → Idle

Init Pattern (TxSubmission, MessageSubmission):

Init → Idle → (request/reply cycle)

Protocol Groups

Core Synchronization
  • Handshake: Establishes protocol version
  • ChainSync: Synchronizes blockchain headers/blocks
  • BlockFetch: Retrieves full block bodies
Transaction Handling
  • TxSubmission: Node-to-node transaction propagation
  • LocalTxSubmission: Submit transactions to local node
  • LocalTxMonitor: Monitor local mempool
State & Discovery
  • LocalStateQuery: Query ledger state
  • PeerSharing: Discover new peers
  • KeepAlive: Maintain connection liveness
CIP-0137 (DMQ)
  • MessageSubmission: Node-to-node message propagation
  • LocalMessageSubmission: Submit messages to local node
  • LocalMessageNotification: Receive message notifications
Leios (Experimental)
  • LeiosNotify: Block announcements and availability notifications
  • LeiosFetch: Block and transaction retrieval
  • LeiosVotes: Vote diffusion

Usage

Creating a Protocol Instance
import (
    "log/slog"

    "github.com/blinklabs-io/gouroboros/protocol"
    "github.com/blinklabs-io/gouroboros/protocol/chainsync"
)

// Create protocol options
protoOptions := protocol.ProtocolOptions{
    ConnectionId: connId,                              // connection.ConnectionId
    Muxer:        muxer,                               // *muxer.Muxer
    Logger:       slog.Default(),                      // *slog.Logger
    ErrorChan:    errorChan,                           // chan error
    Mode:         protocol.ProtocolModeNodeToClient,
    Role:         protocol.ProtocolRoleClient,
    Version:      versionNumber,                       // uint16
}

// Create protocol config with callbacks
cfg := chainsync.NewConfig(
    chainsync.WithRollForwardFunc(handleRollForward),
    chainsync.WithRollBackwardFunc(handleRollBackward),
)

// Create protocol instance
cs := chainsync.New(protoOptions, &cfg)
Starting the Protocol
// Start the protocol
cs.Client.Start()

// Use protocol methods
cs.Client.RequestNext()

Common Configuration

All protocols support these common options:

  • Timeouts: Per-state or operation timeouts
  • Callbacks: Functions called on message receipt
  • Queue Sizes: Receive queue capacity

Error Handling

Protocols report errors through the error channel:

errChan := make(chan error, 10)
protoOptions := protocol.ProtocolOptions{
    ErrorChan: errChan,
    // ...
}

go func() {
    for err := range errChan {
        slog.Default().Error("Protocol error", "error", err)
    }
}()

Limits

Each protocol defines specific limits documented in its README:

  • Message sizes
  • Queue depths
  • Pipeline counts
  • Pending byte limits

References

Documentation

Overview

Package protocol provides the common functionality for mini-protocols

Index

Constants

View Source
const (
	DiffusionModeInitiatorOnly         = true
	DiffusionModeInitiatorAndResponder = false
)

Diffusion modes

View Source
const (
	PeerSharingModeNoPeerSharing         = 0
	PeerSharingModePeerSharingPublic     = 1
	PeerSharingModeV11NoPeerSharing      = 0
	PeerSharingModeV11PeerSharingPrivate = 1
	PeerSharingModeV11PeerSharingPublic  = 2
)

Peer sharing modes

View Source
const (
	QueryModeDisabled = false
	QueryModeEnabled  = true
)

Query modes

View Source
const (
	ProtocolVersionDMQNtN1 uint16 = 1
	ProtocolVersionDMQNtN2 uint16 = 2
)

DMQ node-to-node protocol versions from CIP-0137.

View Source
const DefaultRecvQueueSize = 55

DefaultRecvQueueSize is the default capacity for the recv queue channel

View Source
const ProtocolVersionDMQNtCOffset = 0x1000

The DMQ N2C protocol versions have the 12th bit set in the handshake. Note that this is a different bit than Cardano's NtC offset (15th bit); dmq-node uses the 12th bit deliberately to keep the DMQ namespace distinct from the Cardano N2N/N2C version space (see dmq-node/src/DMQ/NodeToClient/Version.hs).

View Source
const ProtocolVersionNtCOffset = 0x8000

The NtC protocol versions have the 15th bit set in the handshake

Variables

View Source
var (
	ErrProtocolViolationQueueExceeded = errors.New(
		"protocol violation: message queue limit exceeded",
	)
	ErrProtocolViolationPipelineExceeded = errors.New(
		"protocol violation: pipeline limit exceeded",
	)
	ErrProtocolViolationRequestExceeded = errors.New(
		"protocol violation: request count limit exceeded",
	)
	ErrProtocolViolationInvalidMessage = errors.New(
		"protocol violation: invalid message received",
	)
)

Protocol violation errors cause connection termination per Ouroboros Network Spec

View Source
var ErrProtocolShuttingDown = errors.New("protocol is shutting down")

Functions

func GetProtocolVersionsDMQNtC added in v0.167.0

func GetProtocolVersionsDMQNtC() []uint16

GetProtocolVersionsDMQNtC returns a list of supported DMQ N2C protocol versions in ascending order.

func GetProtocolVersionsDMQNtN added in v0.170.0

func GetProtocolVersionsDMQNtN() []uint16

GetProtocolVersionsDMQNtN returns a list of supported DMQ N2N protocol versions in ascending order.

func GetProtocolVersionsNtC added in v0.63.0

func GetProtocolVersionsNtC() []uint16

GetProtocolVersionsNtC returns a list of supported NtC protocol versions

func GetProtocolVersionsNtN added in v0.63.0

func GetProtocolVersionsNtN() []uint16

GetProtocolVersionsNtN returns a list of supported NtN protocol versions

Types

type Message

type Message interface {
	SetCbor([]byte)
	Cbor() []byte
	Type() uint8
}

Message provides a common interface for message utility functions

type MessageBase

type MessageBase struct {
	cbor.StructAsArray
	cbor.DecodeStoreCbor
	MessageType uint8
}

MessageBase is the minimum implementation for a mini-protocol message

func (*MessageBase) Type

func (m *MessageBase) Type() uint8

Type returns the message type

type MessageFromCborFunc

type MessageFromCborFunc func(uint, []byte) (Message, error)

MessageFromCborFunc represents a function that parses a mini-protocol message

type MessageHandlerFunc

type MessageHandlerFunc func(Message) error

MessageHandlerFunc represents a function that handles an incoming message

type NewVersionDataFromCborFunc added in v0.63.0

type NewVersionDataFromCborFunc func([]byte) (VersionData, error)

type Protocol

type Protocol struct {
	// contains filtered or unexported fields
}

Protocol implements the base functionality of an Ouroboros mini-protocol

func New

func New(config ProtocolConfig) *Protocol

New returns a new Protocol object

func (*Protocol) DoneChan

func (p *Protocol) DoneChan() <-chan struct{}

DoneChan returns the channel used to signal protocol shutdown

func (*Protocol) EnsureRegistered added in v0.147.0

func (p *Protocol) EnsureRegistered()

EnsureRegistered registers the protocol with the muxer if not already registered.

func (*Protocol) IsDone added in v0.160.0

func (p *Protocol) IsDone() bool

IsDone returns true if the protocol has finished (done channel is closed or in AgencyNone state). Use this to check if the protocol should avoid sending messages (e.g., Done message in Stop()).

func (*Protocol) IsInTerminalOrIdleState added in v0.160.0

func (p *Protocol) IsInTerminalOrIdleState() bool

IsInTerminalOrIdleState returns true if the protocol is in a state where connection close should not be treated as an error. This includes: - Protocol stop/done channel is closed - Current state has AgencyNone (terminal Done state after receiving Done message) - Current state is the initial state (no messages exchanged yet)

func (*Protocol) Logger added in v0.97.0

func (p *Protocol) Logger() *slog.Logger

Logger returns the protocol logger

func (*Protocol) Mode

func (p *Protocol) Mode() ProtocolMode

Mode returns the protocol mode

func (*Protocol) Role

func (p *Protocol) Role() ProtocolRole

Role understands the protocol role

func (*Protocol) SendError

func (p *Protocol) SendError(err error)

SendError sends an error to the handler in the Ouroboros object and stops the protocol. This ensures that protocol errors immediately terminate the connection and prevent further errors from being generated.

func (*Protocol) SendMessage

func (p *Protocol) SendMessage(msg Message) error

SendMessage appends a message to the send queue

func (*Protocol) SendMessageAndWait added in v0.188.0

func (p *Protocol) SendMessageAndWait(msg Message) error

SendMessageAndWait queues a message and waits until its final muxer segment is written to the underlying connection. It returns an error if the write fails or the protocol shuts down before delivery completes.

func (*Protocol) Start

func (p *Protocol) Start()

Start initializes the mini-protocol

func (*Protocol) Stop added in v0.83.0

func (p *Protocol) Stop()

Stop shuts down the mini-protocol

func (*Protocol) WaitSendQueueDrained added in v0.148.0

func (p *Protocol) WaitSendQueueDrained(timeout time.Duration) bool

WaitSendQueueDrained blocks until the send queue has been drained (best-effort) or the protocol begins shutting down, or the timeout expires.

type ProtocolConfig

type ProtocolConfig struct {
	Name                string
	ProtocolId          uint16
	ErrorChan           chan error
	Muxer               *muxer.Muxer
	Logger              *slog.Logger
	Mode                ProtocolMode
	Role                ProtocolRole
	MessageHandlerFunc  MessageHandlerFunc
	MessageFromCborFunc MessageFromCborFunc
	StateMap            StateMap
	StateContext        any
	InitialState        State
	RecvQueueSize       int
}

ProtocolConfig provides the configuration for Protocol

type ProtocolMode

type ProtocolMode uint

ProtocolMode is an enum of the protocol modes

const (
	ProtocolModeNone         ProtocolMode = 0 // Default (invalid) protocol mode
	ProtocolModeNodeToClient ProtocolMode = 1 // Node-to-client protocol mode
	ProtocolModeNodeToNode   ProtocolMode = 2 // Node-to-node protocol mode
)

type ProtocolOptions

type ProtocolOptions struct {
	ConnectionId connection.ConnectionId
	Muxer        *muxer.Muxer
	Logger       *slog.Logger
	ErrorChan    chan error
	Mode         ProtocolMode
	// TODO(cleanup): Role field may be redundant with Mode - evaluate removal
	Role    ProtocolRole
	Version uint16
}

ProtocolOptions provides common arguments for all mini-protocols

type ProtocolRole

type ProtocolRole uint

ProtocolRole is an enum of the protocol roles

const (
	ProtocolRoleNone   ProtocolRole = 0 // Default (invalid) protocol role
	ProtocolRoleClient ProtocolRole = 1 // Client protocol role
	ProtocolRoleServer ProtocolRole = 2 // Server protocol role
)

Protocol roles

type ProtocolStateAgency

type ProtocolStateAgency uint

ProtocolStateAgency is an enum representing the possible protocol state agency values

const (
	AgencyNone   ProtocolStateAgency = 0 // Default (invalid) value
	AgencyClient ProtocolStateAgency = 1 // Client agency
	AgencyServer ProtocolStateAgency = 2 // Server agency
)

type ProtocolVersion added in v0.63.0

type ProtocolVersion struct {
	NewVersionDataFromCborFunc NewVersionDataFromCborFunc
	EnableShelleyEra           bool
	EnableAllegraEra           bool
	EnableMaryEra              bool
	EnableAlonzoEra            bool
	EnableBabbageEra           bool
	EnableConwayEra            bool
	EnableDijkstraEra          bool
	// NtC only
	EnableLocalQueryProtocol     bool
	EnableLocalTxMonitorProtocol bool
	// NtN only
	EnableKeepAliveProtocol   bool
	EnableFullDuplex          bool
	EnablePeerSharingProtocol bool
	PeerSharingUseV11         bool
}

func GetProtocolVersion added in v0.63.0

func GetProtocolVersion(version uint16) ProtocolVersion

GetProtocolVersion returns the protocol version config for the specified protocol version. It searches Cardano NtN/NtC plus DMQ N2C/N2N maps. The key spaces are disjoint for supported Cardano versions: DMQ N2C uses the 0x1000 offset, DMQ N2N uses 1/2, Cardano NtC uses 0x8000, and supported Cardano NtN uses 7-15.

type ProtocolVersionMap added in v0.63.0

type ProtocolVersionMap map[uint16]VersionData

func GetProtocolVersionMap added in v0.63.0

func GetProtocolVersionMap(
	protocolMode ProtocolMode,
	networkMagic uint32,
	diffusionMode bool,
	peerSharing bool,
	queryMode bool,
) ProtocolVersionMap

GetProtocolVersionMap returns a data structure suitable for use with the protocol handshake

func GetProtocolVersionMapDMQNtC added in v0.167.0

func GetProtocolVersionMapDMQNtC(
	networkMagic uint32,
	queryMode bool,
) ProtocolVersionMap

GetProtocolVersionMapDMQNtC returns a ProtocolVersionMap suitable for handshaking against a DMQ node's node-to-client listener (CIP-0137). The networkMagic argument is the DMQ-specific topic magic (e.g. Mithril mainnet = 2912307721, dmq-node default = 3141592), distinct from any Cardano network magic.

func GetProtocolVersionMapDMQNtN added in v0.170.0

func GetProtocolVersionMapDMQNtN(
	networkMagic uint32,
	diffusionMode bool,
	peerSharing bool,
	queryMode bool,
) ProtocolVersionMap

GetProtocolVersionMapDMQNtN returns a ProtocolVersionMap suitable for handshaking against a DMQ node-to-node listener (CIP-0137).

type State

type State struct {
	Id   uint
	Name string
}

State represents protocol state with both a numeric ID and a string identifier

func NewState

func NewState(id uint, name string) State

NewState returns a new State object with the provided numeric ID and string identifier

func (State) String

func (s State) String() string

String returns the state string identifier

type StateMap

type StateMap map[State]StateMapEntry

StateMap represents the state machine definition for a mini-protocol

func (StateMap) Copy

func (s StateMap) Copy() StateMap

Copy returns a copy of the state map. This is mostly for convenience, since we need to copy the state map in various places

type StateMapEntry

type StateMapEntry struct {
	Agency                  ProtocolStateAgency
	Transitions             []StateTransition
	Timeout                 time.Duration        // Fixed timeout for this state (0 = no timeout)
	TimeoutFunc             func() time.Duration // Dynamic timeout; if set, overrides Timeout
	PendingMessageByteLimit int                  // Maximum pending message bytes allowed in this state (0 = no limit)
}

StateMapEntry represents a protocol state, it's possible state transitions, and an optional timeout

type StateTransition

type StateTransition struct {
	MsgType   uint8
	NewState  State
	MatchFunc StateTransitionMatchFunc
}

StateTransition represents a protocol state transition

type StateTransitionMatchFunc

type StateTransitionMatchFunc func(any, Message) bool

StateTransitionMatchFunc represents a function that will take a Message and return a bool that indicates whether the message is a match for the state transition rule

type VersionData added in v0.63.0

type VersionData interface {
	NetworkMagic() uint32
	Query() bool
	// NtN only
	DiffusionMode() bool
	PeerSharing() bool
}

func NewVersionDataNtC9to14FromCbor added in v0.63.0

func NewVersionDataNtC9to14FromCbor(cborData []byte) (VersionData, error)

func NewVersionDataNtC15andUpFromCbor added in v0.63.0

func NewVersionDataNtC15andUpFromCbor(cborData []byte) (VersionData, error)

func NewVersionDataNtN7to10FromCbor added in v0.63.0

func NewVersionDataNtN7to10FromCbor(cborData []byte) (VersionData, error)

func NewVersionDataNtN11to12FromCbor added in v0.63.0

func NewVersionDataNtN11to12FromCbor(cborData []byte) (VersionData, error)

func NewVersionDataNtN13andUpFromCbor added in v0.63.0

func NewVersionDataNtN13andUpFromCbor(cborData []byte) (VersionData, error)

type VersionDataNtC9to14 added in v0.63.0

type VersionDataNtC9to14 uint32

func (VersionDataNtC9to14) DiffusionMode added in v0.63.0

func (v VersionDataNtC9to14) DiffusionMode() bool

func (VersionDataNtC9to14) NetworkMagic added in v0.63.0

func (v VersionDataNtC9to14) NetworkMagic() uint32

func (VersionDataNtC9to14) PeerSharing added in v0.75.0

func (v VersionDataNtC9to14) PeerSharing() bool

func (VersionDataNtC9to14) Query added in v0.146.0

func (v VersionDataNtC9to14) Query() bool

type VersionDataNtC15andUp added in v0.63.0

type VersionDataNtC15andUp struct {
	cbor.StructAsArray
	CborNetworkMagic uint32
	CborQuery        bool
}

func (VersionDataNtC15andUp) DiffusionMode added in v0.63.0

func (v VersionDataNtC15andUp) DiffusionMode() bool

func (VersionDataNtC15andUp) NetworkMagic added in v0.63.0

func (v VersionDataNtC15andUp) NetworkMagic() uint32

func (VersionDataNtC15andUp) PeerSharing added in v0.75.0

func (v VersionDataNtC15andUp) PeerSharing() bool

func (VersionDataNtC15andUp) Query added in v0.146.0

func (v VersionDataNtC15andUp) Query() bool

type VersionDataNtN7to10 added in v0.63.0

type VersionDataNtN7to10 struct {
	cbor.StructAsArray
	CborNetworkMagic                       uint32
	CborInitiatorAndResponderDiffusionMode bool
}

func (VersionDataNtN7to10) DiffusionMode added in v0.63.0

func (v VersionDataNtN7to10) DiffusionMode() bool

func (VersionDataNtN7to10) NetworkMagic added in v0.63.0

func (v VersionDataNtN7to10) NetworkMagic() uint32

func (VersionDataNtN7to10) PeerSharing added in v0.75.0

func (v VersionDataNtN7to10) PeerSharing() bool

func (VersionDataNtN7to10) Query added in v0.146.0

func (v VersionDataNtN7to10) Query() bool

type VersionDataNtN11to12 added in v0.63.0

type VersionDataNtN11to12 struct {
	cbor.StructAsArray
	CborNetworkMagic                       uint32
	CborInitiatorAndResponderDiffusionMode bool
	CborPeerSharing                        uint
	CborQuery                              bool
}

func (VersionDataNtN11to12) DiffusionMode added in v0.63.0

func (v VersionDataNtN11to12) DiffusionMode() bool

func (VersionDataNtN11to12) NetworkMagic added in v0.63.0

func (v VersionDataNtN11to12) NetworkMagic() uint32

func (VersionDataNtN11to12) PeerSharing added in v0.75.0

func (v VersionDataNtN11to12) PeerSharing() bool

func (VersionDataNtN11to12) Query added in v0.146.0

func (v VersionDataNtN11to12) Query() bool

type VersionDataNtN13andUp added in v0.63.0

type VersionDataNtN13andUp struct {
	VersionDataNtN11to12
}

NOTE: the format stays the same, but the values for PeerSharing change

func (VersionDataNtN13andUp) PeerSharing added in v0.75.0

func (v VersionDataNtN13andUp) PeerSharing() bool

func (VersionDataNtN13andUp) Query added in v0.146.0

func (v VersionDataNtN13andUp) Query() bool

Directories

Path Synopsis
Package blockfetch implements the Ouroboros Block Fetch mini-protocol.
Package blockfetch implements the Ouroboros Block Fetch mini-protocol.
Package chainsync implements the Ouroboros chain-sync protocol
Package chainsync implements the Ouroboros chain-sync protocol
The common package contains types used by multiple mini-protocols
The common package contains types used by multiple mini-protocols
Package handshake implements the Ouroboros handshake protocol
Package handshake implements the Ouroboros handshake protocol
Package keepalive implements the Ouroboros KeepAlive mini-protocol, which is used to detect and maintain liveness between nodes in a network.
Package keepalive implements the Ouroboros KeepAlive mini-protocol, which is used to detect and maintain liveness between nodes in a network.
Package leiosvotes implements the Leios vote diffusion mini-protocol.
Package leiosvotes implements the Leios vote diffusion mini-protocol.
Package localmessagenotification implements the Ouroboros local-message-notification protocol (CIP-0137)
Package localmessagenotification implements the Ouroboros local-message-notification protocol (CIP-0137)
Package localmessagesubmission implements the Ouroboros local-message-submission protocol (CIP-0137)
Package localmessagesubmission implements the Ouroboros local-message-submission protocol (CIP-0137)
Package localstatequery implements the Ouroboros local state query mini-protocol.
Package localstatequery implements the Ouroboros local state query mini-protocol.
Package localtxmonitor implements the Ouroboros local-tx-monitor protocol
Package localtxmonitor implements the Ouroboros local-tx-monitor protocol
Package localtxsubmission implements the Ouroboros local-tx-submission protocol
Package localtxsubmission implements the Ouroboros local-tx-submission protocol
Package messagesubmission implements the Ouroboros message-submission protocol (CIP-0137)
Package messagesubmission implements the Ouroboros message-submission protocol (CIP-0137)
Package peersharing implements the Ouroboros PeerSharing protocol
Package peersharing implements the Ouroboros PeerSharing protocol
Package txsubmission implements the Ouroboros TxSubmission protocol
Package txsubmission implements the Ouroboros TxSubmission protocol

Jump to

Keyboard shortcuts

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