|
| 1 | +# sudo_network_unstable_watch |
| 2 | + |
| 3 | +**Parameters**: *none* |
| 4 | + |
| 5 | +**Return value**: String containing an opaque value representing the subscription. |
| 6 | + |
| 7 | +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. |
| 8 | + |
| 9 | +The subscription can later be stopped by calling `sudo_network_unstable_unwatch`. |
| 10 | + |
| 11 | +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. |
| 12 | +In addition, the JSON-RPC server is encouraged to notify the JSON-RPC client of connections and substreams that have recently been closed. |
| 13 | + |
| 14 | +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. |
| 15 | + |
| 16 | +## Notifications format |
| 17 | + |
| 18 | +This function will later generate one or more notifications in the following format: |
| 19 | + |
| 20 | +```json |
| 21 | +{ |
| 22 | + "jsonrpc": "2.0", |
| 23 | + "method": "sudo_networkState_event", |
| 24 | + "params": { |
| 25 | + "subscription": "...", |
| 26 | + "result": ... |
| 27 | + } |
| 28 | +} |
| 29 | +``` |
| 30 | + |
| 31 | +Where `subscription` is the value returned by this function, and `result` can be one of: |
| 32 | + |
| 33 | +### connectionState |
| 34 | + |
| 35 | +```json |
| 36 | +{ |
| 37 | + "event": "connectionState", |
| 38 | + "connectionId": "...", |
| 39 | + "targetPeerId": "...", |
| 40 | + "targetMultiaddr": "...", |
| 41 | + "status": "connecting" | "open" | "closed", |
| 42 | + "direction": "in" | "out", |
| 43 | + "when": ... |
| 44 | +} |
| 45 | +``` |
| 46 | + |
| 47 | +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. |
| 48 | + |
| 49 | +`connectionId` is an opaque string representing this specific connection. |
| 50 | + |
| 51 | +`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. |
| 52 | + |
| 53 | +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. |
| 54 | + |
| 55 | +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. |
| 56 | + |
| 57 | +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. |
| 58 | + |
| 59 | +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. |
| 60 | + |
| 61 | +`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. |
| 62 | + |
| 63 | +`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. |
| 64 | + |
| 65 | +`when` is an integer containing the UNIX timestamp in milliseconds, in other words the number of milliseconds since the UNIX epoch ignoring leap seconds. |
| 66 | + |
| 67 | +### substreamState |
| 68 | + |
| 69 | +```json |
| 70 | +{ |
| 71 | + "event": "substreamState", |
| 72 | + "connectionId": "...", |
| 73 | + "substreamId": "...", |
| 74 | + "status": "open" | "closed", |
| 75 | + "protocolName": "...", |
| 76 | + "direction": "in" | "out", |
| 77 | + "when": ... |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +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. |
| 82 | + |
| 83 | +`connectionId` is an opaque string representing this specific connection. It must always correspond to a connection whose latest `status` is `open`. |
| 84 | + |
| 85 | +`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. |
| 86 | + |
| 87 | +`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. |
| 88 | + |
| 89 | +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. |
| 90 | + |
| 91 | +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. |
| 92 | + |
| 93 | +`protocolName` is a string indicating the multistream-select protocol name that was negotiated. |
| 94 | + |
| 95 | +`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. |
| 96 | + |
| 97 | +`when` is an integer containing the UNIX timestamp in milliseconds, in other words the number of milliseconds since the UNIX epoch ignoring leap seconds. |
| 98 | + |
| 99 | +### missedEvents |
| 100 | + |
| 101 | +```json |
| 102 | +{ |
| 103 | + "event": "missedEvents" |
| 104 | +} |
| 105 | +``` |
| 106 | + |
| 107 | +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. |
| 108 | + |
| 109 | +See the `Guarantee of delivery` section for more details. |
| 110 | + |
| 111 | +## Guarantee of delivery |
| 112 | + |
| 113 | +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. |
| 114 | + |
| 115 | +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. |
| 116 | + |
| 117 | +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. |
| 118 | + |
| 119 | +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. |
| 120 | + |
| 121 | +## About timestamps |
| 122 | + |
| 123 | +The `connectionState` and `substreamState` events contain a `when` field indicating when the event happened. |
| 124 | + |
| 125 | +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`. |
| 126 | + |
| 127 | +## Possible errors |
| 128 | + |
| 129 | +- A JSON-RPC error with error code `-32100` can be generated if the JSON-RPC client has already opened a `sudo_network_unstable_watch` subscription. |
0 commit comments