| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
LibP2P.Protocol.Identify
Description
Identify protocol implementation (specs/identify).
Protocol ID: ipfsid/1.0.0
After a connection is established, both sides exchange IdentifyInfo messages to learn about each other's capabilities, listen addresses, and agent version. Like all libp2p protobuf streams, the message is varint-length-delimited on the wire: uvarint(len) ++ protobuf. This matches the delimited reader/writer used by go-libp2p (pbio), rust-libp2p, and js-libp2p.
Also implements Identify Push (ipfsidpush1.0.0) for proactive updates when local state changes.
Synopsis
- identifyProtocolId :: ProtocolId
- identifyPushProtocolId :: ProtocolId
- handleIdentify :: Switch -> Connection -> StreamIO -> IO ()
- requestIdentify :: Connection -> IO (Either String IdentifyInfo)
- handleIdentifyPush :: Switch -> Connection -> StreamIO -> IO ()
- pushIdentify :: Switch -> IO ()
- mergeIdentify :: IdentifyInfo -> IdentifyInfo -> IdentifyInfo
- buildLocalIdentify :: Switch -> Maybe Connection -> IO IdentifyInfo
- registerIdentifyHandlers :: Switch -> IO ()
- encodeFramedIdentify :: IdentifyInfo -> ByteString
- readFramedIdentify :: StreamIO -> Int -> IO (Either String IdentifyInfo)
Protocol IDs
identifyProtocolId :: ProtocolId Source #
Identify protocol ID.
identifyPushProtocolId :: ProtocolId Source #
Identify Push protocol ID.
Protocol logic
handleIdentify :: Switch -> Connection -> StreamIO -> IO () Source #
Handle an inbound Identify request (responder side).
Sends our local IdentifyInfo as a varint-length-prefixed protobuf, then closes the stream (per specs/identify: respond and close). The connection provides the remote address used for observedAddr.
requestIdentify :: Connection -> IO (Either String IdentifyInfo) Source #
Request Identify from a remote peer (initiator side).
Opens a new stream, negotiates ipfsid/1.0.0, then reads one
varint-length-prefixed protobuf message. The publicKey field is
validated against the connection's authenticated peer id (see
validatePublicKey).
handleIdentifyPush :: Switch -> Connection -> StreamIO -> IO () Source #
Handle an inbound Identify Push (responder side).
Reads the pushed varint-length-prefixed IdentifyInfo from the remote peer. The length prefix is the message boundary — identify push has no stream-close boundary to fall back on.
The pushed info is merged into the existing peer entry via
mergeIdentify: pushes may be partial updates, so fields absent
from the message must not erase what we already know.
pushIdentify :: Switch -> IO () Source #
Push our current IdentifyInfo to every connected peer (sender side of ipfsidpush1.0.0).
Per specs/identify: open a stream to each remote peer, negotiate the push protocol id, send one Identify message and close the stream. Call this whenever local state advertised via identify changes (listen addresses, registered protocols). Failures on individual peers (e.g. push protocol not supported) are ignored.
mergeIdentify :: IdentifyInfo -> IdentifyInfo -> IdentifyInfo Source #
Merge a received (possibly partial) Identify update into the previously known info for a peer.
Per specs/identify: "missing fields should be ignored, as peers may choose to send partial updates containing only the fields whose values have changed." Optional fields keep the known value when the update omits them; repeated fields (protobuf cannot distinguish absent from empty) keep the known list when the update's is empty and are replaced wholesale otherwise, matching go-libp2p.
Building local info
buildLocalIdentify :: Switch -> Maybe Connection -> IO IdentifyInfo Source #
Build our local IdentifyInfo from Switch state, including a signed peer record (RFC 0003) over our listen addresses, sealed with the identity key.
Registration
registerIdentifyHandlers :: Switch -> IO () Source #
Register Identify protocol handlers on the Switch.
Registers: ipfsid/1.0.0 — respond to Identify requests ipfsidpush1.0.0 — handle Identify Push from remote
Wire framing
encodeFramedIdentify :: IdentifyInfo -> ByteString Source #
Encode an IdentifyInfo with its uvarint length prefix, as written on the wire: uvarint(len) ++ protobuf.
readFramedIdentify :: StreamIO -> Int -> IO (Either String IdentifyInfo) Source #
Read one varint-length-prefixed Identify message from a stream.
Reads the uvarint length prefix, then exactly that many payload bytes, and decodes the protobuf. Rejects messages larger than maxSize before reading the payload.