4141 } else {
4242 s
4343 } ;
44- s. parse ( ) . map_err ( D :: Error :: custom)
44+ match s. parse ( ) . map_err ( D :: Error :: custom) {
45+ Ok ( peer_addr) => Ok ( peer_addr) ,
46+ Err ( _) => {
47+ // try to fix an invalid IP v6 address encoding on node
48+ // the format should be `[ipv6]:port`, but pre-JDK14 node returns `ipv6:port`
49+ // see https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8225499
50+ dbg ! ( & s) ;
51+ let parts: Vec < & str > = s. rsplit ( ':' ) . collect ( ) ;
52+ if parts. len ( ) == 2 {
53+ // not an IP v6 address
54+ return Err ( D :: Error :: custom ( format ! (
55+ "expected invalid IP v6(without brackets) address, got: {}" ,
56+ s
57+ ) ) ) ;
58+ }
59+ #[ allow( clippy:: unwrap_used) ]
60+ let port = parts. first ( ) . cloned ( ) . unwrap ( ) ;
61+ let host: String = parts
62+ . into_iter ( )
63+ . skip ( 1 )
64+ . rev ( )
65+ . collect :: < Vec < & str > > ( )
66+ . join ( ":" ) ;
67+ // put host inside brackets to make it a valid IP v6 address
68+ let str = format ! ( "[{}]:{}" , host, port) ;
69+ str. parse ( ) . map_err ( D :: Error :: custom)
70+ }
71+ }
4572}
4673
4774#[ cfg( test) ]
@@ -54,4 +81,10 @@ mod tests {
5481 let json = "{\n \" address\" : \" /62.106.112.158:9030\" ,\n \" lastMessage\" : 0,\n \" lastHandshake\" : 0,\n \" name\" : \" ergo-mainnet-4.0.12\" ,\n \" connectionType\" : null\n }" ;
5582 let _: PeerInfo = serde_json:: from_str ( json) . unwrap ( ) ;
5683 }
84+
85+ #[ test]
86+ fn test_parse_peer_info_ipv6_pre_jkd14 ( ) {
87+ let json = "{\n \" address\" : \" /2a0d:6fc0:7cb:be00:50be:7d74:7a00:aa3e:9030\" ,\n \" lastMessage\" : 0,\n \" lastHandshake\" : 0,\n \" name\" : \" ergo-mainnet-4.0.12\" ,\n \" connectionType\" : null\n }" ;
88+ let _: PeerInfo = serde_json:: from_str ( json) . unwrap ( ) ;
89+ }
5790}
0 commit comments