18
18
19
19
//! Configuration of the networking layer.
20
20
21
- use std:: { fmt, str} ;
21
+ use libp2p:: { multiaddr, Multiaddr , PeerId } ;
22
+ use std:: { fmt, str, str:: FromStr } ;
22
23
23
24
/// Name of a protocol, transmitted on the wire. Should be unique for each chain. Always UTF-8.
24
25
#[ derive( Clone , PartialEq , Eq , Hash ) ]
@@ -42,3 +43,129 @@ impl fmt::Debug for ProtocolId {
42
43
fmt:: Debug :: fmt ( self . as_ref ( ) , f)
43
44
}
44
45
}
46
+
47
+ /// Parses a string address and splits it into Multiaddress and PeerId, if
48
+ /// valid.
49
+ ///
50
+ /// # Example
51
+ ///
52
+ /// ```
53
+ /// # use libp2p::{Multiaddr, PeerId};
54
+ /// # use sc_network_common::config::parse_str_addr;
55
+ /// let (peer_id, addr) = parse_str_addr(
56
+ /// "/ip4/198.51.100.19/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV"
57
+ /// ).unwrap();
58
+ /// assert_eq!(peer_id, "QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV".parse::<PeerId>().unwrap());
59
+ /// assert_eq!(addr, "/ip4/198.51.100.19/tcp/30333".parse::<Multiaddr>().unwrap());
60
+ /// ```
61
+ pub fn parse_str_addr ( addr_str : & str ) -> Result < ( PeerId , Multiaddr ) , ParseErr > {
62
+ let addr: Multiaddr = addr_str. parse ( ) ?;
63
+ parse_addr ( addr)
64
+ }
65
+
66
+ /// Splits a Multiaddress into a Multiaddress and PeerId.
67
+ pub fn parse_addr ( mut addr : Multiaddr ) -> Result < ( PeerId , Multiaddr ) , ParseErr > {
68
+ let who = match addr. pop ( ) {
69
+ Some ( multiaddr:: Protocol :: P2p ( key) ) =>
70
+ PeerId :: from_multihash ( key) . map_err ( |_| ParseErr :: InvalidPeerId ) ?,
71
+ _ => return Err ( ParseErr :: PeerIdMissing ) ,
72
+ } ;
73
+
74
+ Ok ( ( who, addr) )
75
+ }
76
+
77
+ /// Address of a node, including its identity.
78
+ ///
79
+ /// This struct represents a decoded version of a multiaddress that ends with `/p2p/<peerid>`.
80
+ ///
81
+ /// # Example
82
+ ///
83
+ /// ```
84
+ /// # use libp2p::{Multiaddr, PeerId};
85
+ /// # use sc_network_common::config::MultiaddrWithPeerId;
86
+ /// let addr: MultiaddrWithPeerId =
87
+ /// "/ip4/198.51.100.19/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV".parse().unwrap();
88
+ /// assert_eq!(addr.peer_id.to_base58(), "QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV");
89
+ /// assert_eq!(addr.multiaddr.to_string(), "/ip4/198.51.100.19/tcp/30333");
90
+ /// ```
91
+ #[ derive( Debug , Clone , serde:: Serialize , serde:: Deserialize , PartialEq ) ]
92
+ #[ serde( try_from = "String" , into = "String" ) ]
93
+ pub struct MultiaddrWithPeerId {
94
+ /// Address of the node.
95
+ pub multiaddr : Multiaddr ,
96
+ /// Its identity.
97
+ pub peer_id : PeerId ,
98
+ }
99
+
100
+ impl MultiaddrWithPeerId {
101
+ /// Concatenates the multiaddress and peer ID into one multiaddress containing both.
102
+ pub fn concat ( & self ) -> Multiaddr {
103
+ let proto = multiaddr:: Protocol :: P2p ( From :: from ( self . peer_id ) ) ;
104
+ self . multiaddr . clone ( ) . with ( proto)
105
+ }
106
+ }
107
+
108
+ impl fmt:: Display for MultiaddrWithPeerId {
109
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
110
+ fmt:: Display :: fmt ( & self . concat ( ) , f)
111
+ }
112
+ }
113
+
114
+ impl FromStr for MultiaddrWithPeerId {
115
+ type Err = ParseErr ;
116
+
117
+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
118
+ let ( peer_id, multiaddr) = parse_str_addr ( s) ?;
119
+ Ok ( Self { peer_id, multiaddr } )
120
+ }
121
+ }
122
+
123
+ impl From < MultiaddrWithPeerId > for String {
124
+ fn from ( ma : MultiaddrWithPeerId ) -> String {
125
+ format ! ( "{}" , ma)
126
+ }
127
+ }
128
+
129
+ impl TryFrom < String > for MultiaddrWithPeerId {
130
+ type Error = ParseErr ;
131
+ fn try_from ( string : String ) -> Result < Self , Self :: Error > {
132
+ string. parse ( )
133
+ }
134
+ }
135
+
136
+ /// Error that can be generated by `parse_str_addr`.
137
+ #[ derive( Debug ) ]
138
+ pub enum ParseErr {
139
+ /// Error while parsing the multiaddress.
140
+ MultiaddrParse ( multiaddr:: Error ) ,
141
+ /// Multihash of the peer ID is invalid.
142
+ InvalidPeerId ,
143
+ /// The peer ID is missing from the address.
144
+ PeerIdMissing ,
145
+ }
146
+
147
+ impl fmt:: Display for ParseErr {
148
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
149
+ match self {
150
+ Self :: MultiaddrParse ( err) => write ! ( f, "{}" , err) ,
151
+ Self :: InvalidPeerId => write ! ( f, "Peer id at the end of the address is invalid" ) ,
152
+ Self :: PeerIdMissing => write ! ( f, "Peer id is missing from the address" ) ,
153
+ }
154
+ }
155
+ }
156
+
157
+ impl std:: error:: Error for ParseErr {
158
+ fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
159
+ match self {
160
+ Self :: MultiaddrParse ( err) => Some ( err) ,
161
+ Self :: InvalidPeerId => None ,
162
+ Self :: PeerIdMissing => None ,
163
+ }
164
+ }
165
+ }
166
+
167
+ impl From < multiaddr:: Error > for ParseErr {
168
+ fn from ( err : multiaddr:: Error ) -> ParseErr {
169
+ Self :: MultiaddrParse ( err)
170
+ }
171
+ }
0 commit comments