18
18
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19
19
// DEALINGS IN THE SOFTWARE.
20
20
21
- use crate :: handler:: { self , Proto , Push } ;
22
- use crate :: protocol:: { Info , ReplySubstream , UpgradeError } ;
23
- use futures:: prelude:: * ;
21
+ use crate :: handler:: { self , InEvent , Proto } ;
22
+ use crate :: protocol:: { Info , Protocol , UpgradeError } ;
24
23
use libp2p_core:: {
25
- connection:: ConnectionId , multiaddr:: Protocol , ConnectedPoint , Multiaddr , PeerId , PublicKey ,
24
+ connection:: ConnectionId , multiaddr, ConnectedPoint , Multiaddr , PeerId , PublicKey ,
26
25
} ;
27
26
use libp2p_swarm:: behaviour:: { ConnectionClosed , ConnectionEstablished , DialFailure , FromSwarm } ;
28
27
use libp2p_swarm:: {
29
28
dial_opts:: DialOpts , AddressScore , ConnectionHandler , ConnectionHandlerUpgrErr , DialError ,
30
- IntoConnectionHandler , NegotiatedSubstream , NetworkBehaviour , NetworkBehaviourAction ,
31
- NotifyHandler , PollParameters ,
29
+ IntoConnectionHandler , NetworkBehaviour , NetworkBehaviourAction , NotifyHandler , PollParameters ,
32
30
} ;
33
31
use lru:: LruCache ;
34
32
use std:: num:: NonZeroUsize ;
35
33
use std:: {
36
34
collections:: { HashMap , HashSet , VecDeque } ,
37
35
iter:: FromIterator ,
38
- pin:: Pin ,
39
36
task:: Context ,
40
37
task:: Poll ,
41
38
time:: Duration ,
@@ -51,30 +48,23 @@ pub struct Behaviour {
51
48
config : Config ,
52
49
/// For each peer we're connected to, the observed address to send back to it.
53
50
connected : HashMap < PeerId , HashMap < ConnectionId , Multiaddr > > ,
54
- /// Pending replies to send.
55
- pending_replies : VecDeque < Reply > ,
51
+ /// Pending requests to be fulfilled, either `Handler` requests for `Behaviour` info
52
+ /// to address identification requests, or push requests to peers
53
+ /// with current information about the local peer.
54
+ requests : Vec < Request > ,
56
55
/// Pending events to be emitted when polled.
57
56
events : VecDeque < NetworkBehaviourAction < Event , Proto > > ,
58
- /// Peers to which an active push with current information about
59
- /// the local peer should be sent.
60
- pending_push : HashSet < PeerId > ,
61
57
/// The addresses of all peers that we have discovered.
62
58
discovered_peers : PeerCache ,
63
59
}
64
60
65
- /// A pending reply to an inbound identification request.
66
- enum Reply {
67
- /// The reply is queued for sending.
68
- Queued {
69
- peer : PeerId ,
70
- io : ReplySubstream < NegotiatedSubstream > ,
71
- observed : Multiaddr ,
72
- } ,
73
- /// The reply is being sent.
74
- Sending {
75
- peer : PeerId ,
76
- io : Pin < Box < dyn Future < Output = Result < ( ) , UpgradeError > > + Send > > ,
77
- } ,
61
+ /// A `Behaviour` request to be fulfilled, either `Handler` requests for `Behaviour` info
62
+ /// to address identification requests, or push requests to peers
63
+ /// with current information about the local peer.
64
+ #[ derive( Debug , PartialEq , Eq ) ]
65
+ struct Request {
66
+ peer_id : PeerId ,
67
+ protocol : Protocol ,
78
68
}
79
69
80
70
/// Configuration for the [`identify::Behaviour`](Behaviour).
@@ -184,9 +174,8 @@ impl Behaviour {
184
174
Self {
185
175
config,
186
176
connected : HashMap :: new ( ) ,
187
- pending_replies : VecDeque :: new ( ) ,
177
+ requests : Vec :: new ( ) ,
188
178
events : VecDeque :: new ( ) ,
189
- pending_push : HashSet :: new ( ) ,
190
179
discovered_peers,
191
180
}
192
181
}
@@ -197,7 +186,13 @@ impl Behaviour {
197
186
I : IntoIterator < Item = PeerId > ,
198
187
{
199
188
for p in peers {
200
- if self . pending_push . insert ( p) && !self . connected . contains_key ( & p) {
189
+ let request = Request {
190
+ peer_id : p,
191
+ protocol : Protocol :: Push ,
192
+ } ;
193
+ if !self . requests . contains ( & request) {
194
+ self . requests . push ( request) ;
195
+
201
196
let handler = self . new_handler ( ) ;
202
197
self . events . push_back ( NetworkBehaviourAction :: Dial {
203
198
opts : DialOpts :: peer_id ( p) . build ( ) ,
@@ -240,13 +235,19 @@ impl NetworkBehaviour for Behaviour {
240
235
type OutEvent = Event ;
241
236
242
237
fn new_handler ( & mut self ) -> Self :: ConnectionHandler {
243
- Proto :: new ( self . config . initial_delay , self . config . interval )
238
+ Proto :: new (
239
+ self . config . initial_delay ,
240
+ self . config . interval ,
241
+ self . config . local_public_key . clone ( ) ,
242
+ self . config . protocol_version . clone ( ) ,
243
+ self . config . agent_version . clone ( ) ,
244
+ )
244
245
}
245
246
246
247
fn on_connection_handler_event (
247
248
& mut self ,
248
249
peer_id : PeerId ,
249
- connection : ConnectionId ,
250
+ connection_id : ConnectionId ,
250
251
event : <<Self :: ConnectionHandler as IntoConnectionHandler >:: Handler as ConnectionHandler >:: OutEvent ,
251
252
) {
252
253
match event {
@@ -271,26 +272,22 @@ impl NetworkBehaviour for Behaviour {
271
272
score : AddressScore :: Finite ( 1 ) ,
272
273
} ) ;
273
274
}
275
+ handler:: Event :: Identification ( peer) => {
276
+ self . events
277
+ . push_back ( NetworkBehaviourAction :: GenerateEvent ( Event :: Sent {
278
+ peer_id : peer,
279
+ } ) ) ;
280
+ }
274
281
handler:: Event :: IdentificationPushed => {
275
282
self . events
276
283
. push_back ( NetworkBehaviourAction :: GenerateEvent ( Event :: Pushed {
277
284
peer_id,
278
285
} ) ) ;
279
286
}
280
- handler:: Event :: Identify ( sender) => {
281
- let observed = self
282
- . connected
283
- . get ( & peer_id)
284
- . and_then ( |addrs| addrs. get ( & connection) )
285
- . expect (
286
- "`on_connection_handler_event` is only called \
287
- with an established connection and calling `NetworkBehaviour::on_event` \
288
- with `FromSwarm::ConnectionEstablished ensures there is an entry; qed",
289
- ) ;
290
- self . pending_replies . push_back ( Reply :: Queued {
291
- peer : peer_id,
292
- io : sender,
293
- observed : observed. clone ( ) ,
287
+ handler:: Event :: Identify => {
288
+ self . requests . push ( Request {
289
+ peer_id,
290
+ protocol : Protocol :: Identify ( connection_id) ,
294
291
} ) ;
295
292
}
296
293
handler:: Event :: IdentificationError ( error) => {
@@ -305,99 +302,41 @@ impl NetworkBehaviour for Behaviour {
305
302
306
303
fn poll (
307
304
& mut self ,
308
- cx : & mut Context < ' _ > ,
305
+ _cx : & mut Context < ' _ > ,
309
306
params : & mut impl PollParameters ,
310
307
) -> Poll < NetworkBehaviourAction < Self :: OutEvent , Self :: ConnectionHandler > > {
311
308
if let Some ( event) = self . events . pop_front ( ) {
312
309
return Poll :: Ready ( event) ;
313
310
}
314
311
315
- // Check for a pending active push to perform.
316
- let peer_push = self . pending_push . iter ( ) . find_map ( |peer| {
317
- self . connected . get ( peer) . map ( |conns| {
318
- let observed_addr = conns
319
- . values ( )
320
- . next ( )
321
- . expect ( "connected peer has a connection" )
322
- . clone ( ) ;
323
-
324
- let listen_addrs = listen_addrs ( params) ;
325
- let protocols = supported_protocols ( params) ;
326
-
327
- let info = Info {
328
- public_key : self . config . local_public_key . clone ( ) ,
329
- protocol_version : self . config . protocol_version . clone ( ) ,
330
- agent_version : self . config . agent_version . clone ( ) ,
331
- listen_addrs,
332
- protocols,
333
- observed_addr,
334
- } ;
335
-
336
- ( * peer, Push ( info) )
337
- } )
338
- } ) ;
339
-
340
- if let Some ( ( peer_id, push) ) = peer_push {
341
- self . pending_push . remove ( & peer_id) ;
342
- return Poll :: Ready ( NetworkBehaviourAction :: NotifyHandler {
312
+ // Check for pending requests.
313
+ match self . requests . pop ( ) {
314
+ Some ( Request {
315
+ peer_id,
316
+ protocol : Protocol :: Push ,
317
+ } ) => Poll :: Ready ( NetworkBehaviourAction :: NotifyHandler {
343
318
peer_id,
344
- event : push,
345
319
handler : NotifyHandler :: Any ,
346
- } ) ;
347
- }
348
-
349
- // Check for pending replies to send.
350
- if let Some ( r) = self . pending_replies . pop_front ( ) {
351
- let mut sending = 0 ;
352
- let to_send = self . pending_replies . len ( ) + 1 ;
353
- let mut reply = Some ( r) ;
354
- loop {
355
- match reply {
356
- Some ( Reply :: Queued { peer, io, observed } ) => {
357
- let info = Info {
358
- listen_addrs : listen_addrs ( params) ,
359
- protocols : supported_protocols ( params) ,
360
- public_key : self . config . local_public_key . clone ( ) ,
361
- protocol_version : self . config . protocol_version . clone ( ) ,
362
- agent_version : self . config . agent_version . clone ( ) ,
363
- observed_addr : observed,
364
- } ;
365
- let io = Box :: pin ( io. send ( info) ) ;
366
- reply = Some ( Reply :: Sending { peer, io } ) ;
367
- }
368
- Some ( Reply :: Sending { peer, mut io } ) => {
369
- sending += 1 ;
370
- match Future :: poll ( Pin :: new ( & mut io) , cx) {
371
- Poll :: Ready ( Ok ( ( ) ) ) => {
372
- let event = Event :: Sent { peer_id : peer } ;
373
- return Poll :: Ready ( NetworkBehaviourAction :: GenerateEvent ( event) ) ;
374
- }
375
- Poll :: Pending => {
376
- self . pending_replies . push_back ( Reply :: Sending { peer, io } ) ;
377
- if sending == to_send {
378
- // All remaining futures are NotReady
379
- break ;
380
- } else {
381
- reply = self . pending_replies . pop_front ( ) ;
382
- }
383
- }
384
- Poll :: Ready ( Err ( err) ) => {
385
- let event = Event :: Error {
386
- peer_id : peer,
387
- error : ConnectionHandlerUpgrErr :: Upgrade (
388
- libp2p_core:: upgrade:: UpgradeError :: Apply ( err) ,
389
- ) ,
390
- } ;
391
- return Poll :: Ready ( NetworkBehaviourAction :: GenerateEvent ( event) ) ;
392
- }
393
- }
394
- }
395
- None => unreachable ! ( ) ,
396
- }
397
- }
320
+ event : InEvent {
321
+ listen_addrs : listen_addrs ( params) ,
322
+ supported_protocols : supported_protocols ( params) ,
323
+ protocol : Protocol :: Push ,
324
+ } ,
325
+ } ) ,
326
+ Some ( Request {
327
+ peer_id,
328
+ protocol : Protocol :: Identify ( connection_id) ,
329
+ } ) => Poll :: Ready ( NetworkBehaviourAction :: NotifyHandler {
330
+ peer_id,
331
+ handler : NotifyHandler :: One ( connection_id) ,
332
+ event : InEvent {
333
+ listen_addrs : listen_addrs ( params) ,
334
+ supported_protocols : supported_protocols ( params) ,
335
+ protocol : Protocol :: Identify ( connection_id) ,
336
+ } ,
337
+ } ) ,
338
+ None => Poll :: Pending ,
398
339
}
399
-
400
- Poll :: Pending
401
340
}
402
341
403
342
fn addresses_of_peer ( & mut self , peer : & PeerId ) -> Vec < Multiaddr > {
@@ -417,15 +356,27 @@ impl NetworkBehaviour for Behaviour {
417
356
} ) => {
418
357
if remaining_established == 0 {
419
358
self . connected . remove ( & peer_id) ;
420
- self . pending_push . remove ( & peer_id) ;
359
+ self . requests . retain ( |request| {
360
+ request
361
+ != & Request {
362
+ peer_id,
363
+ protocol : Protocol :: Push ,
364
+ }
365
+ } ) ;
421
366
} else if let Some ( addrs) = self . connected . get_mut ( & peer_id) {
422
367
addrs. remove ( & connection_id) ;
423
368
}
424
369
}
425
370
FromSwarm :: DialFailure ( DialFailure { peer_id, error, .. } ) => {
426
371
if let Some ( peer_id) = peer_id {
427
372
if !self . connected . contains_key ( & peer_id) {
428
- self . pending_push . remove ( & peer_id) ;
373
+ self . requests . retain ( |request| {
374
+ request
375
+ != & Request {
376
+ peer_id,
377
+ protocol : Protocol :: Push ,
378
+ }
379
+ } ) ;
429
380
}
430
381
}
431
382
@@ -437,14 +388,17 @@ impl NetworkBehaviour for Behaviour {
437
388
}
438
389
}
439
390
}
440
- FromSwarm :: NewListenAddr ( _) => {
441
- if self . config . push_listen_addr_updates {
442
- self . pending_push . extend ( self . connected . keys ( ) ) ;
443
- }
444
- }
445
- FromSwarm :: ExpiredListenAddr ( _) => {
391
+ FromSwarm :: NewListenAddr ( _) | FromSwarm :: ExpiredListenAddr ( _) => {
446
392
if self . config . push_listen_addr_updates {
447
- self . pending_push . extend ( self . connected . keys ( ) ) ;
393
+ for p in self . connected . keys ( ) {
394
+ let request = Request {
395
+ peer_id : * p,
396
+ protocol : Protocol :: Push ,
397
+ } ;
398
+ if !self . requests . contains ( & request) {
399
+ self . requests . push ( request) ;
400
+ }
401
+ }
448
402
}
449
403
}
450
404
FromSwarm :: AddressChange ( _)
@@ -509,7 +463,7 @@ fn listen_addrs(params: &impl PollParameters) -> Vec<Multiaddr> {
509
463
/// the given peer_id. If there is no peer_id for the peer in the mutiaddr, this returns true.
510
464
fn multiaddr_matches_peer_id ( addr : & Multiaddr , peer_id : & PeerId ) -> bool {
511
465
let last_component = addr. iter ( ) . last ( ) ;
512
- if let Some ( Protocol :: P2p ( multi_addr_peer_id) ) = last_component {
466
+ if let Some ( multiaddr :: Protocol :: P2p ( multi_addr_peer_id) ) = last_component {
513
467
return multi_addr_peer_id == * peer_id. as_ref ( ) ;
514
468
}
515
469
true
@@ -557,6 +511,7 @@ impl PeerCache {
557
511
mod tests {
558
512
use super :: * ;
559
513
use futures:: pin_mut;
514
+ use futures:: prelude:: * ;
560
515
use libp2p_core:: { identity, muxing:: StreamMuxerBox , transport, upgrade, PeerId , Transport } ;
561
516
use libp2p_mplex:: MplexConfig ;
562
517
use libp2p_noise as noise;
@@ -618,7 +573,7 @@ mod tests {
618
573
619
574
// nb. Either swarm may receive the `Identified` event first, upon which
620
575
// it will permit the connection to be closed, as defined by
621
- // `IdentifyHandler ::connection_keep_alive`. Hence the test succeeds if
576
+ // `Handler ::connection_keep_alive`. Hence the test succeeds if
622
577
// either `Identified` event arrives correctly.
623
578
async_std:: task:: block_on ( async move {
624
579
loop {
@@ -835,8 +790,8 @@ mod tests {
835
790
let addr_without_peer_id: Multiaddr = addr. clone ( ) ;
836
791
let mut addr_with_other_peer_id = addr. clone ( ) ;
837
792
838
- addr. push ( Protocol :: P2p ( peer_id. into ( ) ) ) ;
839
- addr_with_other_peer_id. push ( Protocol :: P2p ( other_peer_id. into ( ) ) ) ;
793
+ addr. push ( multiaddr :: Protocol :: P2p ( peer_id. into ( ) ) ) ;
794
+ addr_with_other_peer_id. push ( multiaddr :: Protocol :: P2p ( other_peer_id. into ( ) ) ) ;
840
795
841
796
assert ! ( multiaddr_matches_peer_id( & addr, & peer_id) ) ;
842
797
assert ! ( !multiaddr_matches_peer_id(
0 commit comments