@@ -343,6 +343,36 @@ impl<K: EnrKey> Enr<K> {
343
343
None
344
344
}
345
345
346
+ /// Returns [EIP-7636](https://eips.ethereum.org/EIPS/eip-7636) entry if it is defined.
347
+ #[ must_use]
348
+ pub fn client_info ( & self ) -> Option < ( String , String , Option < String > ) > {
349
+ if let Some ( Ok ( client_list) ) = self . get_decodable :: < Vec < Bytes > > ( "client" ) {
350
+ match client_list. len ( ) {
351
+ 2 => {
352
+ let client_name = String :: from_utf8_lossy ( client_list[ 0 ] . as_ref ( ) ) . to_string ( ) ;
353
+
354
+ let client_version =
355
+ String :: from_utf8_lossy ( client_list[ 1 ] . as_ref ( ) ) . to_string ( ) ;
356
+
357
+ return Some ( ( client_name, client_version, None ) ) ;
358
+ }
359
+ 3 => {
360
+ let client_name = String :: from_utf8_lossy ( client_list[ 0 ] . as_ref ( ) ) . to_string ( ) ;
361
+
362
+ let client_version =
363
+ String :: from_utf8_lossy ( client_list[ 1 ] . as_ref ( ) ) . to_string ( ) ;
364
+
365
+ let client_additional =
366
+ String :: from_utf8_lossy ( client_list[ 2 ] . as_ref ( ) ) . to_string ( ) ;
367
+ return Some ( ( client_name, client_version, Some ( client_additional) ) ) ;
368
+ }
369
+ _ => { }
370
+ }
371
+ }
372
+
373
+ None
374
+ }
375
+
346
376
/// The TCP port of ENR record if it is defined.
347
377
#[ must_use]
348
378
pub fn tcp4 ( & self ) -> Option < u16 > {
@@ -620,6 +650,23 @@ impl<K: EnrKey> Enr<K> {
620
650
Ok ( None )
621
651
}
622
652
653
+ /// Sets the [EIP-7636](https://eips.ethereum.org/EIPS/eip-7636) `client` field in the record.
654
+ pub fn set_client_info (
655
+ & mut self ,
656
+ name : String ,
657
+ version : String ,
658
+ build : Option < String > ,
659
+ key : & K ,
660
+ ) -> Result < ( ) , Error > {
661
+ if build. is_none ( ) {
662
+ self . insert ( "client" , & vec ! [ name, version] , key) ?;
663
+ } else {
664
+ self . insert ( "client" , & vec ! [ name, version, build. unwrap( ) ] , key) ?;
665
+ }
666
+
667
+ Ok ( ( ) )
668
+ }
669
+
623
670
/// Sets the IP and UDP port in a single update with a single increment in sequence number.
624
671
pub fn set_udp_socket ( & mut self , socket : SocketAddr , key : & K ) -> Result < ( ) , Error > {
625
672
self . set_socket ( socket, key, false )
@@ -1969,6 +2016,79 @@ mod tests {
1969
2016
assert_eq ! ( record. seq( ) , 30 ) ;
1970
2017
}
1971
2018
2019
+ #[ test]
2020
+ fn test_set_client_eip7636 ( ) {
2021
+ let key = k256:: ecdsa:: SigningKey :: random ( & mut rand:: thread_rng ( ) ) ;
2022
+ let mut enr = Enr :: empty ( & key) . unwrap ( ) ;
2023
+
2024
+ enr. set_client_info (
2025
+ "Test" . to_string ( ) ,
2026
+ "v1.0.0" . to_string ( ) ,
2027
+ Some ( "Test" . to_string ( ) ) ,
2028
+ & key,
2029
+ )
2030
+ . unwrap ( ) ;
2031
+ assert ! ( enr. verify( ) ) ;
2032
+
2033
+ enr. set_client_info ( "Test" . to_string ( ) , "v1.0.0" . to_string ( ) , None , & key)
2034
+ . unwrap ( ) ;
2035
+ assert ! ( enr. verify( ) ) ;
2036
+ }
2037
+
2038
+ #[ test]
2039
+ fn test_get_eip7636 ( ) {
2040
+ let example_eip = "enr:-MO4QBn4OF-y-dqULg4WOIlc8gQAt-arldNFe0_YQ4HNX28jDtg41xjDyKfCXGfZaPN97I-MCfogeK91TyqmWTpb0_AChmNsaWVudNqKTmV0aGVybWluZIYxLjkuNTOHN2ZjYjU2N4JpZIJ2NIJpcIR_AAABg2lwNpAAAAAAAAAAAAAAAAAAAAABiXNlY3AyNTZrMaECn-TTdCwfZP4XgJyq8Lxoj-SgEoIFgDLVBEUqQk4HnAqDdWRwgiMshHVkcDaCIyw" ;
2041
+ let enr = example_eip. parse :: < DefaultEnr > ( ) . unwrap ( ) ;
2042
+
2043
+ let info = enr. client_info ( ) . unwrap ( ) ;
2044
+
2045
+ assert_eq ! ( info. 0 , "Nethermind" ) ;
2046
+ assert_eq ! ( info. 1 , "1.9.53" ) ;
2047
+ assert_eq ! ( info. 2 . unwrap( ) , "7fcb567" ) ;
2048
+
2049
+ let key = k256:: ecdsa:: SigningKey :: random ( & mut rand:: thread_rng ( ) ) ;
2050
+ let mut enr = Enr :: empty ( & key) . unwrap ( ) ;
2051
+
2052
+ enr. set_client_info ( "Test" . to_string ( ) , "v1.0.0" . to_string ( ) , None , & key)
2053
+ . unwrap ( ) ;
2054
+
2055
+ let info = enr. client_info ( ) . unwrap ( ) ;
2056
+ assert_eq ! ( info. 0 , "Test" ) ;
2057
+ assert_eq ! ( info. 1 , "v1.0.0" ) ;
2058
+ assert_eq ! ( info. 2 , None ) ;
2059
+ }
2060
+
2061
+ #[ test]
2062
+ fn test_builder_eip7636 ( ) {
2063
+ let key = k256:: ecdsa:: SigningKey :: random ( & mut rand:: thread_rng ( ) ) ;
2064
+ let enr = Enr :: builder ( )
2065
+ . ip4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) )
2066
+ . tcp4 ( 30303 )
2067
+ . client_info (
2068
+ "Test" . to_string ( ) ,
2069
+ "v1.0.0" . to_string ( ) ,
2070
+ Some ( "Test" . to_string ( ) ) ,
2071
+ )
2072
+ . build ( & key)
2073
+ . unwrap ( ) ;
2074
+
2075
+ let info = enr. client_info ( ) . unwrap ( ) ;
2076
+ assert_eq ! ( info. 0 , "Test" ) ;
2077
+ assert_eq ! ( info. 1 , "v1.0.0" ) ;
2078
+ assert_eq ! ( info. 2 . unwrap( ) , "Test" ) ;
2079
+
2080
+ let enr = Enr :: builder ( )
2081
+ . ip4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) )
2082
+ . tcp4 ( 30303 )
2083
+ . client_info ( "Test" . to_string ( ) , "v1.0.0" . to_string ( ) , None )
2084
+ . build ( & key)
2085
+ . unwrap ( ) ;
2086
+
2087
+ let info = enr. client_info ( ) . unwrap ( ) ;
2088
+ assert_eq ! ( info. 0 , "Test" ) ;
2089
+ assert_eq ! ( info. 1 , "v1.0.0" ) ;
2090
+ assert_eq ! ( info. 2 , None ) ;
2091
+ }
1972
2092
/// Tests a common ENR which uses RLP encoded values without the header
1973
2093
#[ test]
1974
2094
fn test_common_rlp_convention ( ) {
0 commit comments