@@ -320,10 +320,7 @@ impl Discv5 {
320320 return None
321321 }
322322
323- // todo: extend for all network stacks in reth-network rlpx logic
324- let fork_id = ( self . fork_key == Some ( NetworkStackId :: ETH ) )
325- . then ( || self . get_fork_id ( enr) . ok ( ) )
326- . flatten ( ) ;
323+ let fork_id = self . get_fork_id ( enr) . ok ( ) ;
327324
328325 trace ! ( target: "net::discv5" ,
329326 ?fork_id,
@@ -387,7 +384,22 @@ impl Discv5 {
387384 let Some ( key) = self . fork_key else { return Err ( Error :: NetworkStackIdNotConfigured ) } ;
388385 let fork_id = enr
389386 . get_decodable :: < EnrForkIdEntry > ( key)
390- . ok_or ( Error :: ForkMissing ( key) ) ?
387+ . or_else ( || {
388+ ( key != NetworkStackId :: ETH )
389+ . then ( || {
390+ // Fallback: trying to get fork id from Enr with 'eth' as network stack id
391+ trace ! ( target: "net::discv5" ,
392+ key = %String :: from_utf8_lossy( key) ,
393+ "Fork id not found for key, trying 'eth'..."
394+ ) ;
395+ enr. get_decodable :: < EnrForkIdEntry > ( NetworkStackId :: ETH )
396+ } )
397+ . flatten ( )
398+ } )
399+ . ok_or ( {
400+ trace ! ( target: "net::discv5" , "Fork id not found for 'eth' network stack id" ) ;
401+ Error :: ForkMissing ( key)
402+ } ) ?
391403 . map ( Into :: into) ?;
392404
393405 Ok ( fork_id)
@@ -669,6 +681,8 @@ mod test {
669681 use :: enr:: { CombinedKey , EnrKey } ;
670682 use rand_08:: thread_rng;
671683 use reth_chainspec:: MAINNET ;
684+ use reth_tracing:: init_test_tracing;
685+ use std:: env;
672686 use tracing:: trace;
673687
674688 fn discv5_noop ( ) -> Discv5 {
@@ -901,4 +915,55 @@ mod test {
901915 assert_eq ! ( fork_id, decoded_fork_id) ;
902916 assert_eq ! ( TCP_PORT , enr. tcp4( ) . unwrap( ) ) ; // listen config is defaulting to ip mode ipv4
903917 }
918+
919+ #[ test]
920+ fn get_fork_id_with_different_network_stack_ids ( ) {
921+ unsafe {
922+ env:: set_var ( "RUST_LOG" , "net::discv5=trace" ) ;
923+ }
924+ init_test_tracing ( ) ;
925+
926+ let fork_id = MAINNET . latest_fork_id ( ) ;
927+ let sk = SecretKey :: new ( & mut thread_rng ( ) ) ;
928+
929+ // Test 1: ENR with OPEL fork ID, Discv5 configured for OPEL
930+ let enr_with_opel = Enr :: builder ( )
931+ . add_value_rlp (
932+ NetworkStackId :: OPEL ,
933+ alloy_rlp:: encode ( EnrForkIdEntry :: from ( fork_id) ) . into ( ) ,
934+ )
935+ . build ( & sk)
936+ . unwrap ( ) ;
937+
938+ let mut discv5 = discv5_noop ( ) ;
939+ discv5. fork_key = Some ( NetworkStackId :: OPEL ) ;
940+ assert_eq ! ( discv5. get_fork_id( & enr_with_opel) . unwrap( ) , fork_id) ;
941+
942+ // Test 2: ENR with ETH fork ID, Discv5 configured for OPEL (fallback to ETH)
943+ let enr_with_eth = Enr :: builder ( )
944+ . add_value_rlp (
945+ NetworkStackId :: ETH ,
946+ alloy_rlp:: encode ( EnrForkIdEntry :: from ( fork_id) ) . into ( ) ,
947+ )
948+ . build ( & sk)
949+ . unwrap ( ) ;
950+
951+ discv5. fork_key = Some ( NetworkStackId :: OPEL ) ;
952+ assert_eq ! ( discv5. get_fork_id( & enr_with_eth) . unwrap( ) , fork_id) ;
953+
954+ // Test 3: ENR with neither OPEL nor ETH fork ID (should fail)
955+ let enr_without_network_stack_id = Enr :: empty ( & sk) . unwrap ( ) ;
956+ discv5. fork_key = Some ( NetworkStackId :: OPEL ) ;
957+ assert ! ( matches!(
958+ discv5. get_fork_id( & enr_without_network_stack_id) ,
959+ Err ( Error :: ForkMissing ( NetworkStackId :: OPEL ) )
960+ ) ) ;
961+
962+ // Test 4: discv5 without network stack id configured (should fail)
963+ let discv5 = discv5_noop ( ) ;
964+ assert ! ( matches!(
965+ discv5. get_fork_id( & enr_without_network_stack_id) ,
966+ Err ( Error :: NetworkStackIdNotConfigured )
967+ ) ) ;
968+ }
904969}
0 commit comments