## 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

> The Peer-to-Peer Network is currently in experimental mode!

Let’s define NPNP as an object that models a working Peer-to-Peer Network P2PP2P.

A minimal NPNP 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 `PeerStore` container to keep peer data and expose relevant connection metadata
(see [Peer management section](https://specs.algorand.co/network/non-normative/network-nn-peer-management)),

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

- A `topicTags` mapping of the form (`protocolTag -> string`), which represents
which tagtag to use with `GossipSub`, mapped to topic names[1](https://specs.algorand.co/network/non-normative/network-nn-definitions-p2p#footnote-1).

- A set of primitives taken or adapted from the Relay Network WSWS and
PeerPeer, to support WSWS messages:
  - The generic `MessageHandler` to route WSWS messages to the appropriate
    message handler,
  - PeerPeer connectivity monitoring utilities,
  - A mapping of `PeerID` to WSWS peers, and a mapping of WSWS peers
    to `PeerID` (this is to get O(1)O(1) lookup in both ways),
- A flag indicating if the node wants to receive `TX` tagged messages
( [transactions](https://specs.algorand.co/ledger/ledger-transactions)) or not,

- A `capabilitiesDiscovery` structure abstracting all functionalities to advertise
nd discover peers for specific capabilities (see [section below](https://specs.algorand.co/network/non-normative/network-nn-definitions-p2p#node-capabilities)).

A P2PP2P network implements the `GossipNode` interface to manage peer-to-peer
communication.

Currently, transactions are distributed using the `GossipSub` protocol (`/meshsub/1.1.0`).
All other messages are forwarded over a stream `/algorand-ws/1.0.0` that uses the
same message serialization as the existing [Relay Network](https://specs.algorand.co/network/non-normative/network-nn-definitions-ws)
implementation. These two streams are multiplexed over a single connection.

The following sketch represents a typical topology of a Peer-to-Peer Network NPNP,
where:

- PP represents a _peer node_,
- PpPp represents a _peer node_ connected to PP,
- A PpPp is connected on average to 4P4P.

The _publishing/subscribing_ (`pubsub`) protocol is a system where peers congregate
around _topics_ they are interested in.

Peers interested in a _topic_ (identified by a simple string) are said to be _subscribed_
to that topic.

Functionally, topics can be thought of as generators of _sub-networks_: peers _subscribed_
to a topic are _discoverable_ and _addressable_ by other peers capable of serving
data about that topic.

The _topic_ used to subscribe to transaction gossiping is `algotx01`.

The naming convention used for the _topics_ is: the word `algo`, followed by a 2-byte
protocol tagtag (`TX` in this case) followed by the 2-byte version identifier
(`01` in this case).

The `makePubSub(.)` function initializes the `pubsub` protocol with a list of options
that set parameters for peer scoring, topic filters, message validation, and subscription
handling.

- **Peer Scoring**: sets peer score parameters, like the `FirstMessageDeliveriesWeight`,
which scores peers based on the promptness of message delivery,

- **Subscription Filters**: limits subscriptions to the `algotx01` topic,

- **Validation Queue Size**: configures the validation queue[2](https://specs.algorand.co/network/non-normative/network-nn-definitions-p2p#footnote-2).

The `pubsub` protocol makes use of the following functions:

- `Publish(topic string, data []byte)`: Sends data to a specific topic’s subscribers.
After verifying that the topic exists, the data is propagated across the network.

- `ListPeersForTopic(topic string) -> []PeerID`: Retrieves a list of peers currently
subscribed to a given topic, making it accessible to other parts of the network layer.

- `Subscribe(topic string)`: Subscribes to a topic, advertising the network about
peer’s intention of sending and receiving data on the topic.

- `getOrCreateTopic(topicName string)`: Attempts to fetch the topic if already mapped,
otherwise it creates a local register of it and joins its subscribers.

The following is an enumeration of `pubsub` _message validation_ results (where
`ValidationResult` is an alias for a signed integer):

- `ValidationAccept(0)` indicates a valid message that should be accepted, delivered
to the application, and forwarded to the network.

- `ValidationReject(1)` indicates an invalid message that should not be delivered
to the application or forwarded to the network. Furthermore, the peer that forwarded
the message should be penalized by peer-scoring routers.

- `ValidationIgnore(2)` and `validationThrottled(-1)` are `libp2p` internals that
should not be exposed.

With direct P2PP2P network support, the notion of node capabilities acquires
importance.

The capabilities of a P2PP2P node are:

- **Archival**: holds the entire history of the blockchain,

- **Catchpoint Storing**: stores catch-point files and provides catch-point labels
to node synchronizing with the network using a _fast catch-up_.

- **Gossip**: act as a permissionless _relay node_, able to perform network-level
validation of messages and efficiently route them to peers.

Each node advertises its capabilities and keeps track of peers in a [distributed hash table](https://specs.algorand.co/network/non-normative/network-nn-definitions-p2p#distributed-hash-table-dht).

Peer-to-Peer networks, such as IPFS, use _distributed hash tables_ (DHT) to look
up files in the network. A DHT is a distributed system for mapping keys to values,
storing resource locations throughout the network.

> IPFS DHT is based on the [Kadmelia algorithm](https://docs.ipfs.tech/concepts/dht/#kademlia),
as a fundamental component for the content routing system, and acts like a cross
between a catalog and a navigation system. It maps what users want to the peers
storing the matching content.

The Algorand node reference implementation (`go-algorand`) uses [Kadmelia DHT](https://github.com/libp2p/go-libp2p-kad-dht),
to keep track of the peers’ capabilities.
