@@ -54,13 +54,17 @@ fn test_subscribe() {
5454 "Subscribe should add a new entry to the mesh[topic] hashmap"
5555 ) ;
5656
57- // collect all the subscriptions
57+ // collect all the subscriptions (hello RPC on connection is now a single SubscribeMany)
5858 let subscriptions = queues
5959 . into_values ( )
6060 . fold ( 0 , |mut collected_subscriptions, mut queue| {
6161 while !queue. is_empty ( ) {
62- if let Some ( RpcOut :: Subscribe { .. } ) = queue. try_pop ( ) {
63- collected_subscriptions += 1
62+ match queue. try_pop ( ) {
63+ Some ( RpcOut :: Subscribe { .. } ) => collected_subscriptions += 1 ,
64+ Some ( RpcOut :: SubscribeMany ( topics) ) => {
65+ collected_subscriptions += topics. len ( )
66+ }
67+ _ => { }
6468 }
6569 }
6670 collected_subscriptions
@@ -114,19 +118,23 @@ fn test_unsubscribe() {
114118 "should be able to unsubscribe successfully from each topic" ,
115119 ) ;
116120
117- // collect all the subscriptions
121+ // collect all the subscriptions (hello RPC on connection is now a single SubscribeMany)
118122 let subscriptions = queues
119123 . into_values ( )
120124 . fold ( 0 , |mut collected_subscriptions, mut queue| {
121125 while !queue. is_empty ( ) {
122- if let Some ( RpcOut :: Subscribe { .. } ) = queue. try_pop ( ) {
123- collected_subscriptions += 1
126+ match queue. try_pop ( ) {
127+ Some ( RpcOut :: Subscribe { .. } ) => collected_subscriptions += 1 ,
128+ Some ( RpcOut :: SubscribeMany ( topics) ) => {
129+ collected_subscriptions += topics. len ( )
130+ }
131+ _ => { }
124132 }
125133 }
126134 collected_subscriptions
127135 } ) ;
128136
129- // we sent a unsubscribe to all known peers, for two topics
137+ // we sent subscriptions to all known peers for two topics (20 peers × 2 topics)
130138 assert_eq ! ( subscriptions, 40 ) ;
131139
132140 // check we clean up internal structures
@@ -303,23 +311,22 @@ fn test_peer_added_on_connection() {
303311 . to_subscribe ( true )
304312 . create_network ( ) ;
305313
306- // check that our subscriptions are sent to each of the peers
307- // collect all the SendEvents
314+ // check that our subscriptions are sent to each of the peers as a single hello RPC
308315 let subscriptions = queues. into_iter ( ) . fold (
309316 HashMap :: < libp2p_identity:: PeerId , Vec < String > > :: new ( ) ,
310317 |mut collected_subscriptions, ( peer, mut queue) | {
311318 while !queue. is_empty ( ) {
312- if let Some ( RpcOut :: Subscribe { topic , .. } ) = queue. try_pop ( ) {
313- let mut peer_subs = collected_subscriptions . remove ( & peer ) . unwrap_or_default ( ) ;
314- peer_subs . push ( topic . into_string ( ) ) ;
319+ if let Some ( RpcOut :: SubscribeMany ( topics ) ) = queue. try_pop ( ) {
320+ let peer_subs: Vec < String > =
321+ topics . into_iter ( ) . map ( | ( t , _ , _ ) | t . into_string ( ) ) . collect ( ) ;
315322 collected_subscriptions. insert ( peer, peer_subs) ;
316323 }
317324 }
318325 collected_subscriptions
319326 } ,
320327 ) ;
321328
322- // check that there are two subscriptions sent to each peer
329+ // check that there are two subscriptions sent to each peer in a single RPC
323330 for peer_subs in subscriptions. values ( ) {
324331 assert ! ( peer_subs. contains( & String :: from( "topic1" ) ) ) ;
325332 assert ! ( peer_subs. contains( & String :: from( "topic2" ) ) ) ;
@@ -339,6 +346,53 @@ fn test_peer_added_on_connection() {
339346 }
340347}
341348
349+ /// Test that on new connection the hello RPC is a single batched message, not one per topic.
350+ #[ test]
351+ fn test_hello_rpc_is_single_batched_message ( ) {
352+ let topic_names = vec ! [
353+ String :: from( "alpha" ) ,
354+ String :: from( "beta" ) ,
355+ String :: from( "gamma" ) ,
356+ ] ;
357+ let ( _, _, queues, topic_hashes) = DefaultBehaviourTestBuilder :: default ( )
358+ . peer_no ( 5 )
359+ . topics ( topic_names)
360+ . to_subscribe ( true )
361+ . create_network ( ) ;
362+
363+ for ( _, mut queue) in queues {
364+ let mut subscribe_many_count = 0 ;
365+ let mut individual_subscribe_count = 0 ;
366+
367+ while !queue. is_empty ( ) {
368+ match queue. try_pop ( ) {
369+ Some ( RpcOut :: SubscribeMany ( topics) ) => {
370+ subscribe_many_count += 1 ;
371+ // All topics must be present in the single hello packet.
372+ let sent: Vec < _ > = topics. into_iter ( ) . map ( |( t, _, _) | t) . collect ( ) ;
373+ for topic_hash in & topic_hashes {
374+ assert ! (
375+ sent. contains( topic_hash) ,
376+ "hello RPC must include all subscribed topics"
377+ ) ;
378+ }
379+ }
380+ Some ( RpcOut :: Subscribe { .. } ) => individual_subscribe_count += 1 ,
381+ _ => { }
382+ }
383+ }
384+
385+ assert_eq ! (
386+ subscribe_many_count, 1 ,
387+ "exactly one batched hello RPC should be sent per peer"
388+ ) ;
389+ assert_eq ! (
390+ individual_subscribe_count, 0 ,
391+ "no individual Subscribe RPCs should be sent on connection"
392+ ) ;
393+ }
394+ }
395+
342396/// Test subscription handling
343397#[ test]
344398fn test_handle_received_subscriptions ( ) {
0 commit comments