-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
P2P: Add QUIC support #13786
P2P: Add QUIC support #13786
Conversation
02cdb59
to
c3ccf8d
Compare
Value: 12000, | ||
} | ||
// P2PTCPPort defines the port to be used by libp2p. | ||
// P2PQUICPort defines the QUIC port to be used by libp2p. | ||
P2PQUICPort = &cli.IntFlag{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Along with this flag, is it possible to also add a feature flag enable-quic
? We do not want QUIC to immediately be the default as if there are issues with other Lighthouse nodes and their QUIC implementation it could lead to issues for node operators.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in c69efdb.
beacon-chain/p2p/peers/status.go
Outdated
@@ -449,6 +450,32 @@ func (p *Status) InboundConnected() []peer.ID { | |||
return peers | |||
} | |||
|
|||
// InboundConnectedTCP returns the current batch of inbound peers that are connected using TCP. | |||
func (p *Status) InboundConnectedTCP() []peer.ID { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of having separate methods for different protocols, how about:
func (p *Status) InboundConnected(protocol string) []peer.ID
that way, you don't have to duplicate the implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in f42455b.
beacon-chain/p2p/peers/status.go
Outdated
@@ -475,7 +502,33 @@ func (p *Status) OutboundConnected() []peer.ID { | |||
return peers | |||
} | |||
|
|||
// Active returns the peers that are connecting or connected. | |||
// OutboundConnected returns the current batch of outbound peers that are connected using TCP. | |||
func (p *Status) OutboundConnectedTCP() []peer.ID { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in f42455b.
@@ -257,6 +257,7 @@ func (node *BeaconNode) Start(ctx context.Context) error { | |||
fmt.Sprintf("--%s=%s", flags.ExecutionJWTSecretFlag.Name, jwtPath), | |||
fmt.Sprintf("--%s=%d", flags.MinSyncPeers.Name, 1), | |||
fmt.Sprintf("--%s=%d", cmdshared.P2PUDPPort.Name, e2e.TestParams.Ports.PrysmBeaconNodeUDPPort+index), | |||
fmt.Sprintf("--%s=%d", cmdshared.P2PQUICPort.Name, e2e.TestParams.Ports.PrysmBeaconNodeQUICPort+index), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also add the enable-quic
flag here, so that every prysm node is running with it enabled in e2e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 1f0d84d.
@@ -229,6 +234,7 @@ var BeaconChainFlags = append(deprecatedBeaconFlags, append(deprecatedFlags, []c | |||
DisableRegistrationCache, | |||
EnableLightClient, | |||
BlobSaveFsync, | |||
EnableQUIC, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add this to our dev flags too ? So that any user running with --dev
is also running this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 1f0d84d.
beacon-chain/p2p/discovery.go
Outdated
// If the node has a both a QUIC and a TCP port set in their ENR, then | ||
// the multiaddr corresponding to the QUIC port is added first, followed | ||
// by the multiaddr corresponding to the TCP port. | ||
func convertToMultiAddrs(node *enode.Node) ([]ma.Multiaddr, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why was the name changed here ? its easy to get this mixed up with convertToMultiAddr
. The previous name emphasized the singular nature
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nvm, I do understand why singular was removed but its easy to confuse it with convertToMultiAddr
, another name would be better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in a0c0326.
beacon-chain/p2p/discovery.go
Outdated
return nil, nil, errors.Wrapf(err, "could not convert to peer info: %v", multiAddrs) | ||
} | ||
|
||
if len(infos) > 1 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems wrong, what happens if we have 2 multiaddrs returned from convertToMultiAddrs
. This error would always be triggered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
peer.AddrInfosFromP2pAddrs
groups input maddrs
by node.
If multiaddrs
contains 5 multiaddr
s, but belonging to only 2 nodes, (for example 3 multiaddr
s for one node and 2 multiaddr
s for the other node), then len(infos) == 2
and:
len(infos[0].Addrs) == 3
len(infos[1].Addrs) == 2
For information, this is the code of AddrInfosFromP2PAddrs
:
// AddrInfosFromP2pAddrs converts a set of Multiaddrs to a set of AddrInfos.
func AddrInfosFromP2pAddrs(maddrs ...ma.Multiaddr) ([]AddrInfo, error) {
m := make(map[ID][]ma.Multiaddr)
for _, maddr := range maddrs {
transport, id := SplitAddr(maddr)
if id == "" {
return nil, ErrInvalidAddr
}
if transport == nil {
if _, ok := m[id]; !ok {
m[id] = nil
}
} else {
m[id] = append(m[id], transport)
}
}
ais := make([]AddrInfo, 0, len(m))
for id, maddrs := range m {
ais = append(ais, AddrInfo{ID: id, Addrs: maddrs})
}
return ais, nil
}
In our case, all the multiaddr
s come from the same node, so we expect at most 1 item in infos
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok in that case, if we do get a value not equal to 1, we should simply return an error. Otherwise the caller will assume the address info is valid and proceed to use it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also added a check in func (s *Service) filterPeer(node *enode.Node) bool
.
In this function, even if the only way to have peerData == nil
is to have at the same time multiAddrs == nil
, it's better to check peerData
nilness explicitely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in e9d80e2.
beacon-chain/p2p/discovery.go
Outdated
return nil, nil, errors.Errorf("infos contains %v elements, expected not more than 1", len(infos)) | ||
} | ||
|
||
if len(infos) == 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we get no info, then we should return an error imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the caller will expect the addr info not to be nil and will end up panicking here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comment about if len(infos) > 1
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in e9d80e2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great Job ! Looks great to me
* (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`.
What type of PR is this?
Feature
What does this PR do? Why is it needed?
This pull request adds the QUIC protocol support. For more information about the QUIC protocol, and how it is supported into libp2p, please checkout here.
This PR adds a new
--p2p-quic-port (default: 13000)
flag.This new feature is hidden behind the
--enable-quic
feature flag:P2P ports are now:
Now, port
13000
is used as both default port for libp2p TCP and QUIC(UDP).When starting the beacon node, the following log is displayed:
The corresponding decoded ENR is the following:
(Note the new
quic
entry.)When starting a new node, the following logs are displayed:
If using the
--p2p-host-ip
flag:Every minute, the following log is displayed, showing the number of inbound/outbound TCP/QUIC peers.
Below is represented an extract of the beacon API call to
<ip-address>:3500/eth/v1/beacon/genesis
:Only four items are retained in the extract:
Outbound / Inbound is represented in the
direction
field.TCP / QUIC is represented in the
last_seen_p2p_address
field.Decoded ENR of the TCP/Outbound peer is represented as:
(No
quic
entry in present the ENR.)Decoded ENR of the QUIC/Outbound peer is represented as:
(The
quic
entry is present in the ENR.)Note:
When an outbound peer supports both the TCP and the QUIC protocols, then Prysm favors the QUIC protocol.