Documentation
¶
Overview ¶
Package protocol defines the canonical libp2p wire contract: the stream protocol identifiers, the GossipSub topic names, and the framed message structs that travel over them.
Every identifier is pinned to a single protocol version (1.0.0). A node only speaks to peers that dial the exact same string, so the version is the wire compatibility boundary — bump it deliberately, never per-stream.
The package is transport-agnostic: it owns the names and the bytes, never a host.Host. The auth/receipt/pubsub helpers under pkg/p2p take a caller-built host and register handlers for these identifiers.
Index ¶
Constants ¶
const ( // ProtocolAuth carries the nonce-challenge authentication handshake: the // server sends an AuthChallenge, the peer returns a signed AuthResponse. ProtocolAuth = "/ynp/auth/1.0.0" // ProtocolBurnReceipt carries a signed BurnReceipt — the attestation that // the L1 execute() of a finalized withdrawal landed — and a ReceiptAck. ProtocolBurnReceipt = "/ynp/burnreceipt/1.0.0" // ProtocolMintReceipt carries a signed MintReceipt — the attestation that // an L1 deposit confirmed — and a ReceiptAck. ProtocolMintReceipt = "/ynp/mintreceipt/1.0.0" )
Stream protocol identifiers. Each names a libp2p request/response or one-shot stream; the body is a cborx envelope (auth) or frame (receipt) of the typed payload. Only the identifiers a shared SDK consumer drives are exported here; the cluster-internal streams (transfer, heartbeat, identify, …) stay in the node that owns them.
TODO(sdk): revisit whether other streams belong here. The rule today is "move a channel iff a consumer of the SDK could legitimately speak it" — so only the three shared custody↔clearnet streams (auth, burn/mint receipt) moved, and the ~14 cluster-internal streams (transfer, swap, shardsync, heartbeat, identify, peerexchange, signature, …) stayed in node.go. If a future consumer needs to dial one of those (and its wire body is extracted to the SDK), promote its identifier here and pin the version.
const ( // TopicBlocks fans out sealed *core.Block values. TopicBlocks = "/clearnet/blocks.v1" // TopicTransfers fans out a batched []core.Event of non-pool events. TopicTransfers = "/clearnet/transfers.v1" // TopicWithdrawals fans out *core.FinalizedWithdrawal notifications. TopicWithdrawals = "/clearnet/withdrawals.v1" // TopicChallenges fans out fraud-challenge submissions. TopicChallenges = "/clearnet/challenges.v1" )
GossipSub topic names. The topic name encodes the payload type; a subscriber dispatches on the topic and decodes the body as the cborx envelope of that payload directly (no inner message wrapper).
Variables ¶
This section is empty.
Functions ¶
func PoolTopic ¶
PoolTopic returns the canonical GossipSub topic for a pool anchor. Format: /clearnet/pool/<anchor-hex>.v1. The payload is a batched []core.Event of pool events (Swap, LiquidityAdded/Removed, Repeg, PoolCreated).
func PoolTopicHex ¶
PoolTopicHex is the string-anchor variant for call sites that already carry the anchor as hex (no 0x prefix, lowercase, 64 chars).
Types ¶
type AuthChallenge ¶
type AuthChallenge struct {
Nonce [32]byte
}
AuthChallenge is sent by the server (entry node) to a connecting peer at the start of the auth handshake: 32 random bytes scoped to a single attempt.
Wire encoding: cborx V1 envelope wrapping a 1-tuple (Nonce [32]byte).
func (*AuthChallenge) MarshalCBOR ¶
func (t *AuthChallenge) MarshalCBOR(w io.Writer) error
MarshalCBOR writes AuthChallenge as a 1-element CBOR array.
func (*AuthChallenge) UnmarshalCBOR ¶
func (t *AuthChallenge) UnmarshalCBOR(r io.Reader) error
UnmarshalCBOR reads AuthChallenge from a 1-element CBOR array.
type AuthResponse ¶
AuthResponse is the peer's reply after signing the nonce.
Wire encoding: cborx V1 envelope wrapping a 2-tuple (Signature []byte, Address string). Operator auth sets Address and signs keccak256(Nonce) with the operator secp256k1 key (raw v=0/1 form). Passive auth leaves Address empty and signs a domain-separated nonce with the libp2p identity key; the Address field is then carried empty.
func (*AuthResponse) MarshalCBOR ¶
func (t *AuthResponse) MarshalCBOR(w io.Writer) error
MarshalCBOR writes AuthResponse as a 2-element CBOR array.
func (*AuthResponse) UnmarshalCBOR ¶
func (t *AuthResponse) UnmarshalCBOR(r io.Reader) error
UnmarshalCBOR reads AuthResponse from a 2-element CBOR array.
type ReceiptAck ¶
ReceiptAck is the server's response to a burn/mint receipt submission.
Accepted is true when the server persisted the receipt or recognized it as a duplicate of an already-persisted one (the receipt path is idempotent on the natural keys the clearing layer de-dupes by, so retries are safe). Reason carries a short diagnostic when Accepted is false; empty otherwise.
Wire encoding: cborx V1 frame wrapping a 2-tuple (Accepted bool, Reason string).
func (*ReceiptAck) MarshalCBOR ¶
func (t *ReceiptAck) MarshalCBOR(w io.Writer) error
MarshalCBOR writes ReceiptAck as a 2-element CBOR array.
func (*ReceiptAck) UnmarshalCBOR ¶
func (t *ReceiptAck) UnmarshalCBOR(r io.Reader) error
UnmarshalCBOR reads ReceiptAck from a 2-element CBOR array.
type Registrar ¶
type Registrar interface {
// Register installs the server's stream handlers on h. The caller owns h
// and its lifecycle; Register only attaches handlers.
Register(h host.Host)
}
Registrar is implemented by every p2p server: it installs that server's stream handlers on a caller-owned host. Keeping the contract here lets the wiring layer treat auth/receipt/… servers uniformly — register a slice of Registrars against one host without knowing their concrete types.
GossipSub helpers (publish/subscribe over topics) deliberately do NOT implement Registrar: they register no stream handlers, which is the line between a stream protocol and a broadcast topic.