Skip to content

Commit

Permalink
Add sudo_network_unstable_watch (#91)
Browse files Browse the repository at this point in the history
* Add `sudo_network_unstable_watch`

* Hyperlink in SUMMARY

* Update src/api/sudo_network_unstable_watch.md

Co-authored-by: Alexandru Vasile <[email protected]>

* Update src/api/sudo_network_unstable_watch.md

Co-authored-by: Josep M Sobrepere <[email protected]>

---------

Co-authored-by: Alexandru Vasile <[email protected]>
Co-authored-by: Josep M Sobrepere <[email protected]>
  • Loading branch information
3 people authored Jan 23, 2024
1 parent bee8868 commit 607b71b
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
- [sudo_unstable_p2pDiscover](api/sudo_unstable_p2pDiscover.md)
- [sudo_unstable_pendingTransactions](api/sudo_unstable_pendingTransactions.md)
- [sudo_unstable_version](api/sudo_unstable_version.md)
- [sudo_network]()
- [sudo_network_unstable_unwatch](api/sudo_network_unstable_unwatch.md)
- [sudo_network_unstable_watch](api/sudo_network_unstable_watch.md)
- [sudo_sessionKeys]()
- [sudo_sessionKeys_unstable_generate](api/sudo_sessionKeys_unstable_generate.md)
- [transaction](api/transaction.md)
Expand Down
9 changes: 9 additions & 0 deletions src/api/sudo_network_unstable_unwatch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# sudo_network_unstable_unwatch

**Parameters**:

- `subscription`: An opaque string that was returned by `sudo_network_unstable_watch`.

**Return value**: *null*

JSON-RPC client implementations must be aware that, due to the asynchronous nature of JSON-RPC client <-> server communication, they might still receive notifications concerning this subscription, for example because these notifications were already in the process of being sent back by the JSON-RPC server.
129 changes: 129 additions & 0 deletions src/api/sudo_network_unstable_watch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# 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:

```json
{
"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

```json
{
"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

```json
{
"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

```json
{
"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 a `sudo_network_unstable_watch` subscription.

0 comments on commit 607b71b

Please sign in to comment.