## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

- Auto
- Light
- Dark

# Algorand Specifications

Let’s define NWSNWS as an object that models a working Relay Network WSWS.

The Relay Network WSWS uses a websocket mesh for message transmission.

The following diagram is an overview of NWSNWS operations:

```
Message Handler thread

Startup

Setup

Message

Create WS Network

Create Phonebook

Create IdentityTracker

Initialize

Listener

Identity Scheme

Priority Handler

Serve & Listen

Message Handler

Check connection to peers
```

A minimal NWSNWS should have:

- A `GenesisID` identifying which network it is a part of (see [Ledger specifications](https://specs.algorand.co/ledger/ledger-genesis#genesis-identifier)),

- A `Phonebook` to bootstrap the peer discovery,

- A `PeerContainer` data structure to manage and iterate over peer connections (inbound and outbound),

- A `Broadcaster` to send messages to the network,

- A `MessageHandler` structure to route messages into the correct handlers,

- An `IdentityChallengeScheme` to execute the peer [identity challenge](https://specs.algorand.co/network/non-normative/network-nn-identity#websocket-network-identity-challenge),

- An `IdentityTracker`, for connection deduplication (e.g., to avoid self-gossip),

- Similarly to the identity challenge, a `priorityChallengeScheme` and `priorityTracker`,

- A flag indicating if the node wants to receive `TX` tagged messages ([transactions](https://specs.algorand.co/ledger/ledger-transactions)) or not,

- `lastNetworkAdvance`, the latest timestamp on which the Agreement protocol made notable progress.

The following sketch represents a typical topology of a Relay Network NWSNWS:

Let’s define PeerWSPeerWS as a data structure that holds all fields necessary for a Relay Network PeerPeer to function and collect functioning statistics.

PeerWSPeerWS must contain:

- `lastPacketTime`, an integer that represents the last timestamp at which a successful communication was established with the PeerPeer (either inbound or outbound),

- `requestNonce`, an unsigned 64-bit integer nonce, used to identify requests uniquely (so that identical requests do not get caught in deduplication),

- `priorityWeight`, an unsigned 64-bit integer that represents the priority of the PeerPeer inside the `peersheap` structure.

- Unsigned 64-bit integers to count messages of each type sent by this PeerPeer (that is, for each [`protocolTag`](https://specs.algorand.co/network/non-normative/network-nn-notation#protocol-tags)).

- A `readBuffer`, used to read incoming messages.

- Incoming and Outgoing message `filters`.

- Identity challenges metadata:
  - PeerPeer public key,
  - Challenge value
  - A flag indicating whether it has already been verified (see [Network identity challenge](https://specs.algorand.co/network/non-normative/network-nn-identity#websocket-network-identity-challenge)).
- Some connection metadata:
  - A flag indicating if it is inbound or outbound,
  - Timestamp at which the connection was established,
  - A map of messages allowed to be sent,
  - An average delay time (calculated by the [performance monitor](https://specs.algorand.co/network/non-normative/network-nn-parameters#performance-monitoring)).

Connections to peers are constantly monitored. Whenever a PeerPeer incurs in some behavior deemed harmful or adversarial (regardless of whether it is coordinated or accidental), the node may choose to disconnect from said PeerPeer after processing an incoming message ∗M∗M from said peer.

Disconnect reasons are modeled as a finite set of strings and would be part of the generated outbound message M∗M∗ suggesting a disconnection.

The following is a list of disconnection reasons:

| DISCONNECTION REASON | DESCRIPTION |
| --- | --- |
| `disconnectBadData` | The sender PeerPeer is serving wrongly constructed data |
| `disconnectReadError` | Error reading the incoming message from the `readBuffer` |
| `disconnectWriteError` | Error sending a message to the PeerPeer |
| `disconnectIdleConn` | The PeerPeer has been idle for a certain amount of time |
| `disconnectSlowConn` | The PeerPeer connection is slow |
| `disconnectLeastPerformingPeer` | The PeerPeer is the worst performing peer in the peers container |
| `disconnectCliqueResolve` | Node detected it is part of an isolated network partition |
| `disconnectRequestReceived` | Disconnection requested from the PeerPeer itself |
| `disconnectStaleWrite` | A write operation has not been successful |
| `disconnectDuplicateConnection` | The PeerPeer connection is already present |
| `disconnectBadIdentityData` | The PeerPeer address is misconstrued (or the identity challenge has failed) |
| `disconnectUnexpectedTopicResp` | The PeerPeer has gossiped a non-normative topic |
| `disconnectReasonNone` | No reason (included for completeness) |

The `connectionPerformanceMonitor` struct monitors connections’ performance by tracking various metrics such as the message arrival times, delays, and monitoring stages.

The following is a list of performance monitor fields in `go-algorand`:

| FIELD | DESCRIPTION |
| --- | --- |
| `monitoredConnections` | Maps connections being monitored. Messages from unmonitored connections are ignored |
| `monitoredMessageTags` | Maps message tagtag of interest. Typically, non-broadcast-type messages are monitored |
| `stage` | The current performance monitoring stage |
| `peerLastMsgTime` | Maps the timestamp of the last received message from each PeerPeer |
| `lastIncomingMsgTime` | Timestamp of the last received message from any PeerPeer |
| `stageStartTime` | Timestamp of the current stage start |
| `pendingMessagesBuckets` | Array of message buckets for messages not received from all peers within `pmMaxMessageWaitTime` |
| `connectionDelay` | Total delay sustained by each PeerPeer during monitoring stages and average delay afterward (in nanoseconds) |
| `firstMessageCount` | Maps peers to their accumulated first message count |
| `msgCount` | Total number of accumulated messages |
| `accumulationTime` | Duration for message accumulation, randomized to prevent cross-node synchronization |

The `PeersHeap` is a heap of PeerPeer entries.

This structure is used in the Relay Network and defines a weighted priority for connection to peers.

When a PeerPeer is added, it’s pushed on the `PeersHeap` with its weight, evicting the previous one.

The _network priority challenge_ is a two-way handshake that prioritizes connections resolving the challenge.

A _multiplexer_ is employed to route messages to their respective handlers according to protocol tagtag.
