@@ -21,10 +21,11 @@ pub use libp2p::identity::{Keypair, PublicKey};
21
21
use enr:: { ATTESTATION_BITFIELD_ENR_KEY , ETH2_ENR_KEY , SYNC_COMMITTEE_BITFIELD_ENR_KEY } ;
22
22
use futures:: prelude:: * ;
23
23
use futures:: stream:: FuturesUnordered ;
24
+ use libp2p:: multiaddr:: Protocol ;
24
25
use libp2p:: swarm:: behaviour:: { DialFailure , FromSwarm } ;
25
26
use libp2p:: swarm:: THandlerInEvent ;
26
27
pub use libp2p:: {
27
- core:: { ConnectedPoint , Multiaddr } ,
28
+ core:: { transport :: ListenerId , ConnectedPoint , Multiaddr } ,
28
29
identity:: PeerId ,
29
30
swarm:: {
30
31
dummy:: ConnectionHandler , ConnectionId , DialError , NetworkBehaviour , NotifyHandler ,
@@ -77,6 +78,19 @@ pub struct DiscoveredPeers {
77
78
pub peers : HashMap < Enr , Option < Instant > > ,
78
79
}
79
80
81
+ /// Specifies which port numbers should be modified after start of the discovery service
82
+ #[ derive( Debug ) ]
83
+ pub struct UpdatePorts {
84
+ /// TCP port associated wih IPv4 address (if present)
85
+ pub tcp4 : bool ,
86
+ /// TCP port associated wih IPv6 address (if present)
87
+ pub tcp6 : bool ,
88
+ /// QUIC port associated wih IPv4 address (if present)
89
+ pub quic4 : bool ,
90
+ /// QUIC port associated wih IPv6 address (if present)
91
+ pub quic6 : bool ,
92
+ }
93
+
80
94
#[ derive( Clone , PartialEq ) ]
81
95
struct SubnetQuery {
82
96
subnet : Subnet ,
@@ -177,12 +191,8 @@ pub struct Discovery<TSpec: EthSpec> {
177
191
/// always false.
178
192
pub started : bool ,
179
193
180
- /// This keeps track of whether an external UDP port change should also indicate an internal
181
- /// TCP port change. As we cannot detect our external TCP port, we assume that the external UDP
182
- /// port is also our external TCP port. This assumption only holds if the user has not
183
- /// explicitly set their ENR TCP port via the CLI config. The first indicates tcp4 and the
184
- /// second indicates tcp6.
185
- update_tcp_port : ( bool , bool ) ,
194
+ /// Specifies whether various port numbers should be updated after the discovery service has been started
195
+ update_ports : UpdatePorts ,
186
196
187
197
/// Logger for the discovery behaviour.
188
198
log : slog:: Logger ,
@@ -300,10 +310,12 @@ impl<TSpec: EthSpec> Discovery<TSpec> {
300
310
}
301
311
}
302
312
303
- let update_tcp_port = (
304
- config. enr_tcp4_port . is_none ( ) ,
305
- config. enr_tcp6_port . is_none ( ) ,
306
- ) ;
313
+ let update_ports = UpdatePorts {
314
+ tcp4 : config. enr_tcp4_port . is_none ( ) ,
315
+ tcp6 : config. enr_tcp6_port . is_none ( ) ,
316
+ quic4 : config. enr_quic4_port . is_none ( ) ,
317
+ quic6 : config. enr_quic6_port . is_none ( ) ,
318
+ } ;
307
319
308
320
Ok ( Self {
309
321
cached_enrs : LruCache :: new ( 50 ) ,
@@ -314,7 +326,7 @@ impl<TSpec: EthSpec> Discovery<TSpec> {
314
326
discv5,
315
327
event_stream,
316
328
started : !config. disable_discovery ,
317
- update_tcp_port ,
329
+ update_ports ,
318
330
log,
319
331
enr_dir,
320
332
} )
@@ -1006,8 +1018,8 @@ impl<TSpec: EthSpec> NetworkBehaviour for Discovery<TSpec> {
1006
1018
// Discv5 will have updated our local ENR. We save the updated version
1007
1019
// to disk.
1008
1020
1009
- if ( self . update_tcp_port . 0 && socket_addr. is_ipv4 ( ) )
1010
- || ( self . update_tcp_port . 1 && socket_addr. is_ipv6 ( ) )
1021
+ if ( self . update_ports . tcp4 && socket_addr. is_ipv4 ( ) )
1022
+ || ( self . update_ports . tcp6 && socket_addr. is_ipv6 ( ) )
1011
1023
{
1012
1024
// Update the TCP port in the ENR
1013
1025
self . discv5 . update_local_enr_socket ( socket_addr, true ) ;
@@ -1036,12 +1048,79 @@ impl<TSpec: EthSpec> NetworkBehaviour for Discovery<TSpec> {
1036
1048
FromSwarm :: DialFailure ( DialFailure { peer_id, error, .. } ) => {
1037
1049
self . on_dial_failure ( peer_id, error)
1038
1050
}
1051
+ FromSwarm :: NewListenAddr ( ev) => {
1052
+ let addr = ev. addr ;
1053
+ let listener_id = ev. listener_id ;
1054
+
1055
+ trace ! ( self . log, "Received NewListenAddr event from swarm" ; "listener_id" => ?listener_id, "addr" => ?addr) ;
1056
+
1057
+ let mut addr_iter = addr. iter ( ) ;
1058
+
1059
+ let attempt_enr_update = match addr_iter. next ( ) {
1060
+ Some ( Protocol :: Ip4 ( _) ) => match ( addr_iter. next ( ) , addr_iter. next ( ) ) {
1061
+ ( Some ( Protocol :: Tcp ( port) ) , None ) => {
1062
+ if !self . update_ports . tcp4 {
1063
+ debug ! ( self . log, "Skipping ENR update" ; "multiaddr" => ?addr) ;
1064
+ return ;
1065
+ }
1066
+
1067
+ self . update_enr_tcp_port ( port)
1068
+ }
1069
+ ( Some ( Protocol :: Udp ( port) ) , Some ( Protocol :: QuicV1 ) ) => {
1070
+ if !self . update_ports . quic4 {
1071
+ debug ! ( self . log, "Skipping ENR update" ; "multiaddr" => ?addr) ;
1072
+ return ;
1073
+ }
1074
+
1075
+ self . update_enr_quic_port ( port)
1076
+ }
1077
+ _ => {
1078
+ debug ! ( self . log, "Encountered unacceptable multiaddr for listening (unsupported transport)" ; "addr" => ?addr) ;
1079
+ return ;
1080
+ }
1081
+ } ,
1082
+ Some ( Protocol :: Ip6 ( _) ) => match ( addr_iter. next ( ) , addr_iter. next ( ) ) {
1083
+ ( Some ( Protocol :: Tcp ( port) ) , None ) => {
1084
+ if !self . update_ports . tcp6 {
1085
+ debug ! ( self . log, "Skipping ENR update" ; "multiaddr" => ?addr) ;
1086
+ return ;
1087
+ }
1088
+
1089
+ self . update_enr_tcp_port ( port)
1090
+ }
1091
+ ( Some ( Protocol :: Udp ( port) ) , Some ( Protocol :: QuicV1 ) ) => {
1092
+ if !self . update_ports . quic6 {
1093
+ debug ! ( self . log, "Skipping ENR update" ; "multiaddr" => ?addr) ;
1094
+ return ;
1095
+ }
1096
+
1097
+ self . update_enr_quic_port ( port)
1098
+ }
1099
+ _ => {
1100
+ debug ! ( self . log, "Encountered unacceptable multiaddr for listening (unsupported transport)" ; "addr" => ?addr) ;
1101
+ return ;
1102
+ }
1103
+ } ,
1104
+ _ => {
1105
+ debug ! ( self . log, "Encountered unacceptable multiaddr for listening (no IP)" ; "addr" => ?addr) ;
1106
+ return ;
1107
+ }
1108
+ } ;
1109
+
1110
+ let local_enr: Enr = self . discv5 . local_enr ( ) ;
1111
+
1112
+ match attempt_enr_update {
1113
+ Ok ( _) => {
1114
+ info ! ( self . log, "Updated local ENR" ; "enr" => local_enr. to_base64( ) , "seq" => local_enr. seq( ) , "id" => %local_enr. node_id( ) , "ip4" => ?local_enr. ip4( ) , "udp4" => ?local_enr. udp4( ) , "tcp4" => ?local_enr. tcp4( ) , "tcp6" => ?local_enr. tcp6( ) , "udp6" => ?local_enr. udp6( ) )
1115
+ }
1116
+ Err ( e) => warn ! ( self . log, "Failed to update ENR" ; "error" => ?e) ,
1117
+ }
1118
+ }
1039
1119
FromSwarm :: ConnectionEstablished ( _)
1040
1120
| FromSwarm :: ConnectionClosed ( _)
1041
1121
| FromSwarm :: AddressChange ( _)
1042
1122
| FromSwarm :: ListenFailure ( _)
1043
1123
| FromSwarm :: NewListener ( _)
1044
- | FromSwarm :: NewListenAddr ( _)
1045
1124
| FromSwarm :: ExpiredListenAddr ( _)
1046
1125
| FromSwarm :: ListenerError ( _)
1047
1126
| FromSwarm :: ListenerClosed ( _)
0 commit comments