---
# System prepended metadata

title: Custom libp2p implementation

---

## Goals

- simplify
- ownership

## Constraint

- inter-operability with all libp2p implementations
- same interface as go-libp2p; it can be used in prysm simply by switching a feature flag
- at least same performance


## libp2p features recap

| libp2p feature                | Use in Prysm | Notes                                                                                  |
| ----------------------------- | ------------ | -------------------------------------------------------------------------------------- |
| Ping                          | ❌           |                                                                                        |
| Addressing                    | ✔️           | use multiaddress                                                                       |
| TCP                           | ✔️           |                                                                                        |
| QUIC                          | ✔️           |                                                                                        |
| WebSocket                     | ❌           |                                                                                        |
| WebRTC                        | ❌           |                                                                                        |
| TLS                           | ❌           |                                                                                        |
| Noise                         | ✔️           |                                                                                        |
| Early Multiplexer Negotiation | ✔️?          | [link](https://docs.libp2p.io/concepts/multiplex/early-negotiation/)                   |
| mplex                         | ✔️           |                                                                                        |
| yamux                         | ✔️           |                                                                                        |
| autonat                       | ✔️?          | not specified in Prysm, but enabled by default in go-libp2p                            |
| autonatv2                     | ❌           | not specified in Prysm, disabled by default in go-libp2p                               |
| circuit relay                 | ✔️          | disabled by default in prysm. no need to re-write ?                                                            |
| Hole Punching                 | ❌?          | not specified in Prysm, not sure if enabled by default in go-libp2p, I think it is not |
| UPNP                          | ✔️           | disabled by default in prysm, controled by NATPortMap option in go-libp2p              |
| boostrap discovery nodes      | ✔️           |                                                                                        |
| Kademlia                      | ❌           |                                                                                        |
| mdns                          | ❌           |                                                                                        |
| rendezvous                    | ❌           |                                                                                        |
| pubsub gossipsub              | ✔️           | no need to re-write ?                                                                  |

Maybe we should use [libp2p specs](https://github.com/libp2p/specs/tree/master), and note what we are going to keep, what we are going to remove, what we are going to add ?

## go-libp2p code tour

### Config

#### Removed unused options

go-libp2p offers a lot of options that we can remove because Prysm always use the same set of options.

Prysm construct a new libp2p object in two locations: `beacon-chain\p2p\options.go` and `cmd\prysmctl\p2p\client.go`.
Prysm use these options that can be configured:

- `libp2p.Identity`(set PeerKey)
- `ListenAddrs`
- `UserAgent`
- `ConnectionGater`
- `libp2p.Transport(libp2pquic.NewTransport)`
- `libp2p.Muxer("/mplex/6.7.0", mplex.DefaultTransport) + Muxer(yamux.ID, yamux.DefaultTransport)`
- `libp2p.NATPortMap` (enable UPnP)
- `libp2p.AddrsFactory` (used to enable relay and to set explicit host addresses and dns)
- `libp2p.DisableRelay`
- `libp2p.ResourceManager` to disable libp2p default resource manager

Prysm always set these options to always have the same value:

- `libp2p.Transport(libp2ptcp.NewTCPTransport)` We always want to run TCP
- `libp2p.Security(noise.ID, noise.New)` We always use noise
- `libp2p.Ping(false)` We always disable Ping service

#### Simplify defaults

go-libp2p use `FallbackDefaults` to set defaults values if certain conditions are met. In my opinion we should remove this logic and use something simpler, like setting the default values explicitly in the constructor:

_TODO_ List options with default values that we are going to use

- `Peerstore := pstoremem.NewPeerstore()`

### New libp2p host

#### Fx

To instanciate a new host, go-libp2p use [Fx](https://uber-go.github.io/fx/) as a dependency injector (see `NewNode()` in `config\config.go`).
In my opinion, using Fx will help with dependency managment. The lifecycle hooks have a great potential too.

_TODO_ Write an example of the same code with and without Fx.

_TODO_ Decide if Fx is really needed or not.

### Components

Libp2p use various components / abstractions. We are going to list them and see if we should implement them or not

![components](https://camo.githubusercontent.com/8c3da2eadf623888f440368fbdb5a05c0a5a3c18ee10d5f2631dcb6482861c80/68747470733a2f2f646f63732e676f6f676c652e636f6d2f64726177696e67732f642f314676553747496d527362394776415744446f316c6538356a49726e464a4e56425f4f54505843313557774d2f7075623f683d343830)

#### Conn

_TODO_

#### Swarm

_TODO_

#### Muxer

_TODO_

#### Network

_TODO_

#### Peerstore

_TODO_

#### Event Bus

Allow communication between components. Components can publish and subscribe to specific events.

_TODO_ List events we need to keep

## Simplify

### Remove unused features

Libp2p implements A LOT of features that are not used in Prysm.

#### Example - Remove ping service

Libp2p ping service is always disabled when Prysm instanciate a new libp2p object

```go
	options := []libp2p.Option{
		...
		libp2p.Ping(false), // Ping Service is always disabled
	}
```

So we can remove the matching entry in the config and the [Ping service](https://github.com/libp2p/go-libp2p/blob/master/p2p/protocol/ping/ping.go) itself.

```go
type Config struct {
	...
	DisablePing bool // No need for this anymore
}
```

And finally the `p2p\protocol\ping` folder

### Rewrite and simplify

_TODO_



### Presentation

Custom libp2p

- Introduction (Kira)
- What project is? (Max)
    - custom libp2p implementation
    - What is libp2p
        - Functionality, use case (in broader sense)
    - What we are supposed to do?
- Components or builds blocks of beaconChain p2p network (Richa)
- Roadmap (Rose)
    - Deep dive in the spec of `p2p-interface.md` from [consensus specs](https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/p2p-interface.md)
        - Thoroughly understand the various components involved in libp2p networking within the Ethereum beacon chain.
    - Use existing libp2p for references if needed
    - Follow spec to Implement the libp2p for prysm
        - Create a package that implements only the required components (golibp2p includes many components that Prysm does not use).
    - Develop and implement Extensive testing plan 
        - reference: https://docs.prylabs.network/docs/devtools/end-to-end)
        - https://docs.prylabs.network/docs/contribute/golang-principles
    - Replace the `golibp2p` implementation in the Prysm beacon node with the new in-house version, initially hidden behind a feature flag.
    - Compare the networking performance of the beacon node using the external and in-house implementations on the Holesky testnet
- Thanks


### References and resources

- [rlp](https://ethereum.org/developers/docs/data-structures-and-encoding/rlp)
- [snappy]( https://en.wikipedia.org/wiki/Snappy_(compression))
- [ssz](https://ethereum.org/developers/docs/data-structures-and-encoding/ssz)
- [blog](https://medium.com/coinmonks/dissecting-the-ethereum-networking-stack-node-discovery-4b3f7895f83f)
- [epf-wiki PR](https://github.com/eth-protocol-fellows/protocol-studies/pull/246/files)
