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

Issue 650 authority discovery #669

Merged
merged 15 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from 8 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
169 changes: 167 additions & 2 deletions docs/chap-networking.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Complete specification of the Polkadot networking protocol relies on the followi

Each Polkadot Host node maintains an ED25519 key pair which is used to identify the node. The public key is shared with the rest of the network allowing the nodes to establish secure communication channels.

Each node must have its own unique ED25519 key pair. If two or more nodes use the same key, the network will interpret those nodes as a single node, which will result in unspecified behavior. Furthermore, the node’s *PeerId* as defined in [Definition -def-num-ref-](chap-networking#defn-peer-id) is derived from its public key. *PeerId* is used to identify each node when they are discovered in the course of the discovery mechanism described in [Section -sec-num-ref-](chap-networking#sect-discovery-mechanism).
Each node must have its own unique ED25519 key pair. If two or more nodes use the same key, the network will interpret those nodes as a single node, which will result in unspecified behavior. Furthermore, the node’s *PeerId* as defined in [Definition -def-num-ref-](chap-networking#defn-peer-id) is derived from its public key. *PeerId* is used to identify each node when they are discovered in the course of the discovery mechanism described in [Section -sec-num-ref-](chap-networking#sect-network-bootstrap).

###### Definition -def-num- PeerId {#defn-peer-id}
:::definition
Expand Down Expand Up @@ -74,7 +74,7 @@ $$
- ${b}_{{4}}$, ${b}_{{5}}$ and ${b}_{{{6}.{.37}}}$ are a protobuf encoded field-value pair where ${b}_{{5}}$ indicates the length of the public key followed by the the raw ED25519 public key itself, which varies for each Polkadot Host and is always 32 bytes (field ${2}$ contains the public key, which has a field value length prefix).

:::
## -sec-num- Discovery mechanism {#sect-discovery-mechanism}
## -sec-num- Network bootstrap and discovery {#sect-network-bootstrap}
heversonbr marked this conversation as resolved.
Show resolved Hide resolved

The Polkadot Host uses various mechanisms to find peers within the network, to establish and maintain a list of peers and to share that list with other peers from the network as follows:

Expand Down Expand Up @@ -214,6 +214,171 @@ The Polkadot Host must actively communicate with the network in order to partici
The Polkadot network originally only used SCALE encoding for all message formats. Meanwhile, Protobuf has been adopted for certain messages. The encoding of each listed message is always SCALE encoded unless Protobuf is explicitly mentioned. Encoding and message formats are subject to change.
:::


<!-- authority discovery -->

### -sec-num- Discovering authorities {#sect-authority-discovery}

<!-- what it is -->
A discovery mechanism enables Polkadot nodes to both publish their local addresses and learn about other nodes identifiers and addresses.
The Authority discovery mechanism differs from the bootstrap mechanism, described in [Section -sec-num-ref-](chap-networking#sect-network-bootstrap), in that it restricts the discovery output to nodes currently holding the authority role (e.g., validators).

The authority discovery mechanism consists of two main interfaces. A `service` interface that exposes two functions that allow Polkadot nodes to request `identifiers` or `addresses` of current authority nodes. A `worker` interface that provides means of interacting with the Kademlia DHT in order to publish local node addresses and discover the addresses of other authority nodes.

```
-------
| Node |
-------
|
---------------------
| Discovery Authority |
---------------------
|
-------
| DHT |
-------
```

<!-- POLKADOT NODES interacting with AUTHORITY DISCOVERY -->
#### -sec-num- Requesting authority identifier and addresses {#sect-auth-discovery-service-requests}
<!-- `GetAuthorityIdsByPeerId` and `GetAddressesByAuthorityId` are the type of message sent from `service` to `worker` in order to receive the information requested by polkadot nodes. However, this is a implementation detail that can be transparent to developers.
-->
The following requests are exposed by the discovery authority mechanism to Polkadot nodes.

###### Definition -def-num- Authority addresses request {#defn-auth-discovery-address-request}
:::definition

heversonbr marked this conversation as resolved.
Show resolved Hide resolved
An **authority addresses request** is a request that Polkadot nodes can send to the authority discovery mechanism in order to request the addresses of an authority node. The request has the following format:

$$
\texttt{get\_addresses\_by\_authority\_id}{\left(\texttt{authorityId}\right)}
$$

**where**
- $\texttt{authorityId}$ is the `authorityId` 256-bit identifier representing the public key of the targeted authority node.


**expected response**

The response to the previous query includes an enum with one of the following values:
<!-- Option<HashSet<Multiaddr>> -->

| Value | Description |
|----------------------|--------------------------------------------------------|
| None | A type representing `no value` |
| HashSet[Multiaddr] | An unordered collection of unique `Multiaddr` elements |


**with**
- `Multiaddr` a [Multiaddr](https://github.com/libp2p/specs/blob/master/addressing/README.md#multiaddr-in-libp2p) data structure.

:::


<!-- get_authority_ids_by_peer_id(PeerId) -->
###### Definition -def-num- Authority identifier request {#defn-auth-discovery-auth-identifier-request}
:::definition

An **authority identifier request** is a request that polkadot nodes can send to the authority discovery mechanism in order to request the `AuthorityId` of an authority node. The request has the following format:

$$
\texttt{get\_authority\_ids\_by\_peer\_id}{\left(\texttt{PeerId}\right)}
$$

**where**
- $\texttt{PeerId}$ is the Polkadot node’s PeerId ([Definition -def-num-ref-](chap-networking#defn-peer-id)).


**expected response**
<!-- Since we may store the mapping across several sessions, a single. `PeerId` might correspond to multiple `AuthorityId`s -->
The response to the previous query includes an enum with one of the following values:
<!-- Option<HashSet<AuthorityDiscoveryId> -->

| Value | Description |
|------------------------|--------------------------------------------------------|
| None | A type representing `no value` |
| HashSet[authorityId] | An unordered collection of unique `authorityId` elements |


**with**
- `authorityId` the 256-bit identifier representing the public key of the requested `PeerId`.

:::


<!-- AUTHORITY DISCOVER interacting with KADEMLIA -->
#### -sec-num- Publishing addresses {#sect-auth-discovery-worker-publishing}


The authority discovery mechanism ensures up-to-date addresses for authority nodes by periodically publishing and discovering addresses into the DHT.

In order to publish on the DHT, the authority discovery mechanism periodically triggers a `put_value` operation that stores a `SignedAuthorityRecord` of the addresses of authorities it knows from its current and next authority sets into the DHT. The `put_value` operation is created as follows.


###### Definition -def-num- Signed Authority Record {#defn-signed-authority-record}
:::definition

The `SignedAuthorityRecord` is a Protobuf serialized structure representing the authority records and signature to send over the wire.
It is defined in the following format:

| Type | Id | Description |
|--------------------|-----|-------------------------------------------------------|
| *AuthorityRecord* | 1 | Serialized authority record |
| `bytes` | 2 | An Schnorrkel/Ristretto x25519 ("sr25519") signature |
| *PeerSignature* | 3 | Serialized peer signature |

**where**

**AuthorityRecord** is a serialized Protobuf structure that lists the addresses of authority nodes that are currently part of the authority set.

| Type | Id | Description |
|------------------|----|-----------------------------------------------------------------------|
| `repeated bytes` | 1 | Binary representation of zero or more multiaddresses through which a node is reachable |

**PeerSignature** is a Protobuf serialized structure indicating the signature and public key used to sign and verify the `AuthorityRecord`.
This is the protobuf structure used to exchange the signature with other nodes.

| Type | Id | Description |
|---------|-----|---------------------------------------------------|
| `bytes` | 1 | An sr25519 signature |
| `bytes` | 2 | A sr25519 public key used to verify the signature |

:::


###### Definition -def-num- Publish addresses operation {#defn-auth-discovery-publish}
:::definition

For each authority node $i$ in the current authority set, the local node invokes a `put_value` operation that triggers a store operation into the DHT with the following format:

$$
\texttt{put\_value}{\left(\texttt{KademliaKey}_{i} , \texttt{Sig}_{AR}\right)}
$$

**where**
- $\texttt{KademliaKey}_{i}$ is the $Sha256$ hash of the authorityId of node $i$.
- $\texttt{Sig}_{AR}$ is the `SignedAuthorityRecord`
described above([Definition -def-num-ref-](chap-networking#defn-signed-authority-record)).
:::


#### -sec-num- Discovering authority addresses {#sect-auth-discovery-worker-discover}
<!-- worker component -->
The authority discovery mechanism periodically invokes `get_value` operation on the DHT in order to discover the addresses of authority nodes it knows about.

###### Definition -def-num- Discover addresses operation {#defn-msg-auth-discovery-lookup}
:::definition

Periodically, the authority discover performs a bounded number of `get_value` operations in the following format:
$$
\texttt{get\_value}{\left(\texttt{KademliaKey}_{i}\right)}
$$

**where**
- $\texttt{KademliaKey}_{i}$ is the $Sha256$ hash of the `authorityId` of node $i$ selected from the current authority set.
:::


### -sec-num- Announcing blocks {#sect-msg-block-announce}

When the node creates or receives a new block, it must be announced to the network. Other nodes within the network will track this announcement and can request information about this block. The mechanism for tracking announcements and requesting the required data is implementation-specific.
Expand Down
2 changes: 1 addition & 1 deletion docs/chap-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ While the full node is still a mostly passive participant of the protocol, they

1. The node must populate the state storage with the official genesis state, elaborated further in [Section -sec-num-ref-](id-cryptography-encoding#section-genesis).

2. The node should maintain a set of around 50 active peers at any time. New peers can be found using the discovery protocols ([Section -sec-num-ref-](chap-networking#sect-discovery-mechanism))
2. The node should maintain a set of around 50 active peers at any time. New peers can be found using the discovery protocols ([Section -sec-num-ref-](chap-networking#sect-network-bootstrap))

3. The node should open and maintain the various required streams ([Section -sec-num-ref-](chap-networking#sect-protocols-substreams)) with each of its active peers.

Expand Down
Loading