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

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