diff --git a/beacon-chain/p2p/discovery.go b/beacon-chain/p2p/discovery.go index 9ee0ebd03274..37a81c1ea1d0 100644 --- a/beacon-chain/p2p/discovery.go +++ b/beacon-chain/p2p/discovery.go @@ -15,6 +15,7 @@ import ( "github.com/pkg/errors" "github.com/prysmaticlabs/go-bitfield" "github.com/prysmaticlabs/prysm/v5/beacon-chain/cache" + "github.com/prysmaticlabs/prysm/v5/config/features" "github.com/prysmaticlabs/prysm/v5/config/params" ecdsaprysm "github.com/prysmaticlabs/prysm/v5/crypto/ecdsa" "github.com/prysmaticlabs/prysm/v5/runtime/version" @@ -230,14 +231,18 @@ func (s *Service) createLocalNode( localNode := enode.NewLocalNode(db, privKey) ipEntry := enr.IP(ipAddr) - udpEntry := enr.UDP(udpPort) - tcpEntry := enr.TCP(tcpPort) - quicEntry := quicProtocol(quicPort) - localNode.Set(ipEntry) + + udpEntry := enr.UDP(udpPort) localNode.Set(udpEntry) + + tcpEntry := enr.TCP(tcpPort) localNode.Set(tcpEntry) - localNode.Set(quicEntry) + + if features.Get().EnableQUIC { + quicEntry := quicProtocol(quicPort) + localNode.Set(quicEntry) + } localNode.SetFallbackIP(ipAddr) localNode.SetFallbackUDP(udpPort) @@ -502,23 +507,25 @@ func convertToMultiAddrs(node *enode.Node) ([]ma.Multiaddr, error) { return nil, errors.Wrap(err, "could not get peer id") } - // If the QUIC entry is present in the ENR, build the corresponding multiaddress. - port, ok, err := getPort(node, quic) - if err != nil { - return nil, errors.Wrap(err, "could not get QUIC port") - } - - if ok { - addr, err := multiAddressBuilderWithID(node.IP(), quic, port, id) + if features.Get().EnableQUIC { + // If the QUIC entry is present in the ENR, build the corresponding multiaddress. + port, ok, err := getPort(node, quic) if err != nil { - return nil, errors.Wrap(err, "could not build QUIC address") + return nil, errors.Wrap(err, "could not get QUIC port") } - multiaddrs = append(multiaddrs, addr) + if ok { + addr, err := multiAddressBuilderWithID(node.IP(), quic, port, id) + if err != nil { + return nil, errors.Wrap(err, "could not build QUIC address") + } + + multiaddrs = append(multiaddrs, addr) + } } // If the TCP entry is present in the ENR, build the corresponding multiaddress. - port, ok, err = getPort(node, tcp) + port, ok, err := getPort(node, tcp) if err != nil { return nil, errors.Wrap(err, "could not get TCP port") } diff --git a/beacon-chain/p2p/options.go b/beacon-chain/p2p/options.go index 391e74c486c6..9935e8e0aef4 100644 --- a/beacon-chain/p2p/options.go +++ b/beacon-chain/p2p/options.go @@ -37,12 +37,6 @@ func MultiAddressBuilder(ip net.IP, tcpPort, quicPort uint) ([]ma.Multiaddr, err return nil, errors.Wrap(err, "unable to determine IP type") } - // Example: /ip4/1.2.3.4/udp/5678/quic-v1 - multiAddrQUIC, err := ma.NewMultiaddr(fmt.Sprintf("/%s/%s/udp/%d/quic-v1", ipType, ip, quicPort)) - if err != nil { - return nil, errors.Wrapf(err, "cannot produce QUIC multiaddr format from %s:%d", ip, tcpPort) - } - // Example: /ip4/1.2.3.4./tcp/5678 multiaddrStr := fmt.Sprintf("/%s/%s/tcp/%d", ipType, ip, tcpPort) multiAddrTCP, err := ma.NewMultiaddr(multiaddrStr) @@ -50,7 +44,19 @@ func MultiAddressBuilder(ip net.IP, tcpPort, quicPort uint) ([]ma.Multiaddr, err return nil, errors.Wrapf(err, "cannot produce TCP multiaddr format from %s:%d", ip, tcpPort) } - return []ma.Multiaddr{multiAddrTCP, multiAddrQUIC}, nil + multiaddrs := []ma.Multiaddr{multiAddrTCP} + + if features.Get().EnableQUIC { + // Example: /ip4/1.2.3.4/udp/5678/quic-v1 + multiAddrQUIC, err := ma.NewMultiaddr(fmt.Sprintf("/%s/%s/udp/%d/quic-v1", ipType, ip, quicPort)) + if err != nil { + return nil, errors.Wrapf(err, "cannot produce QUIC multiaddr format from %s:%d", ip, tcpPort) + } + + multiaddrs = append(multiaddrs, multiAddrQUIC) + } + + return multiaddrs, nil } // buildOptions for the libp2p host. @@ -87,7 +93,6 @@ func (s *Service) buildOptions(ip net.IP, priKey *ecdsa.PrivateKey) ([]libp2p.Op libp2p.ListenAddrs(multiaddrs...), libp2p.UserAgent(version.BuildData()), libp2p.ConnectionGater(s), - libp2p.Transport(libp2pquic.NewTransport), libp2p.Transport(libp2ptcp.NewTCPTransport), libp2p.DefaultMuxers, libp2p.Muxer("/mplex/6.7.0", mplex.DefaultTransport), @@ -95,6 +100,10 @@ func (s *Service) buildOptions(ip net.IP, priKey *ecdsa.PrivateKey) ([]libp2p.Op libp2p.Ping(false), // Disable Ping Service. } + if features.Get().EnableQUIC { + options = append(options, libp2p.Transport(libp2pquic.NewTransport)) + } + if cfg.EnableUPnP { options = append(options, libp2p.NATPortMap()) // Allow to use UPnP } diff --git a/beacon-chain/p2p/service.go b/beacon-chain/p2p/service.go index 5be7f9951a23..8192d9b0b67f 100644 --- a/beacon-chain/p2p/service.go +++ b/beacon-chain/p2p/service.go @@ -24,6 +24,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/beacon-chain/p2p/peers" "github.com/prysmaticlabs/prysm/v5/beacon-chain/p2p/peers/scorers" "github.com/prysmaticlabs/prysm/v5/beacon-chain/p2p/types" + "github.com/prysmaticlabs/prysm/v5/config/features" "github.com/prysmaticlabs/prysm/v5/config/params" leakybucket "github.com/prysmaticlabs/prysm/v5/container/leaky-bucket" prysmnetwork "github.com/prysmaticlabs/prysm/v5/network" @@ -241,13 +242,18 @@ func (s *Service) Start() { outboundTCPCount := len(s.peers.OutboundConnectedWithProtocol(peers.TCP)) total := inboundQUICCount + inboundTCPCount + outboundQUICCount + outboundTCPCount - log.WithFields(logrus.Fields{ - "inboundQUIC": inboundQUICCount, - "inboundTCP": inboundTCPCount, - "outboundQUIC": outboundQUICCount, - "outboundTCP": outboundTCPCount, - "total": total, - }).Info("Connected peers") + fields := logrus.Fields{ + "inboundTCP": inboundTCPCount, + "outboundTCP": outboundTCPCount, + "total": total, + } + + if features.Get().EnableQUIC { + fields["inboundQUIC"] = inboundQUICCount + fields["outboundQUIC"] = outboundQUICCount + } + + log.WithFields(fields).Info("Connected peers") }) multiAddrs := s.host.Network().ListenAddresses() diff --git a/config/features/config.go b/config/features/config.go index 43f1c3d10a67..aa606ce9a8d6 100644 --- a/config/features/config.go +++ b/config/features/config.go @@ -42,6 +42,7 @@ type Flags struct { WriteSSZStateTransitions bool // WriteSSZStateTransitions to tmp directory. EnablePeerScorer bool // EnablePeerScorer enables experimental peer scoring in p2p. EnableLightClient bool // EnableLightClient enables light client APIs. + EnableQUIC bool // EnableQUIC specifies whether to enable QUIC transport for libp2p. WriteWalletPasswordOnWebOnboarding bool // WriteWalletPasswordOnWebOnboarding writes the password to disk after Prysm web signup. EnableDoppelGanger bool // EnableDoppelGanger enables doppelganger protection on startup for the validator. EnableHistoricalSpaceRepresentation bool // EnableHistoricalSpaceRepresentation enables the saving of registry validators in separate buckets to save space @@ -265,6 +266,10 @@ func ConfigureBeaconChain(ctx *cli.Context) error { logEnabled(BlobSaveFsync) cfg.BlobSaveFsync = true } + if ctx.IsSet(EnableQUIC.Name) { + logEnabled(EnableQUIC) + cfg.EnableQUIC = true + } cfg.AggregateIntervals = [3]time.Duration{aggregateFirstInterval.Value, aggregateSecondInterval.Value, aggregateThirdInterval.Value} Init(cfg) diff --git a/config/features/flags.go b/config/features/flags.go index fec1b987ac00..06572e7d3afe 100644 --- a/config/features/flags.go +++ b/config/features/flags.go @@ -171,6 +171,11 @@ var ( Name: "blob-save-fsync", Usage: "Forces new blob files to be fysnc'd before continuing, ensuring durable blob writes.", } + // EnableQUIC enables connection using the QUIC protocol for peers which support it. + EnableQUIC = &cli.BoolFlag{ + Name: "enable-quic", + Usage: "Enables connection using the QUIC protocol for peers which support it.", + } ) // devModeFlags holds list of flags that are set when development mode is on. @@ -229,6 +234,7 @@ var BeaconChainFlags = append(deprecatedBeaconFlags, append(deprecatedFlags, []c DisableRegistrationCache, EnableLightClient, BlobSaveFsync, + EnableQUIC, }...)...) // E2EBeaconChainFlags contains a list of the beacon chain feature flags to be tested in E2E.