14
14
// You should have received a copy of the GNU General Public License
15
15
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
16
16
17
- use crate :: custom_proto :: { CustomProto , CustomProtoOut , RegisteredProtocol } ;
17
+ use crate :: DiscoveryNetBehaviour ;
18
18
use futures:: prelude:: * ;
19
19
use libp2p:: NetworkBehaviour ;
20
- use libp2p:: core:: { Multiaddr , PeerId , ProtocolsHandler , PublicKey } ;
20
+ use libp2p:: core:: { Multiaddr , PeerId , ProtocolsHandler , protocols_handler :: IntoProtocolsHandler , PublicKey } ;
21
21
use libp2p:: core:: swarm:: { ConnectedPoint , NetworkBehaviour , NetworkBehaviourAction } ;
22
22
use libp2p:: core:: swarm:: { NetworkBehaviourEventProcess , PollParameters } ;
23
23
#[ cfg( not( target_os = "unknown" ) ) ]
@@ -29,19 +29,19 @@ use libp2p::mdns::{Mdns, MdnsEvent};
29
29
use libp2p:: multiaddr:: Protocol ;
30
30
use libp2p:: ping:: { Ping , PingConfig , PingEvent , PingSuccess } ;
31
31
use log:: { debug, info, trace, warn} ;
32
- use std:: { borrow :: Cow , cmp , time:: Duration } ;
32
+ use std:: { cmp , iter , time:: Duration } ;
33
33
use tokio_io:: { AsyncRead , AsyncWrite } ;
34
34
use tokio_timer:: { Delay , clock:: Clock } ;
35
35
use void;
36
36
37
37
/// General behaviour of the network.
38
38
#[ derive( NetworkBehaviour ) ]
39
- #[ behaviour( out_event = "BehaviourOut<TMessage>" , poll_method = "poll" ) ]
40
- pub struct Behaviour < TMessage , TSubstream > {
39
+ #[ behaviour( out_event = "BehaviourOut<TBehaviourEv>" , poll_method = "poll" ) ]
40
+ pub struct Behaviour < TBehaviour , TBehaviourEv , TSubstream > {
41
+ /// Main protocol that handles everything except the discovery and the technicalities.
42
+ user_protocol : UserBehaviourWrap < TBehaviour > ,
41
43
/// Periodically ping nodes, and close the connection if it's unresponsive.
42
44
ping : Ping < TSubstream > ,
43
- /// Custom protocols (dot, bbq, sub, etc.).
44
- custom_protocols : CustomProto < TMessage , TSubstream > ,
45
45
/// Discovers nodes of the network. Defined below.
46
46
discovery : DiscoveryBehaviour < TSubstream > ,
47
47
/// Periodically identifies the remote and responds to incoming requests.
@@ -52,26 +52,23 @@ pub struct Behaviour<TMessage, TSubstream> {
52
52
53
53
/// Queue of events to produce for the outside.
54
54
#[ behaviour( ignore) ]
55
- events : Vec < BehaviourOut < TMessage > > ,
55
+ events : Vec < BehaviourOut < TBehaviourEv > > ,
56
56
}
57
57
58
- impl < TMessage , TSubstream > Behaviour < TMessage , TSubstream > {
58
+ impl < TBehaviour , TBehaviourEv , TSubstream > Behaviour < TBehaviour , TBehaviourEv , TSubstream > {
59
59
/// Builds a new `Behaviour`.
60
60
pub fn new (
61
+ user_protocol : TBehaviour ,
61
62
user_agent : String ,
62
63
local_public_key : PublicKey ,
63
- protocol : RegisteredProtocol < TMessage > ,
64
64
known_addresses : Vec < ( PeerId , Multiaddr ) > ,
65
- peerset : substrate_peerset:: Peerset ,
66
65
enable_mdns : bool ,
67
66
) -> Self {
68
67
let identify = {
69
68
let proto_version = "/substrate/1.0" . to_string ( ) ;
70
69
Identify :: new ( proto_version, user_agent, local_public_key. clone ( ) )
71
70
} ;
72
71
73
- let custom_protocols = CustomProto :: new ( protocol, peerset) ;
74
-
75
72
let mut kademlia = Kademlia :: new ( local_public_key. clone ( ) . into_peer_id ( ) ) ;
76
73
for ( peer_id, addr) in & known_addresses {
77
74
kademlia. add_connected_address ( peer_id, addr. clone ( ) ) ;
@@ -84,8 +81,8 @@ impl<TMessage, TSubstream> Behaviour<TMessage, TSubstream> {
84
81
85
82
let clock = Clock :: new ( ) ;
86
83
Behaviour {
84
+ user_protocol : UserBehaviourWrap ( user_protocol) ,
87
85
ping : Ping :: new ( PingConfig :: new ( ) ) ,
88
- custom_protocols,
89
86
discovery : DiscoveryBehaviour {
90
87
user_defined : known_addresses,
91
88
kademlia,
@@ -111,95 +108,34 @@ impl<TMessage, TSubstream> Behaviour<TMessage, TSubstream> {
111
108
}
112
109
}
113
110
114
- /// Sends a message to a peer.
115
- ///
116
- /// Has no effect if the custom protocol is not open with the given peer.
117
- ///
118
- /// Also note that even we have a valid open substream, it may in fact be already closed
119
- /// without us knowing, in which case the packet will not be received.
120
- #[ inline]
121
- pub fn send_custom_message ( & mut self , target : & PeerId , data : TMessage ) {
122
- self . custom_protocols . send_packet ( target, data)
123
- }
124
-
125
111
/// Returns the list of nodes that we know exist in the network.
126
112
pub fn known_peers ( & self ) -> impl Iterator < Item = & PeerId > {
127
113
self . discovery . kademlia . kbuckets_entries ( )
128
114
}
129
115
130
- /// Returns true if we try to open protocols with the given peer.
131
- pub fn is_enabled ( & self , peer_id : & PeerId ) -> bool {
132
- self . custom_protocols . is_enabled ( peer_id)
133
- }
134
-
135
- /// Returns true if we have an open protocol with the given peer.
136
- pub fn is_open ( & self , peer_id : & PeerId ) -> bool {
137
- self . custom_protocols . is_open ( peer_id)
138
- }
139
-
140
116
/// Adds a hard-coded address for the given peer, that never expires.
141
117
pub fn add_known_address ( & mut self , peer_id : PeerId , addr : Multiaddr ) {
142
118
if self . discovery . user_defined . iter ( ) . all ( |( p, a) | * p != peer_id && * a != addr) {
143
119
self . discovery . user_defined . push ( ( peer_id, addr) ) ;
144
120
}
145
121
}
146
122
147
- /// Disconnects the custom protocols from a peer.
148
- ///
149
- /// The peer will still be able to use Kademlia or other protocols, but will get disconnected
150
- /// after a few seconds of inactivity.
151
- ///
152
- /// This is asynchronous and does not instantly close the custom protocols.
153
- /// Corresponding closing events will be generated once the closing actually happens.
154
- ///
155
- /// Has no effect if we're not connected to the `PeerId`.
156
- #[ inline]
157
- pub fn drop_node ( & mut self , peer_id : & PeerId ) {
158
- self . custom_protocols . disconnect_peer ( peer_id)
123
+ /// Returns a shared reference to the user protocol.
124
+ pub fn user_protocol ( & self ) -> & TBehaviour {
125
+ & self . user_protocol . 0
159
126
}
160
127
161
- /// Returns the state of the peerset manager, for debugging purposes .
162
- pub fn peerset_debug_info ( & mut self ) -> serde_json :: Value {
163
- self . custom_protocols . peerset_debug_info ( )
128
+ /// Returns a mutable reference to the user protocol .
129
+ pub fn user_protocol_mut ( & mut self ) -> & mut TBehaviour {
130
+ & mut self . user_protocol . 0
164
131
}
165
132
}
166
133
167
134
/// Event that can be emitted by the behaviour.
168
135
#[ derive( Debug ) ]
169
- pub enum BehaviourOut < TMessage > {
170
- /// Opened a custom protocol with the remote.
171
- CustomProtocolOpen {
172
- /// Version of the protocol that has been opened.
173
- version : u8 ,
174
- /// Id of the node we have opened a connection with.
175
- peer_id : PeerId ,
176
- /// Endpoint used for this custom protocol.
177
- endpoint : ConnectedPoint ,
178
- } ,
179
-
180
- /// Closed a custom protocol with the remote.
181
- CustomProtocolClosed {
182
- /// Id of the peer we were connected to.
183
- peer_id : PeerId ,
184
- /// Reason why the substream closed, for diagnostic purposes.
185
- reason : Cow < ' static , str > ,
186
- } ,
187
-
188
- /// Receives a message on a custom protocol substream.
189
- CustomMessage {
190
- /// Id of the peer the message came from.
191
- peer_id : PeerId ,
192
- /// Message that has been received.
193
- message : TMessage ,
194
- } ,
195
-
196
- /// A substream with a remote is clogged. We should avoid sending more data to it if possible.
197
- Clogged {
198
- /// Id of the peer the message came from.
199
- peer_id : PeerId ,
200
- /// Copy of the messages that are within the buffer, for further diagnostic.
201
- messages : Vec < TMessage > ,
202
- } ,
136
+ pub enum BehaviourOut < TBehaviourEv > {
137
+ /// Message from the user protocol.
138
+ UserProtocol ( TBehaviourEv ) ,
203
139
204
140
/// We have obtained debug information from a peer.
205
141
Identified {
@@ -218,38 +154,21 @@ pub enum BehaviourOut<TMessage> {
218
154
} ,
219
155
}
220
156
221
- impl < TMessage > From < CustomProtoOut < TMessage > > for BehaviourOut < TMessage > {
222
- fn from ( other : CustomProtoOut < TMessage > ) -> BehaviourOut < TMessage > {
223
- match other {
224
- CustomProtoOut :: CustomProtocolOpen { version, peer_id, endpoint } => {
225
- BehaviourOut :: CustomProtocolOpen { version, peer_id, endpoint }
226
- }
227
- CustomProtoOut :: CustomProtocolClosed { peer_id, reason } => {
228
- BehaviourOut :: CustomProtocolClosed { peer_id, reason }
229
- }
230
- CustomProtoOut :: CustomMessage { peer_id, message } => {
231
- BehaviourOut :: CustomMessage { peer_id, message }
232
- }
233
- CustomProtoOut :: Clogged { peer_id, messages } => {
234
- BehaviourOut :: Clogged { peer_id, messages }
235
- }
236
- }
237
- }
238
- }
239
-
240
- impl < TMessage , TSubstream > NetworkBehaviourEventProcess < void:: Void > for Behaviour < TMessage , TSubstream > {
157
+ impl < TBehaviour , TBehaviourEv , TSubstream > NetworkBehaviourEventProcess < void:: Void > for Behaviour < TBehaviour , TBehaviourEv , TSubstream > {
241
158
fn inject_event ( & mut self , event : void:: Void ) {
242
159
void:: unreachable ( event)
243
160
}
244
161
}
245
162
246
- impl < TMessage , TSubstream > NetworkBehaviourEventProcess < CustomProtoOut < TMessage > > for Behaviour < TMessage , TSubstream > {
247
- fn inject_event ( & mut self , event : CustomProtoOut < TMessage > ) {
248
- self . events . push ( event. into ( ) ) ;
163
+ impl < TBehaviour , TBehaviourEv , TSubstream > NetworkBehaviourEventProcess < UserEventWrap < TBehaviourEv > > for Behaviour < TBehaviour , TBehaviourEv , TSubstream > {
164
+ fn inject_event ( & mut self , event : UserEventWrap < TBehaviourEv > ) {
165
+ self . events . push ( BehaviourOut :: UserProtocol ( event. 0 ) ) ;
249
166
}
250
167
}
251
168
252
- impl < TMessage , TSubstream > NetworkBehaviourEventProcess < IdentifyEvent > for Behaviour < TMessage , TSubstream > {
169
+ impl < TBehaviour , TBehaviourEv , TSubstream > NetworkBehaviourEventProcess < IdentifyEvent >
170
+ for Behaviour < TBehaviour , TBehaviourEv , TSubstream >
171
+ where TBehaviour : DiscoveryNetBehaviour {
253
172
fn inject_event ( & mut self , event : IdentifyEvent ) {
254
173
match event {
255
174
IdentifyEvent :: Identified { peer_id, mut info, .. } => {
@@ -270,7 +189,7 @@ impl<TMessage, TSubstream> NetworkBehaviourEventProcess<IdentifyEvent> for Behav
270
189
for addr in & info. listen_addrs {
271
190
self . discovery . kademlia . add_connected_address ( & peer_id, addr. clone ( ) ) ;
272
191
}
273
- self . custom_protocols . add_discovered_nodes ( Some ( peer_id. clone ( ) ) ) ;
192
+ self . user_protocol . 0 . add_discovered_nodes ( iter :: once ( peer_id. clone ( ) ) ) ;
274
193
self . events . push ( BehaviourOut :: Identified { peer_id, info } ) ;
275
194
}
276
195
IdentifyEvent :: Error { .. } => { }
@@ -282,12 +201,14 @@ impl<TMessage, TSubstream> NetworkBehaviourEventProcess<IdentifyEvent> for Behav
282
201
}
283
202
}
284
203
285
- impl < TMessage , TSubstream > NetworkBehaviourEventProcess < KademliaOut > for Behaviour < TMessage , TSubstream > {
204
+ impl < TBehaviour , TBehaviourEv , TSubstream > NetworkBehaviourEventProcess < KademliaOut >
205
+ for Behaviour < TBehaviour , TBehaviourEv , TSubstream >
206
+ where TBehaviour : DiscoveryNetBehaviour {
286
207
fn inject_event ( & mut self , out : KademliaOut ) {
287
208
match out {
288
209
KademliaOut :: Discovered { .. } => { }
289
210
KademliaOut :: KBucketAdded { peer_id, .. } => {
290
- self . custom_protocols . add_discovered_nodes ( Some ( peer_id) ) ;
211
+ self . user_protocol . 0 . add_discovered_nodes ( iter :: once ( peer_id) ) ;
291
212
}
292
213
KademliaOut :: FindNodeResult { key, closer_peers } => {
293
214
trace ! ( target: "sub-libp2p" , "Libp2p => Query for {:?} yielded {:?} results" ,
@@ -303,7 +224,7 @@ impl<TMessage, TSubstream> NetworkBehaviourEventProcess<KademliaOut> for Behavio
303
224
}
304
225
}
305
226
306
- impl < TMessage , TSubstream > NetworkBehaviourEventProcess < PingEvent > for Behaviour < TMessage , TSubstream > {
227
+ impl < TBehaviour , TBehaviourEv , TSubstream > NetworkBehaviourEventProcess < PingEvent > for Behaviour < TBehaviour , TBehaviourEv , TSubstream > {
307
228
fn inject_event ( & mut self , event : PingEvent ) {
308
229
match event {
309
230
PingEvent { peer, result : Ok ( PingSuccess :: Ping { rtt } ) } => {
@@ -316,19 +237,21 @@ impl<TMessage, TSubstream> NetworkBehaviourEventProcess<PingEvent> for Behaviour
316
237
}
317
238
318
239
#[ cfg( not( target_os = "unknown" ) ) ]
319
- impl < TMessage , TSubstream > NetworkBehaviourEventProcess < MdnsEvent > for Behaviour < TMessage , TSubstream > {
240
+ impl < TBehaviour , TBehaviourEv , TSubstream > NetworkBehaviourEventProcess < MdnsEvent > for
241
+ Behaviour < TBehaviour , TBehaviourEv , TSubstream >
242
+ where TBehaviour : DiscoveryNetBehaviour {
320
243
fn inject_event ( & mut self , event : MdnsEvent ) {
321
244
match event {
322
245
MdnsEvent :: Discovered ( list) => {
323
- self . custom_protocols . add_discovered_nodes ( list. into_iter ( ) . map ( |( peer_id, _) | peer_id) ) ;
246
+ self . user_protocol . 0 . add_discovered_nodes ( list. into_iter ( ) . map ( |( peer_id, _) | peer_id) ) ;
324
247
} ,
325
248
MdnsEvent :: Expired ( _) => { }
326
249
}
327
250
}
328
251
}
329
252
330
- impl < TMessage , TSubstream > Behaviour < TMessage , TSubstream > {
331
- fn poll < TEv > ( & mut self ) -> Async < NetworkBehaviourAction < TEv , BehaviourOut < TMessage > > > {
253
+ impl < TBehaviour , TBehaviourEv , TSubstream > Behaviour < TBehaviour , TBehaviourEv , TSubstream > {
254
+ fn poll < TEv > ( & mut self ) -> Async < NetworkBehaviourAction < TEv , BehaviourOut < TBehaviourEv > > > {
332
255
if !self . events . is_empty ( ) {
333
256
return Async :: Ready ( NetworkBehaviourAction :: GenerateEvent ( self . events . remove ( 0 ) ) )
334
257
}
@@ -337,6 +260,69 @@ impl<TMessage, TSubstream> Behaviour<TMessage, TSubstream> {
337
260
}
338
261
}
339
262
263
+ /// Because of limitations with the network behaviour custom derive and trait impl duplication, we
264
+ /// have to wrap the user protocol into a struct.
265
+ pub struct UserBehaviourWrap < TInner > ( TInner ) ;
266
+ /// Event produced by `UserBehaviourWrap`.
267
+ pub struct UserEventWrap < TInner > ( TInner ) ;
268
+ impl < TInner : NetworkBehaviour > NetworkBehaviour for UserBehaviourWrap < TInner > {
269
+ type ProtocolsHandler = TInner :: ProtocolsHandler ;
270
+ type OutEvent = UserEventWrap < TInner :: OutEvent > ;
271
+ fn new_handler ( & mut self ) -> Self :: ProtocolsHandler { self . 0 . new_handler ( ) }
272
+ fn addresses_of_peer ( & mut self , peer_id : & PeerId ) -> Vec < Multiaddr > {
273
+ self . 0 . addresses_of_peer ( peer_id)
274
+ }
275
+ fn inject_connected ( & mut self , peer_id : PeerId , endpoint : ConnectedPoint ) {
276
+ self . 0 . inject_connected ( peer_id, endpoint)
277
+ }
278
+ fn inject_disconnected ( & mut self , peer_id : & PeerId , endpoint : ConnectedPoint ) {
279
+ self . 0 . inject_disconnected ( peer_id, endpoint)
280
+ }
281
+ fn inject_node_event (
282
+ & mut self ,
283
+ peer_id : PeerId ,
284
+ event : <<Self :: ProtocolsHandler as IntoProtocolsHandler >:: Handler as ProtocolsHandler >:: OutEvent
285
+ ) {
286
+ self . 0 . inject_node_event ( peer_id, event)
287
+ }
288
+ fn poll (
289
+ & mut self ,
290
+ params : & mut PollParameters
291
+ ) -> Async < NetworkBehaviourAction < <<Self :: ProtocolsHandler as IntoProtocolsHandler >:: Handler as ProtocolsHandler >:: InEvent , Self :: OutEvent > > {
292
+ match self . 0 . poll ( params) {
293
+ Async :: NotReady => Async :: NotReady ,
294
+ Async :: Ready ( NetworkBehaviourAction :: GenerateEvent ( ev) ) =>
295
+ Async :: Ready ( NetworkBehaviourAction :: GenerateEvent ( UserEventWrap ( ev) ) ) ,
296
+ Async :: Ready ( NetworkBehaviourAction :: DialAddress { address } ) =>
297
+ Async :: Ready ( NetworkBehaviourAction :: DialAddress { address } ) ,
298
+ Async :: Ready ( NetworkBehaviourAction :: DialPeer { peer_id } ) =>
299
+ Async :: Ready ( NetworkBehaviourAction :: DialPeer { peer_id } ) ,
300
+ Async :: Ready ( NetworkBehaviourAction :: SendEvent { peer_id, event } ) =>
301
+ Async :: Ready ( NetworkBehaviourAction :: SendEvent { peer_id, event } ) ,
302
+ Async :: Ready ( NetworkBehaviourAction :: ReportObservedAddr { address } ) =>
303
+ Async :: Ready ( NetworkBehaviourAction :: ReportObservedAddr { address } ) ,
304
+ }
305
+ }
306
+ fn inject_replaced ( & mut self , peer_id : PeerId , closed_endpoint : ConnectedPoint , new_endpoint : ConnectedPoint ) {
307
+ self . 0 . inject_replaced ( peer_id, closed_endpoint, new_endpoint)
308
+ }
309
+ fn inject_addr_reach_failure ( & mut self , peer_id : Option < & PeerId > , addr : & Multiaddr , error : & dyn std:: error:: Error ) {
310
+ self . 0 . inject_addr_reach_failure ( peer_id, addr, error)
311
+ }
312
+ fn inject_dial_failure ( & mut self , peer_id : & PeerId ) {
313
+ self . 0 . inject_dial_failure ( peer_id)
314
+ }
315
+ fn inject_new_listen_addr ( & mut self , addr : & Multiaddr ) {
316
+ self . 0 . inject_new_listen_addr ( addr)
317
+ }
318
+ fn inject_expired_listen_addr ( & mut self , addr : & Multiaddr ) {
319
+ self . 0 . inject_expired_listen_addr ( addr)
320
+ }
321
+ fn inject_new_external_addr ( & mut self , addr : & Multiaddr ) {
322
+ self . 0 . inject_new_external_addr ( addr)
323
+ }
324
+ }
325
+
340
326
/// Implementation of `NetworkBehaviour` that discovers the nodes on the network.
341
327
pub struct DiscoveryBehaviour < TSubstream > {
342
328
/// User-defined list of nodes and their addresses. Typically includes bootstrap nodes and
0 commit comments