Skip to main content

# 3.3 Peer Discovery

## 3.3.1 Introduction​

This section defines the Peer Discovery protocol, its logic and the different requests and responses exchanged.

In order to establish connections, an IOTA node needs to discover and maintain a list of the reachable IP addresses of other peers. Moreover, some external modules, such as the Neighbor Selection and the Fast Probabilistic Consensus (FPC) may require an updated list of known peers.

The main goal of the Peer Discovery protocol is to expose an interface providing a list of all the verified peers.

Throughout this section the terms Node and Peer are used interchangeably to refer to a Node device.

The usage of the Ping and Pong mechanism is to be considered as a bidirectional exchange similarly to how described by other standards such as CoAP and WebSocket.

## 3.3.2 Detailed Design​

To bootstrap the peer discovery, a node must be able to reach one or more entry nodes. To achieve this, the implementation of the protocol shall provide a hard-coded list of trusted entry nodes run by the IF or by trusted community members that answer to peer discovery packets coming from new nodes joining the IOTA network. This approach is a common practice of many distributed networks [Neudecker 2018]. Public Key-based Cryptography (PKC) shall be used for uniquely identifying peers and for authenticating each packet. The usage of the Ping and Pong protocols is that Ping are sent to verify a given peer and, upon reception of a valid Pong as a response from that peer, the peer is verified. Once a peer has been verified, it can be queried to discover new peers by sending a DiscoveryRequest. As a response, a DiscoveryResponse shall be returned, containing a list of new peers. The new peer nodes in this list shall be verified by the receiving application.

This process is summarized in the following figure and detailed in the following subsections:

### 3.3.2.1 Node Identities​

Every node has a cryptographic identity, a key on the ed25519 elliptic curve. The blake2b hash of the public key of the peer serves as its identifier or node ID.

### 3.3.2.2 Verification​

The verification process aims at both verifying peer identities and checking their online status. Each peer shall maintain a list of all the known peers. This list shall be called known_peer_list. Elements of any known peer list shall contain a reference to a Peer and a time at which it shall be verified/re-verified. As such, the known_peer_list can be seen as a time-priority queue. A newly discovered peer gets added to the list at the current time. Whenever a peer is verified, its time value on the known_peer_list gets updated to the time at which that peer shall be re-verified. The intent of this arrangement is to allow the node application to first verify newly discovered (and thus still unverified) peers and then to re-verify older peers (to confirm their online status) by iterating over the known_peer_list. It is worthwhile to note that the order in which the known_peer_list is worked through is important. For example, if the peer is added to the front ('head') of the known_peer_list, it is possible for an adversary to front-fill the known_peer_list with a selection of its own nodes. This is resolved by the use of the time-priority queue.

The verification process always initiates from a Ping. Upon reception of a Ping, a peer shall check its validity by:

• verifying that the signature of the Ping is valid and discarding the request otherwise;
• checking that the version and network_id fields match its configuration and discarding the Ping otherwise;
• checking that the timestamp field is fresh (i.e., not older than a given time) and discarding the packet otherwise;
• checking that the dest_addr matches its IP address and discarding the Ping otherwise.

Upon successful validation of a received Ping, a peer shall respond with a Pong. In case the sender of the Ping is a new peer from the perspective of the receiving node, the receiver peer shall add it to its known_peer_list. This enables the verification process to also occur in the reverse direction.

Upon reception of a Pong, a peer shall check its validity by:

• verifying that the signature of the Pong is valid and discarding it otherwise;
• checking that the req_hash field matches a request (i.e. Ping) previously sent and not expired (i.e., the difference between the timestamp of the Ping and Pong is not greater than a given threshold) and discarding the associated Ping or Pong otherwise;
• checking that the dest_addr matches its IP address and discarding the associated Ping or Pong otherwise.

Upon successful validation of a received Pong, a peer shall:

• add the peer sender of the Pong to a list of verified peers called verified_peer_list;
• move the peer entry of the known_peer_list to the tail.

### 3.3.2.3 Removal​

While verifying a new peer, if no or an invalid Pong is received after max_verify_attempts attempts, that node shall be removed from the known_peer_list. Each expected reply should have a timeout such that if no answer is received after that, an attempt is considered concluded and counted as failed.

Each peer on the verified_peer_list shall be re-verified after verification_lifetime hours; while re-verifying a peer, if no or invalid Pong is received after max_reverify_attempts attempts, the peer shall be removed from the verified_peer_list.

### 3.3.2.4 Discovery​

Each peer entry of the verified_peer_list may be used to discover new peers. This process is initiated by sending a DiscoveryRequest.

Upon reception of a DiscoveryRequest, a peer node shall check its validity by:

• checking that the sender of the DiscoveryRequest is a verified peer (i.e. is stored in the verified_peer_list) and discarding the request otherwise;
• verifying that the signature of the DiscoveryRequest is valid and discarding the request otherwise;
• checking that the timestamp field is fresh (i.e., not older than a given time) and discarding the request otherwise.

Upon successful validation of a received DiscoveryRequest, a peer shall reply with a DiscoveryResponse.

Upon reception of a DiscoveryResponse, a peer shall check its validity by:

• verifying that the signature of the DiscoveryResponse is valid and discarding the response otherwise;
• checking that the req_hash field matches a discovery request (i.e. DiscoveryRequest) previously sent and not expired (i.e., the difference between the timestamp of the DiscoveryRequest and DiscoveryResponse is not greater than a given threshold) and discarding the response otherwise.

Upon successful validation of a received DiscoveryResponse, a node shall add the nodes contained in the peers field to the known_peer_list.

### 3.3.2.5 Ping and Pong Layout​

Each Ping and Pong shall be encapsulated into a data field of a generic Request and Response. Its type shall be specified in the type field. Each request and response shall be signed with the ed25519 private key of the sender's identity and shall contain the related public key, in order to allow the packet receiving node to verify the signature. All the received responses shall be verified and those with invalid signature shall be discarded.

#### Request and Response Layout​

NameTypeDescription
typeuint8Defines the type of the request or response.
dataByteArraycontains the payload of the request or response (e.g., a Ping).
public_keyByteArray[32]The ed25519 public key of the peer's identity used to verify its signatures.
signatureByteArray[32]The ed25519 signature of the data field, signed by using the private key of the peer's identity.

#### Ping​

NameTypeDescription
versionuint32The version of the protocol.
network_iduint32The network identifier.
timestamptimeThe unix timestamp of the Ping.
src_addrstringThe IP address, in string form, of the sender (e.g., "192.0.2.1", "[2001:db8::1]").
src_portuint32The listening port of the sender.
dst_addrstringThe string form of the receiver's IP address. This provides a way to discover the external address (after NAT).

#### Pong​

NameTypeDescription
req_hashByteArray[32]The blake2b digest of the corresponding received Ping.
services
Services supported by the Pong sender.
NameTypeDescription
serviceIDByteArray[32]The service ID (e.g., autopeering, gossip, fpc).
networkstringThe string form of the network (e.g., udp, tcp).
portuint32The listening port of the service.
dst_addrstringthe string form of the receiver's IP address. This MUST mirror the src_addr of the Ping's IP packet. It provides a way to discover the external address (after NAT).

#### DiscoveryRequest​

NameTypeDescription
timestamptimeThe unix timestamp of the DiscoveryRequest.

#### DiscoveryResponse​

NameTypeDescription
req_hashByteArray[32]The blake2b digest of the corresponding received DiscoveryRequest.
peers
The list of some randomly chosen peers known by the sender of the DiscoveryResponse between(1,6).
NameTypeDescription
public_keyByteArray[32]The ed25519 public key of the peer's identity used to verify its signature.
ipstringThe string form of the peer's IP address.
services
Services supported by the peer.
NameTypeDescription
serviceIDByteArray[32]The service ID (e.g., autopeering, gossip, fpc).
networkstringThe string form of the network (e.g., udp, tcp).
portuint32The listening port of the service.

### 3.3.2.6 Denial of Service​

All the requests and responses exchanged during the Peer Discovery protocol are sent via UDP. As such, any UDP based Denial of Service attack could harm the normal functionality of the protocol. To limit this, hardware based protection such as Firewall or alternatively, rate limiting the incoming requests and responses via leaky/token buckets based techniques could be used.