sudo_network_unstable_watch
Parameters: none
Return value: String containing an opaque value representing the subscription.
This functions lets the JSON-RPC client track the state of the peer-to-peer networking of the blockchain node associated to the JSON-RPC server.
The subscription can later be stopped by calling sudo_network_unstable_unwatch
.
When this function is called, a connectionState
event is generated for each connection that already exists, and a substreamState
event is generated for each substream that already exists. In other words, the JSON-RPC server must send its current networking state to the JSON-RPC client.
In addition, the JSON-RPC server is encouraged to notify the JSON-RPC client of connections and substreams that have recently been closed.
The JSON-RPC server must accept at least one sudo_network_unstable_watch
subscriptions per JSON-RPC client. Trying to open more might lead to a JSON-RPC error when calling sudo_network_unstable_watch
. In other words, as long as a JSON-RPC client only starts one sudo_network_unstable_watch
subscriptions, it is guaranteed that this return value will never happen.
Notifications format
This function will later generate one or more notifications in the following format:
{
"jsonrpc": "2.0",
"method": "sudo_networkState_event",
"params": {
"subscription": "...",
"result": ...
}
}
Where subscription
is the value returned by this function, and result
can be one of:
connectionState
{
"event": "connectionState",
"connectionId": "...",
"targetPeerId": "...",
"targetMultiaddr": "...",
"status": "connecting" | "open" | "closed",
"direction": "in" | "out",
"when": ...
}
A connectionState
event is generated when a new connection attempt is started, when a connection has finished its handshaking phase, or when a connection is terminated.
connectionId
is an opaque string representing this specific connection.
status
indicates the state of the connection: connecting
if the connection hasn't finished its handshake phase (including the libp2p-specific handshakes), open
if the connection is fully established and can open substreams, or closed
if the connection is now dead.
Each connectionId
must follow one of the follow status
transitions: connecting
then open
then closed
, or connecting
then closed
(if an error happend during the handshake). The JSON-RPC server is not allowed to omit events such as the connecting
event.
Once a connectionState
event with status
equal to closed
is generated, the connectionId
is unallocated. Any further usage of the same connectionId
designates a different connection instead.
If status
is closed
, the connection must not have any associated substream still alive. A substreamEvent
of status
equal to closed
must have been generated earlier for each substream that corresponds to this connection.
If status
is open
or closed
, the targetPeerId
is a string containing the string representation of the PeerId of the remote side of the connection. If status
is connecting
and direction
is in
, the targetPeerId
must be omitted. If status
is connecting
, the targetPeerId
contains the string representation of the PeerId that the remote is expected to have, which might end up being different from the actual PeerId.
targetMultiaddr
is a string containing the string representation of the multiaddress of the remote side of the connection. The value in the targetMultiaddr
field must always be the same for all the events related to a specific connection. In other words, a the multiaddress of the remote never changes during the lifetime of the connection.
direction
indicates whether the connection was initiated locally (out
) or by the remote (in
). The value in the direction
field must always be the same for all the events related to a specific connection. In other words, a connection never changes direction during its lifetime.
when
is an integer containing the UNIX timestamp in milliseconds, in other words the number of milliseconds since the UNIX epoch ignoring leap seconds.
substreamState
{
"event": "substreamState",
"connectionId": "...",
"substreamId": "...",
"status": "open" | "closed",
"protocolName": "...",
"direction": "in" | "out",
"when": ...
}
A substreamState
event is generated when a new connection attempt is started, when a connection has finished its handshaking phase, or when a connection is terminated.
connectionId
is an opaque string representing this specific connection. It must always correspond to a connection whose latest status
is open
.
substreamId
is an opaque string representing this specific substream within the connection. Each substream is identified by the connectionId
+ substreamId
tuple rather than just the substreamId
alone. The JSON-RPC server is allowed to use the same value of substreamId
for two different substreams belonging to two different connections.
status
indicates the state of the substream: open
if the substream is "alive", or closed
if the substream is dead. A substream is considered "alive" if the JSON-RPC server allocates resources for this substream, even if the remote isn't aware of said substream.
Each substreamState
event where status
equal to closed
must follow a previous substreamState
even for that same substream where status
was open
. In other words, the JSON-RPC server is not allowed to omit event the open
event.
Once a substreamState
event with status
equal to closed
is generated, the substreamId
is unallocated. Any further usage of the same substreamId
in the context of that connectionId
designates a different substream instead.
protocolName
is a string indicating the multistream-select protocol name that was negotiated.
direction
indicates whether the substream was initiated locally (out
) or by the remote (in
). Note that this is not the same thing as the direction
of the corresponding connection. The value in the direction
field must always be the same for all the events related to a specific substream. In other words, a substream never changes direction during its lifetime.
when
is an integer containing the UNIX timestamp in milliseconds, in other words the number of milliseconds since the UNIX epoch ignoring leap seconds.
missedEvents
{
"event": "missedEvents"
}
The missedEvents
event is generated in order to inform the JSON-RPC client that it has not been informed of the existence of all connections or substreams due to it being too slow to pull JSON-RPC notifications from the JSON-RPC server.
See the Guarantee of delivery
section for more details.
Guarantee of delivery
JSON-RPC server implementations must be aware of the fact that JSON-RPC clients might pull notifications from the JSON-RPC server at a slower rate than networking events are generated. If this function is implemented naively, a slow or malicious JSON-RPC client can cause the JSON-RPC server to allocate ever-increasing buffers, which could in turn lead to a DoS attack on the JSON-RPC server.
JSON-RPC server implementations are also allowed to completely omit events about connections and substreams whose existence is unknown to the JSON-RPC client. For example, when a connection gets closed, the JSON-RPC server is allowed to not notify the JSON-RPC client if the client wasn't yet notified of the fact that the new-closed connection existed. When that happens, the JSON-RPC server must send a missedEvents
event to the JSON-RPC client in the nearby future.
JSON-RPC clients must be aware that they aren't guaranteed to see the list of all connections and all substreams that the peer-to-peer endpoint of the node associated to the JSON-RPC server performs. The JSON-RPC client is only guaranteed to be aware of what is currently happening.
Assuming that the number of total active sudo_network_unstable_watch
subscriptions on any given JSON-RPC server is bounded, and that the number of total active connections and substreams is bounded, the size of the buffer of notifications to send back to JSON-RPC clients is also bounded.
About timestamps
The connectionState
and substreamState
events contain a when
field indicating when the event happened.
The JSON-RPC server isn't required to order events by the value in their when
field. The JSON-RPC is only required to order events so that they don't lose their logical meaning. For example, when two different connections open, the JSON-RPC server can send the two connectionState
events in any order. When a connection opens then closes, the JSON-RPC server must send a connectionState
with a status
equal to open
before the connectionState
with a status
equal to closed
.
Possible errors
- A JSON-RPC error with error code
-32100
can be generated if the JSON-RPC client has already opened asudo_network_unstable_watch
subscription.