@@ -3,7 +3,7 @@ use futures::StreamExt;
3
3
use libp2p:: {
4
4
gossipsub, noise,
5
5
swarm:: { NetworkBehaviour , SwarmEvent } ,
6
- upnp, yamux, Multiaddr ,
6
+ upnp, yamux, Multiaddr , PeerId ,
7
7
} ;
8
8
use log:: { error, info} ;
9
9
use rsa:: signature:: SignatureEncoding ;
@@ -90,13 +90,15 @@ struct MyBehaviour {
90
90
enum Event {
91
91
Upnp ( upnp:: Event ) ,
92
92
StdIn ( String ) ,
93
- Msg ( Msg ) ,
93
+ Msg ( Msg , PeerId ) ,
94
+ ConnectionClosed ( PeerId ) ,
94
95
}
95
96
96
97
#[ derive( Debug , Clone , Serialize , Deserialize ) ]
97
98
enum Msg {
98
99
Join ( PublicKey , String ) ,
99
- Participants ( HashMap < PublicKey , String > ) ,
100
+ Quit ( PeerId , String ) ,
101
+ Participants ( HashMap < PublicKey , ( String , PeerId ) > ) ,
100
102
LobbyNowClosed ,
101
103
Share {
102
104
from : PublicKey ,
@@ -120,7 +122,17 @@ enum Phase {
120
122
SendingShares ,
121
123
}
122
124
123
- fn print_results ( results : & BTreeMap < String , i64 > , participants : & HashMap < PublicKey , String > ) {
125
+ fn print_participants ( participants : & HashMap < PublicKey , ( String , PeerId ) > ) {
126
+ println ! ( "\n -- Participants --" ) ;
127
+ for ( pub_key, ( name, _) ) in participants {
128
+ println ! ( "{pub_key} - {name}" ) ;
129
+ }
130
+ }
131
+
132
+ fn print_results (
133
+ results : & BTreeMap < String , i64 > ,
134
+ participants : & HashMap < PublicKey , ( String , PeerId ) > ,
135
+ ) {
124
136
println ! ( "\n Average results:" ) ;
125
137
for ( key, result) in results. iter ( ) {
126
138
let avg = ( * result as f64 / participants. len ( ) as f64 ) / 100.00 ;
@@ -200,7 +212,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
200
212
201
213
let mut phase = Phase :: WaitingForParticipants ;
202
214
let mut stdin = io:: BufReader :: new ( io:: stdin ( ) ) . lines ( ) ;
203
- let mut participants = HashMap :: < PublicKey , String > :: new ( ) ;
215
+ let mut participants = HashMap :: < PublicKey , ( String , PeerId ) > :: new ( ) ;
204
216
let mut sent_shares = HashMap :: < PublicKey , HashMap < & String , i64 > > :: new ( ) ;
205
217
let mut received_shares = HashMap :: < PublicKey , Vec < u8 > > :: new ( ) ;
206
218
let mut sums = HashMap :: < PublicKey , HashMap < String , i64 > > :: new ( ) ;
@@ -363,20 +375,13 @@ async fn main() -> Result<(), Box<dyn Error>> {
363
375
received_shares. insert( from, share) ;
364
376
}
365
377
}
366
- Event :: Msg ( msg)
378
+ Event :: Msg ( msg, propagation_source )
367
379
} ,
368
380
SwarmEvent :: IncomingConnectionError { .. } => {
369
381
eprintln!( "Error while establishing incoming connection" ) ;
370
382
continue ;
371
383
} ,
372
- SwarmEvent :: ConnectionClosed { .. } => {
373
- if result. is_none( ) {
374
- eprintln!( "Connection has been closed by one of the participants" ) ;
375
- std:: process:: exit( 1 ) ;
376
- } else {
377
- std:: process:: exit( 0 ) ;
378
- }
379
- } ,
384
+ SwarmEvent :: ConnectionClosed { peer_id, .. } => Event :: ConnectionClosed ( peer_id) ,
380
385
ev => {
381
386
info!( "{ev:?}" ) ;
382
387
continue ;
@@ -433,7 +438,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
433
438
println ! ( "{pub_key} - {name}" ) ;
434
439
}
435
440
swarm. behaviour_mut ( ) . gossipsub . subscribe ( & topic) ?;
436
- participants. insert ( pub_key. clone ( ) , name. clone ( ) ) ;
441
+ participants. insert ( pub_key. clone ( ) , ( name. clone ( ) , * swarm . local_peer_id ( ) ) ) ;
437
442
}
438
443
( _, Event :: Upnp ( upnp:: Event :: GatewayNotFound ) ) => {
439
444
error ! ( "Gateway does not support UPnP" ) ;
@@ -444,20 +449,62 @@ async fn main() -> Result<(), Box<dyn Error>> {
444
449
break ;
445
450
}
446
451
( _, Event :: Upnp ( ev) ) => info ! ( "{ev:?}" ) ,
447
- ( Phase :: WaitingForParticipants , Event :: Msg ( msg) ) => match msg {
452
+ ( Phase :: WaitingForParticipants , Event :: ConnectionClosed ( peer_id) ) => {
453
+ if result. is_none ( ) {
454
+ let Some ( disconnected) =
455
+ participants. iter ( ) . find ( |( _, ( _, id) ) | * id == peer_id)
456
+ else {
457
+ println ! ( "Connection error, please try again." ) ;
458
+ std:: process:: exit ( 1 ) ;
459
+ } ;
460
+
461
+ let disconnected = disconnected. 1 . 0 . clone ( ) ;
462
+
463
+ println ! ( "\n Participant {disconnected} disconnected" ) ;
464
+
465
+ if swarm. connected_peers ( ) . count ( ) == 0 && is_leader {
466
+ participants. retain ( |_, ( _, id) | * id != peer_id) ;
467
+ } else if is_leader {
468
+ let msg = Msg :: Quit ( peer_id, disconnected) . serialize ( ) ?;
469
+ swarm
470
+ . behaviour_mut ( )
471
+ . gossipsub
472
+ . publish ( topic. clone ( ) , msg) ?;
473
+
474
+ participants. retain ( |_, ( _, id) | * id != peer_id) ;
475
+
476
+ print_participants ( & participants) ;
477
+
478
+ let msg = Msg :: Participants ( participants. clone ( ) ) . serialize ( ) ?;
479
+ if let Err ( e) = swarm. behaviour_mut ( ) . gossipsub . publish ( topic. clone ( ) , msg)
480
+ {
481
+ error ! ( "Could not publish to gossipsub: {e:?}" ) ;
482
+ }
483
+ }
484
+ continue ;
485
+ } else {
486
+ std:: process:: exit ( 0 ) ;
487
+ }
488
+ }
489
+ ( Phase :: WaitingForParticipants , Event :: Msg ( msg, peer_id) ) => match msg {
448
490
Msg :: Join ( public_key, name) => {
449
491
if is_leader {
450
492
println ! ( "{public_key} - {name}" ) ;
451
- participants. insert ( public_key, name) ;
493
+ participants. insert ( public_key, ( name, peer_id ) ) ;
452
494
let msg = Msg :: Participants ( participants. clone ( ) ) . serialize ( ) ?;
453
495
if let Err ( e) = swarm. behaviour_mut ( ) . gossipsub . publish ( topic. clone ( ) , msg)
454
496
{
455
497
error ! ( "Could not publish to gossipsub: {e:?}" ) ;
456
498
}
457
499
}
458
500
}
501
+ Msg :: Quit ( _, name) => {
502
+ println ! ( "\n Participant {name} disconnected" ) ;
503
+
504
+ print_participants ( & participants) ;
505
+ }
459
506
Msg :: Participants ( all_participants) => {
460
- for ( public_key, name) in all_participants. iter ( ) {
507
+ for ( public_key, ( name, _ ) ) in all_participants. iter ( ) {
461
508
if !participants. contains_key ( public_key) {
462
509
println ! ( "{public_key} - {name}" ) ;
463
510
}
@@ -485,14 +532,14 @@ async fn main() -> Result<(), Box<dyn Error>> {
485
532
std:: process:: exit ( 1 ) ;
486
533
}
487
534
} ,
488
- ( Phase :: SendingShares , Event :: Msg ( msg) ) => match msg {
535
+ ( Phase :: SendingShares , Event :: Msg ( msg, _peer_id ) ) => match msg {
489
536
Msg :: Join ( _, _) | Msg :: Participants ( _) | Msg :: LobbyNowClosed => {
490
537
println ! (
491
538
"Already waiting for shares, but some participant still tried to join!"
492
539
) ;
493
540
continue ;
494
541
}
495
- Msg :: Share { .. } => { }
542
+ Msg :: Quit ( .. ) | Msg :: Share { .. } => { } ,
496
543
Msg :: Sum ( public_key, sum) => {
497
544
if is_leader {
498
545
sums. insert ( public_key, sum) ;
@@ -503,6 +550,23 @@ async fn main() -> Result<(), Box<dyn Error>> {
503
550
std:: process:: exit ( 0 ) ;
504
551
}
505
552
} ,
553
+ ( Phase :: SendingShares , Event :: ConnectionClosed ( peer_id) ) => {
554
+ if is_leader {
555
+ let Some ( ( _, ( disconnected, _) ) ) =
556
+ participants. iter ( ) . find ( |( _, ( _, id) ) | * id == peer_id)
557
+ else {
558
+ println ! ( "Connection error, please try again." ) ;
559
+ std:: process:: exit ( 1 ) ;
560
+ } ;
561
+
562
+ println ! (
563
+ "Aborting benchmark: participant {disconnected} left the while waiting for shares"
564
+ ) ;
565
+ } else {
566
+ println ! ( "Aborting benchmark: a participant left while waiting for shares" ) ;
567
+ }
568
+ std:: process:: exit ( 1 ) ;
569
+ }
506
570
( Phase :: ConfirmingParticipants , _) => { }
507
571
}
508
572
}
0 commit comments