P2P: Add QUIC support (#13786)

* (Unrelated) DoppelGanger: Improve message.

* `beacon-blocks-by-range`: Add `--network` option.

* `ensurePeerConnections`: Remove capital letter in error message.

* `MultiAddressBuilder{WithID}`: Refactor.

* `buildOptions`: Improve log.

* `NewService`: Bubbles up errors.

* `tcp` ==> `libp2ptcp`

* `multiAddressBuilderWithID`: Add the ability to build QUIC multiaddr

* `p2p Start`: Fix error message.

* `p2p`: Add QUIC support.

* Status: Implement `{Inbound,Outbound}Connected{TCP,QUIC}`.

* Logging: Display the number of TCP/QUIC connected peers.

* P2P: Implement `{Inbound,Outbound}ConnectedWithProtocol`.

* Hide QUIC protocol behind the `--enable-quic` feature flag.

* `e2e`: Add `--enable-quic` flag.

* Add `--enable-quic` in `devModeFlag`.

* `convertToMultiAddrs` ==> `retrieveMultiAddrsFromNode`.

* `convertToAddrInfo`: Ensure `len(infos) == 1`.
This commit is contained in:
Manu NALEPA
2024-04-04 14:21:35 +02:00
committed by GitHub
parent 8cf5d79852
commit be1bfcce63
29 changed files with 705 additions and 165 deletions

View File

@@ -90,6 +90,7 @@ var appFlags = []cli.Flag{
cmd.StaticPeers,
cmd.RelayNode,
cmd.P2PUDPPort,
cmd.P2PQUICPort,
cmd.P2PTCPPort,
cmd.P2PIP,
cmd.P2PHost,

View File

@@ -55,6 +55,7 @@ var appHelpFlagGroups = []flagGroup{
cmd.BootstrapNode,
cmd.RelayNode,
cmd.P2PUDPPort,
cmd.P2PQUICPort,
cmd.P2PTCPPort,
cmd.DataDirFlag,
cmd.VerbosityFlag,

View File

@@ -113,13 +113,19 @@ var (
// P2PUDPPort defines the port to be used by discv5.
P2PUDPPort = &cli.IntFlag{
Name: "p2p-udp-port",
Usage: "The port used by discv5.",
Usage: "The UDP port used by the discovery service discv5.",
Value: 12000,
}
// P2PTCPPort defines the port to be used by libp2p.
// P2PQUICPort defines the QUIC port to be used by libp2p.
P2PQUICPort = &cli.IntFlag{
Name: "p2p-quic-port",
Usage: "The QUIC port used by libp2p.",
Value: 13000,
}
// P2PTCPPort defines the TCP port to be used by libp2p.
P2PTCPPort = &cli.IntFlag{
Name: "p2p-tcp-port",
Usage: "The port used by libp2p.",
Usage: "The TCP port used by libp2p.",
Value: 13000,
}
// P2PIP defines the local IP to be used by libp2p.

View File

@@ -43,6 +43,7 @@ go_library(
"@com_github_libp2p_go_libp2p//core/peer:go_default_library",
"@com_github_libp2p_go_libp2p//core/protocol:go_default_library",
"@com_github_libp2p_go_libp2p//p2p/security/noise:go_default_library",
"@com_github_libp2p_go_libp2p//p2p/transport/quic:go_default_library",
"@com_github_libp2p_go_libp2p//p2p/transport/tcp:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_fastssz//:go_default_library",

View File

@@ -14,7 +14,8 @@ import (
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/protocol"
"github.com/libp2p/go-libp2p/p2p/security/noise"
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic"
libp2ptcp "github.com/libp2p/go-libp2p/p2p/transport/tcp"
"github.com/pkg/errors"
ssz "github.com/prysmaticlabs/fastssz"
"github.com/prysmaticlabs/go-bitfield"
@@ -43,7 +44,7 @@ type client struct {
nodeClient pb.NodeClient
}
func newClient(beaconEndpoints []string, clientPort uint) (*client, error) {
func newClient(beaconEndpoints []string, tcpPort, quicPort uint) (*client, error) {
ipAdd := ipAddr()
priv, err := privKey()
if err != nil {
@@ -53,15 +54,16 @@ func newClient(beaconEndpoints []string, clientPort uint) (*client, error) {
if err != nil {
return nil, errors.Wrap(err, "could not set up p2p metadata")
}
listen, err := p2p.MultiAddressBuilder(ipAdd.String(), clientPort)
multiaddrs, err := p2p.MultiAddressBuilder(ipAdd, tcpPort, quicPort)
if err != nil {
return nil, errors.Wrap(err, "could not set up listening multiaddr")
}
options := []libp2p.Option{
privKeyOption(priv),
libp2p.ListenAddrs(listen),
libp2p.ListenAddrs(multiaddrs...),
libp2p.UserAgent(version.BuildData()),
libp2p.Transport(tcp.NewTCPTransport),
libp2p.Transport(libp2pquic.NewTransport),
libp2p.Transport(libp2ptcp.NewTCPTransport),
}
options = append(options, libp2p.Security(noise.ID, noise.New))
options = append(options, libp2p.Ping(false))

View File

@@ -22,11 +22,12 @@ import (
)
var requestBlobsFlags = struct {
Peers string
ClientPort uint
APIEndpoints string
StartSlot uint64
Count uint64
Peers string
ClientPortTCP uint
ClientPortQUIC uint
APIEndpoints string
StartSlot uint64
Count uint64
}{}
var requestBlobsCmd = &cli.Command{
@@ -47,9 +48,16 @@ var requestBlobsCmd = &cli.Command{
Value: "",
},
&cli.UintFlag{
Name: "client-port",
Usage: "port to use for the client as a libp2p host",
Destination: &requestBlobsFlags.ClientPort,
Name: "client-port-tcp",
Aliases: []string{"client-port"},
Usage: "TCP port to use for the client as a libp2p host",
Destination: &requestBlobsFlags.ClientPortTCP,
Value: 13001,
},
&cli.UintFlag{
Name: "client-port-quic",
Usage: "QUIC port to use for the client as a libp2p host",
Destination: &requestBlobsFlags.ClientPortQUIC,
Value: 13001,
},
&cli.StringFlag{
@@ -60,13 +68,13 @@ var requestBlobsCmd = &cli.Command{
},
&cli.Uint64Flag{
Name: "start-slot",
Usage: "start slot for blocks by range request. If unset, will use start_slot(current_epoch-1)",
Usage: "start slot for blobs by range request. If unset, will use start_slot(current_epoch-1)",
Destination: &requestBlobsFlags.StartSlot,
Value: 0,
},
&cli.Uint64Flag{
Name: "count",
Usage: "number of blocks to request, (default 32)",
Usage: "number of blobs to request, (default 32)",
Destination: &requestBlobsFlags.Count,
Value: 32,
},
@@ -90,7 +98,7 @@ func cliActionRequestBlobs(cliCtx *cli.Context) error {
allAPIEndpoints = strings.Split(requestBlobsFlags.APIEndpoints, ",")
}
var err error
c, err := newClient(allAPIEndpoints, requestBlobsFlags.ClientPort)
c, err := newClient(allAPIEndpoints, requestBlobsFlags.ClientPortTCP, requestBlobsFlags.ClientPortQUIC)
if err != nil {
return err
}

View File

@@ -23,12 +23,14 @@ import (
)
var requestBlocksFlags = struct {
Peers string
ClientPort uint
APIEndpoints string
StartSlot uint64
Count uint64
Step uint64
Network string
Peers string
ClientPortTCP uint
ClientPortQUIC uint
APIEndpoints string
StartSlot uint64
Count uint64
Step uint64
}{}
var requestBlocksCmd = &cli.Command{
@@ -42,6 +44,12 @@ var requestBlocksCmd = &cli.Command{
},
Flags: []cli.Flag{
cmd.ChainConfigFileFlag,
&cli.StringFlag{
Name: "network",
Usage: "network to run on (mainnet, sepolia, holesky)",
Destination: &requestBlocksFlags.Network,
Value: "mainnet",
},
&cli.StringFlag{
Name: "peer-multiaddrs",
Usage: "comma-separated, peer multiaddr(s) to connect to for p2p requests",
@@ -49,9 +57,16 @@ var requestBlocksCmd = &cli.Command{
Value: "",
},
&cli.UintFlag{
Name: "client-port",
Usage: "port to use for the client as a libp2p host",
Destination: &requestBlocksFlags.ClientPort,
Name: "client-port-tcp",
Aliases: []string{"client-port"},
Usage: "TCP port to use for the client as a libp2p host",
Destination: &requestBlocksFlags.ClientPortTCP,
Value: 13001,
},
&cli.UintFlag{
Name: "client-port-quic",
Usage: "QUIC port to use for the client as a libp2p host",
Destination: &requestBlocksFlags.ClientPortQUIC,
Value: 13001,
},
&cli.StringFlag{
@@ -82,6 +97,21 @@ var requestBlocksCmd = &cli.Command{
}
func cliActionRequestBlocks(cliCtx *cli.Context) error {
switch requestBlocksFlags.Network {
case params.SepoliaName:
if err := params.SetActive(params.SepoliaConfig()); err != nil {
log.Fatal(err)
}
case params.HoleskyName:
if err := params.SetActive(params.HoleskyConfig()); err != nil {
log.Fatal(err)
}
case params.MainnetName:
// Do nothing
default:
log.Fatalf("Unknown network provided: %s", requestBlocksFlags.Network)
}
if cliCtx.IsSet(cmd.ChainConfigFileFlag.Name) {
chainConfigFileName := cliCtx.String(cmd.ChainConfigFileFlag.Name)
if err := params.LoadChainConfigFile(chainConfigFileName, nil); err != nil {
@@ -98,7 +128,7 @@ func cliActionRequestBlocks(cliCtx *cli.Context) error {
allAPIEndpoints = strings.Split(requestBlocksFlags.APIEndpoints, ",")
}
var err error
c, err := newClient(allAPIEndpoints, requestBlocksFlags.ClientPort)
c, err := newClient(allAPIEndpoints, requestBlocksFlags.ClientPortTCP, requestBlocksFlags.ClientPortQUIC)
if err != nil {
return err
}