Crate sc_network[][src]

Substrate-specific P2P networking.

Important: This crate is unstable and the API and usage may change.

Node identities and addresses

In a decentralized network, each node possesses a network private key and a network public key. In Substrate, the keys are based on the ed25519 curve.

From a node’s public key, we can derive its identity. In Substrate and libp2p, a node’s identity is represented with the PeerId struct. All network communications between nodes on the network use encryption derived from both sides’s keys, which means that identities cannot be faked.

A node’s identity uniquely identifies a machine on the network. If you start two or more clients using the same network key, large interferences will happen.

Substrate’s network protocol

Substrate’s networking protocol is based upon libp2p. It is at the moment not possible and not planned to permit using something else than the libp2p network stack and the rust-libp2p library. However the libp2p framework is very flexible and the rust-libp2p library could be extended to support a wider range of protocols than what is offered by libp2p.

Discovery mechanisms

In order for our node to join a peer-to-peer network, it has to know a list of nodes that are part of said network. This includes nodes identities and their address (how to reach them). Building such a list is called the discovery mechanism. There are three mechanisms that Substrate uses:

Connection establishment

When node Alice knows node Bob’s identity and address, it can establish a connection with Bob. All connections must always use encryption and multiplexing. While some node addresses (eg. addresses using /quic) already imply which encryption and/or multiplexing to use, for others the multistream-select protocol is used in order to negotiate an encryption layer and/or a multiplexing layer.

The connection establishment mechanism is called the transport.

As of the writing of this documentation, the following base-layer protocols are supported by Substrate:

On top of the base-layer protocol, the Noise protocol is negotiated and applied. The exact handshake protocol is experimental and is subject to change.

The following multiplexing protocols are supported:


Once a connection has been established and uses multiplexing, substreams can be opened. When a substream is open, the multistream-select protocol is used to negotiate which protocol to use on that given substream.

Protocols that are specific to a certain chain have a <protocol-id> in their name. This “protocol ID” is defined in the chain specifications. For example, the protocol ID of Polkadot is “dot”. In the protocol names below, <protocol-id> must be replaced with the corresponding protocol ID.

Note: It is possible for the same connection to be used for multiple chains. For example, one can use both the /dot/sync/2 and /sub/sync/2 protocols on the same connection, provided that the remote supports them.

Substrate uses the following standard libp2p protocols:

Additionally, Substrate uses the following non-libp2p-standard protocols:

The legacy Substrate substream

Substrate uses a component named the peerset manager (PSM). Through the discovery mechanism, the PSM is aware of the nodes that are part of the network and decides which nodes we should perform Substrate-based communications with. For these nodes, we open a connection if necessary and open a unique substream for Substrate-based communications. If the PSM decides that we should disconnect a node, then that substream is closed.

For more information about the PSM, see the sc-peerset crate.

Note that at the moment there is no mechanism in place to solve the issues that arise where the two sides of a connection open the unique substream simultaneously. In order to not run into issues, only the dialer of a connection is allowed to open the unique substream. When the substream is closed, the entire connection is closed as well. This is a bug that will be resolved by deprecating the protocol entirely.

Within the unique Substrate substream, messages encoded using parity-scale-codec are exchanged. The detail of theses messages is not totally in place, but they can be found in the file.

Once the substream is open, the first step is an exchange of a status message from both sides, containing information such as the chain root hash, head of chain, and so on.

Communications within this substream include:

Request-response protocols

A so-called request-response protocol is defined as follow:

Each request is performed in a new separate substream.

Notifications protocols

A so-called notifications protocol is defined as follow:

The API of sc-network allows one to register user-defined notification protocols. sc-network automatically tries to open a substream towards each node for which the legacy Substream substream is open. The handshake is then performed automatically.

For example, the sc-finality-grandpa crate registers the /paritytech/grandpa/1 notifications protocol.

At the moment, for backwards-compatibility, notification protocols are tied to the legacy Substrate substream. Additionally, the handshake message is hardcoded to be a single 8-bits integer representing the role of the node:

In the future, though, these restrictions will be removed.


Using the sc-network crate is done through the NetworkWorker struct. Create this struct by passing a config::Params, then poll it as if it was a Future. You can extract an Arc<NetworkService> from the NetworkWorker, which can be shared amongst multiple places in order to give orders to the networking.

See the config module for more information about how to configure the networking.

After the NetworkWorker has been created, the important things to do are:

More precise usage details are still being worked on and will likely change in the future.



Bitswap server for substrate.


Helper for handling (i.e. answering) block requests from a remote peer via the [crate::request_responses::RequestResponsesBehaviour].


Configuration of the networking layer.


Substrate network possible errors.


Helper for sending rate-limited gossip messages.


Helpers for outgoing and incoming light client requests.


Information about the networking, for diagnostic purposes.


Helper for handling (i.e. answering) state requests from a remote peer via the [crate::request_responses::RequestResponsesBehaviour].


Transactions handling to plug on top of the network service.



Representation of a Multiaddr.


Substrate network service. Handles network IO and manages connectivity.


Overview status of the network.


Main network worker. Must be polled in order for the network to advance.


A NotificationSender allows for sending notifications to a peer with a chosen protocol.


Reserved slot in the notifications buffer, ready to accept data.


Identifier of a peer of the network.


Info about a peer’s known state.


Description of a reputation adjustment for a node.


Reported state download progress.



Events generated by DHT as a response to get_value and put_value requests.


Type for events generated by networking layer.


When sending a request, what to do on a disconnected recipient.


Role that the peer sent to us during the handshake, with the addition of what our local node knows about that peer.


Possible failures occurring in the context of sending an outbound request and receiving the response.


Error in a request.


Reported sync state.



Minimum Requirements for a Hash within Networking


Trait for providing information about the local network state