Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

extensions-negotiation definition #112

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions 03-Protocol-Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ If a device is aware of the semantics of a given extension type, it MUST process

Messages with an unknown `extension_type` which are to be processed locally (as defined above) MUST be discarded and ignored.

### 3.4.1 Implementing Extensions Support

To support extensions, an implementation MUST first implement **Extension 1**, which defines the basic protocol for requesting and negotiating support for extensions. This extension must be included in any protocol implementation that plans to support additional protocol extensions.

Extensions MUST require version negotiation with the recipient of the message to check that the extension is supported before sending non-version-negotiation messages for it.
This prevents the needlessly wasted bandwidth and potentially serious performance degradation of extension messages when the recipient does not support them.

Expand Down
6 changes: 3 additions & 3 deletions 09-Extensions.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 9. Extensions

There are not yet any defined extensions.
| Extenstion Type | Extension Name | Description / BIP |
| -------------------- | -------------- | ---------------------------------------------------------------------------- |
| (no channel_msg bit) | | |
| Extension Type | Extension Name | Description / BIP |
| -------------- | ---------------------- | --------------------------------------------------------- |
| 0x0001 | Extensions Negotiation | Definition [here](./extensions/extensions-negotiation.md) |
112 changes: 112 additions & 0 deletions extensions/extensions-negotiation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Stratum V2 Extension: Extensions Negotiation

## 0. Abstract

This document defines a Stratum V2 extension to negotiate support for other protocol extensions between clients and servers.

The mechanism allows clients to request support for a list of extensions immediately after the `SetupConnection` message exchange. The server responds with either:
- `RequestExtensions.Success`, listing the supported extensions.
- `RequestExtensions.Error`, listing the unsupported extensions.

This negotiation ensures that both parties can establish a common set of features before exchanging further protocol messages.

Terms like "MUST," "MUST NOT," "REQUIRED," etc., follow RFC2119 standards.

---

## 1. Overview

### 1.1 Negotiating Extensions

After the successful `SetupConnection` exchange, clients MUST send a `RequestExtensions` message to indicate the extensions they wish to use. The server responds with:
- `RequestExtensions.Success`, confirming which extensions are supported.
- `RequestExtensions.Error`, identifying unsupported extensions.

Clients MUST NOT use any features from extensions that are not confirmed as supported by the server.

#### Message Exchange Example

1. **Connection Setup**:
```
Client --- SetupConnection (connection details) ---> Server
Client <--- SetupConnection.Success (connection accepted) ---- Server
```

2. **Extension Negotiation**:
```
Client --- RequestExtensions (list of requested U16) ---> Server
```

3. **Server Response**:
- If successful:
```
Client <--- RequestExtensions.Success (list of supported U16) ---- Server
```
- If an error occurs:
```
Client <--- RequestExtensions.Error (list of unsupported U16) ---- Server
```

---

## 2. Messages Defined by This Extension

### `RequestExtensions` (Client -> Server)

| Field Name | Data Type | Description |
|----------------------|--------------|-----------------------------------------------|
| request_id | U16 | Unique identifier for pairing the response. |
| requested_extensions | SEQ0_64K[U16]| List of requested extension identifiers. |

### `RequestExtensions.Success` (Server -> Client)

| Field Name | Data Type | Description |
|----------------------|--------------|-----------------------------------------------|
| request_id | U16 | Unique identifier for pairing the response. |
| supported_extensions | SEQ0_64K[U16]| List of supported extension identifiers. |

### `RequestExtensions.Error` (Server -> Client)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if upstream returns RequestExtensionsError? are they expected to drop the connection?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need to drop the connection here. Client based on the server response can decide if:

  1. continue with extension requested by up and/or continue without ext not supported by up
  2. drop connection (if for example up do not support an ext that is mandatory for cli)


| Field Name | Data Type | Description |
|------------------------|--------------|-----------------------------------------------|
| request_id | U16 | Unique identifier for pairing the response. |
| unsupported_extensions | SEQ0_64K[U16]| List of unsupported extension identifiers. |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a field called requested_extension with extension that server require but are not in RequestExtensions from client.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't you think extensions should be requested only by the client? Do you some tangible examples for the opposite case?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a pool accept only client that have an extension for example I want the client to use a specific accounting or auditing system


---

## 3. Message Types

| Message Type (8-bit) | channel_msg_bit | Message Name |
|----------------------|-----------------|---------------------------|
| 0x00 | 0 | RequestExtensions |
| 0x01 | 0 | RequestExtensions.Success |
| 0x02 | 0 | RequestExtensions.Error |

---

## 4. Implementation Notes

1. **Error Handling**:
- Servers MUST respond with `RequestExtensions.Error` if none of the requested extensions are supported.
- Servers MAY include an empty `unsupported_extensions` field in the error message if no extensions are explicitly unsupported.

2. **Ordering**:
- The `RequestExtensions` message MUST be sent immediately after `SetupConnection.Success` and before any other protocol-specific messages.

#### 3. **Backward Compatibility**:
- **Server Behavior**:
- Servers that do not support this extension will ignore the `RequestExtensions` message, potentially leading to a connection timeout.

- **Client Behavior**:
- Clients MUST NOT send any further protocol-specific messages until they receive a `RequestExtensions.Success` or `RequestExtensions.Error` response.
- If the client does not receive a response within a reasonable timeout period (e.g., X seconds, where X is implementation-defined), it SHOULD close the connection and report the timeout as an error.

This ensures clients can handle servers that do not implement extensions negotiation gracefully while avoiding indefinite blocking.

4. **Example Use Case**:
A client requesting support for extensions `0x0002` and `0x0003`:
```
Client --- RequestExtensions [0x0002, 0x0003] ---> Server
Client <--- RequestExtensions.Success [0x0002] ---- Server
```
The client now knows that extension `0x0003` is not supported and must adapt its behavior accordingly.