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

Define ping/pong payload extensions #348

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
7 changes: 1 addition & 6 deletions beacon-chain/beacon-network.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,7 @@ The beacon chain network supports the following protocol messages:

#### `Ping.custom_data` & `Pong.custom_data`

In the beacon chain network the `custom_payload` field of the `Ping` and `Pong` messages is the serialization of an SSZ Container specified as `custom_data`:

```python
custom_data = Container(data_radius: uint256)
custom_payload = serialize(custom_data)
```
In the beacon chain network the `custom_payload` field of the `Ping` and `Pong` messages is the serialization of an SSZ Container specified as [Type 1 Basic Radius Payload](../ping-payload-extensions/extensions/type-1.md)

### Routing Table

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,7 @@ The canonical transaction index network supports the following protocol messages

#### `Ping.custom_data` & `Pong.custom_data`

In the canonical transaction index network the `custom_payload` field of the `Ping` and `Pong` messages is the serialization of an SSZ Container specified as `custom_data`:

```
custom_data = Container(data_radius: uint256)
custom_payload = SSZ.serialize(custom_data)
```
In the canonical transaction index network the `custom_payload` field of the `Ping` and `Pong` messages is the serialization of an SSZ Container specified as [Type 1 Basic Radius Payload](../ping-payload-extensions/extensions/type-1.md)


### Routing Table
Expand Down
6 changes: 1 addition & 5 deletions history/history-network.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,8 @@ The history network supports the following protocol messages:

#### `Ping.custom_data` & `Pong.custom_data`

In the history network the `custom_payload` field of the `Ping` and `Pong` messages is the serialization of an SSZ Container specified as `custom_data`:
In the history network the `custom_payload` field of the `Ping` and `Pong` messages is the serialization of an SSZ Container specified as [Type 2 History Radius Payload](../ping-payload-extensions/extensions/type-2.md)

```python
custom_data = Container(data_radius: uint256)
custom_payload = SSZ.serialize(custom_data)
```

### Routing Table

Expand Down
11 changes: 11 additions & 0 deletions ping-payload-extensions/extensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# This document lists defined extensions
This is a list and short description of all the extensions

- Extensions can be supported by all sub-networks or a subsection


| Type number | Name | Supported sub-networks | Short Description | Is this call Required to Implement |
|---|---|---|---|---|
| [0](extensions/type-0.md) | Client Info and Capabilities | All | Returns client info e.x. `trin/0.1.1-2b00d730/linux-x86_64/rustc1.81.0` and a list of enabled extensions | Yes |
| [1](extensions/type-1.md) | Basic Radius Payload | State, Beacon | Provides the nodes Radius | Yes |
| [2](extensions/type-2.md) | History Radius Payload | History | Provides the nodes radius and ephemeral header count | Yes |
26 changes: 26 additions & 0 deletions ping-payload-extensions/extensions/template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# [Title]

[Description]

Ping payload
```python

[Payload] = SSZ.serialize(Container([Key Value Pairs]))


[Container Name] = Container(
type: [Type Number],
payload: [Payload]
)
```

Pong payload
```python

[Payload] = SSZ.serialize(Container([Key Value Pairs]))

[Container Name] = Container(
type: [Type Number],
payload: [Payload]
)
```
42 changes: 42 additions & 0 deletions ping-payload-extensions/extensions/type-0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Client Info and Capabilities Payload

## Client Info
Client info are ASCII hex encoded strings.

Client info strings consist of 4 parts
- client name (e.x. `trin`,`fluffy`)
- client version + short commit (e.x. `0.1.1-2b00d730`)
- operating system + cpu archtecture (e.x. `linux-x86_64`)
- programming language + language version (e.x. `rustc1.81.0`)

Example
- String: `trin/0.1.1-2b00d730/linux-x86_64/rustc1.81.0`
- Hex encoding: `0x7472696E2F302E312E312D32623030643733302F6C696E75782D7838365F36342F7275737463312E38312E30`

#### Privacy Concerns
Clients can optionally return an empty string for privacy reasons, this is not recommended as client info helps researchers understand the network.

## Capabilities
Portal clients can only have max 400 extensions enabled per sub-network.

This payload provides a list of u16's each u16 provide in the list corresponds to an enabled extension type.

## Payload Outline

Ping and Pong Payload
```python

MAX_CLIENT_INFO_BYTE_LENGTH = 200
MAX_CAPABILITIES_LENGTH = 400

client_info_and_capabilities = SSZ.serialize(Container(
client_info: ByteList[MAX_CLIENT_INFO_BYTE_LENGTH]
capabilities: List[u16, MAX_CAPABILITIES_LENGTH]
))

CapabilitiesPayload = Container(
type: 0,
payload: client_info_and_capabilities
)
```

15 changes: 15 additions & 0 deletions ping-payload-extensions/extensions/type-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Basic Radius Payload

A basic Ping/Pong payload which only contains the nodes radius

Ping and Pong Payload
```python

basic_radius = SSZ.serialize(Container(data_radius: U256))

BasicRadiusPayload = Container(
type: 1,
payload: basic_radius
)
```

14 changes: 14 additions & 0 deletions ping-payload-extensions/extensions/type-2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# History Radius Payload

A specialized radius payload for the history network which contains field for how many ephemeral headers the node holds.

Ping and Pong Payload
```python

history_radius = SSZ.serialize(Container(data_radius: U256, ephemeral_header_count=U16))

HistoryRadiusPayload = Container(
type: 1,
payload: history_radius
)
```
85 changes: 85 additions & 0 deletions ping-payload-extensions/ping-custom-payload-extensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Ping Custom Payload Extensions

## Motivation

Ping Payload Extensions. There is a minimal set of `standard extensions` which require a breaking change to update. This framework allows Portal clients to implement `non standard extensions` which don't require a breaking change to deploy to the network. A more flexible way to extend the Protocol without bloating the [Portal-Wire-Protocol](../portal-wire-protocol.md)

# Type's

There are 65536 unique type ids.

Types 0-10_000 and 65436-65535 are reserved for for future upgrades.

The rest are first come first serve, but they should still be defined in this repo to avoid overlaps.


## Requirements

All payloads used in the Ping `custom_payload` MUST follow the `Ping Custom Payload Extensions` format.

## Custom Payload Extensions Format

- **type**: numeric identifier which tells clients how the `payload` field should be decoded.
- **payload**: the SSZ encoded extension payload


```python
CustomPayloadExtensionsFormat = Container(
type: u16,
payload: ByteList[max_length=1100]
)
```

## Ping vs Pong
The relationship between Ping and Pong message will be determined by the requirements of the type.

Currently type 1,2,3 are symmetrical, having the same payload for both request and response. This symmetry is not required. Extensions may define separate payloads for Ping and Pong within the same type.


### Error responses
If the ping receiver can't handle the ping for any reason the pong should return an error payload

Pong payload
```python

# Max ASCII hex encoded strings length
MAX_ERROR_BYTE_LENGTH = 300

error_payload = SSZ.serialize(Container(error_code: u16, message: ByteList[MAX_ERROR_BYTE_LENGTH]))

ErrorPayload = Container(
type: 65535,
payload: error_payload
)
```

### Error Code's

#### 0: Extension not supported
This code should be returned if the extension isn't supported. This error should only be returned if
- The extension isn't supported
- The extension isn't a required extension for specified Portal Network.

#### 1: Requested data not found
This error code should be used when a client is unable to provide the necessary data for the response.

#### 2: Failed to decode payload
Wasn't able to decode the payload

#### 3: System error
A critical error happened and the ping can't be processed

## Standard extensions

Every Portal Network Client is required to support 3 extensions
- [Type 0: Capabilities Payload](extensions/type-0.md): useful for finding what ping extensions a client supports
- Sub-network standard extension. For history this is currently [Type 2: History Radius Payload](extensions/type-2.md). For State and Beacon the base extension is [Type 1: Basic Radius Payload](extensions/type-1.md). These are extensions what are crucial. This standard extensions are specified the respective sub-networks specification
- Type 3: [Get Client info Payload](extensions/type-3.md)
Copy link
Member

Choose a reason for hiding this comment

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

I suggest we remove this from the standard set. Clients should support it but I don't think it makes sense to make it be required.

Copy link
Member Author

@KolbyML KolbyML Nov 21, 2024

Choose a reason for hiding this comment

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

I think it is fine to make it so a valid option is an empty string for privacy inclined users, but I don't think we should remove it from being a standard extension, as 99.9% of honest Portal nodes would support it. Client Info is important for

  • getting better statistics of our network,
    • useful for glados
    • tells us what platforms our popular and we should support better e.x. x86/arm/riscv5
  • allows us to better track what client is creating bugs on the network. Are they running an old commit? Is it a CPU architecture specific issue? etc

If this isn't a standard extension it would require

  • one ping to get capabilities
  • one ping to get client info

If 99.9% of honest clients are going to support this call, I think it should be a standard extension, with an opt out to return an empty string by the 0.001% of users which have a privacy concern.

Copy link
Member

Choose a reason for hiding this comment

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

I think I agree with this. Will set the default path towards clients supporting this which I think is positive for network monitoring/health.

Copy link
Collaborator

@kdeme kdeme Nov 21, 2024

Choose a reason for hiding this comment

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

If it is fine to just be an empty string, then it is a bit silly to send this around as another message req/rep for those that want to keep that private.

Perhaps just add it as a field in the capabilities extension?

Copy link
Member

Choose a reason for hiding this comment

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

Perhaps just add it as a field in the capabilities extension?

I actually like this. Removes an additional message pair and makes it so that this data gets transmitted implicitly with the other message.

Copy link
Member Author

Choose a reason for hiding this comment

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

I will update the PR to make it so client info is a part of the capabilities extension, this will limit the max amount of ping extensions a client can have enabled at a time to 450 or 400 instead of 500 to reserve byte space for the client enough, but 400 extensions should be more then enough so it isn't a deal breaker at the end of the day.

Copy link
Collaborator

Choose a reason for hiding this comment

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

To be honest, I don't think anybody would want to be writing Portal implementations if they have to deal with 400 (or even 40 for that matter) ping extensions :).

Copy link
Member Author

@KolbyML KolbyML Nov 22, 2024

Choose a reason for hiding this comment

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

To be honest, I don't think anybody would want to be writing Portal implementations if they have to deal with 400 (or even 40 for that matter) ping extensions :).

The whole point is they are optional, so Portal implementation that didn't want to implement something wouldn't have to. I don't know what will happen in the future or how extensions we would be adopted. So who knows how many would end up being used.

I don't see an issue in having some head room


## What is the [Type 0: Capabilities Payload](extensions/type-0.md) for
It is for Portal implementations which want to see what extensions a peer supports. Not all extensions need to be implemented by all parties. So in order for a peer to find if an extension is implemented a [Type 0: Capabilities Payload](extensions/type-0.md) should be exchanged.

Non-required extension offer a way for Portal implementations to offer extended functionality to its users without requiring every Portal implementing party to agree to a new feature. This allows for a diverse set of use cases to be fulfilled without requiring every implementer implement every extension, or requiring the need to bloat the minimal [Portal-Wire-Protocol](../portal-wire-protocol.md) with new `Message Types`.

## How do sub-network standard extension's work
sub-network standard extension's are fundamental extensions that are required for a Portal sub-network to function. They must be supported by the sub-networks implementations.
7 changes: 1 addition & 6 deletions state/state-network.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,7 @@ The execution state network supports the following protocol messages:

#### `Ping.custom_data` & `Pong.custom_data`

In the execution state network the `custom_payload` field of the `Ping` and `Pong` messages is the serialization of an SSZ Container specified as `custom_data`:

```
custom_data = Container(data_radius: uint256)
custom_payload = SSZ.serialize(custom_data)
```
In the execution state network the `custom_payload` field of the `Ping` and `Pong` messages is the serialization of an SSZ Container specified as [Type 1 Basic Radius Payload](../ping-payload-extensions/extensions/type-1.md)

#### POKE Mechanism

Expand Down
14 changes: 1 addition & 13 deletions transaction-gossip/transaction-gossip.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,7 @@ The network uses the PING/PONG/FINDNODES/FOUNDNODES/OFFER/ACCEPT messages from t

The network uses the standard XOR distance function.

### PING payload

```
Ping.custom_payload := ssz_serialize(custom_data)
custom_data := Container(transaction_radius: uint256)
```

### PONG payload

```
Pong.custom_payload := ssz_serialize(custom_data)
custom_data := Container(transaction_radius: uint256)
```
In the execution state network the `custom_payload` field of the `Ping` and `Pong` messages is the serialization of an SSZ Container specified as [Type 1 Basic Radius Payload](../ping-payload-extensions/extensions/type-1.md)

## Content Keys

Expand Down
Loading