@@ -309,4 +309,142 @@ async fn aggregated_translator_correctly_deals_with_group_channels() {
309309 share_channel_id, group_channel_id,
310310 "Share NOT submitted to the group channel ID"
311311 ) ;
312- }
312+ }
313+
314+ // This test launches a tProxy in non-aggregated mode and leverages a MockUpstream to test the
315+ // correct functionalities of grouping standard channels.
316+ #[ tokio:: test]
317+ async fn non_aggregated_translator_correctly_deals_with_group_channels ( ) {
318+ start_tracing ( ) ;
319+ let ( _tp, tp_addr) = start_template_provider ( None , DifficultyLevel :: Low ) ;
320+ let ( _pool, pool_addr) = start_pool ( sv2_tp_config ( tp_addr) , vec ! [ ] , vec ! [ ] ) . await ;
321+ let ( sniffer, sniffer_addr) = start_sniffer ( "0" , pool_addr, false , vec ! [ ] , None ) ;
322+
323+ // non-aggregated tProxy
324+ let ( _, tproxy_addr) = start_sv2_translator ( & [ sniffer_addr] , false , vec ! [ ] , vec ! [ ] ) . await ;
325+
326+ sniffer
327+ . wait_for_message_type_and_clean_queue (
328+ MessageDirection :: ToDownstream ,
329+ MESSAGE_TYPE_SETUP_CONNECTION_SUCCESS ,
330+ )
331+ . await ;
332+
333+ // connect first minerd process
334+ let ( _minerd_process_1, _minerd_addr_1) = start_minerd ( tproxy_addr, None , None , false ) . await ;
335+
336+ sniffer
337+ . wait_for_message_type_and_clean_queue (
338+ MessageDirection :: ToUpstream ,
339+ MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL ,
340+ )
341+ . await ;
342+
343+ sniffer
344+ . wait_for_message_type (
345+ MessageDirection :: ToDownstream ,
346+ MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL_SUCCESS ,
347+ )
348+ . await ;
349+
350+ let ( channel_id_a, group_channel_id) = match sniffer. next_message_from_upstream ( ) {
351+ Some ( (
352+ _,
353+ AnyMessage :: Mining ( parsers_sv2:: Mining :: OpenExtendedMiningChannelSuccess ( msg) ) ,
354+ ) ) => ( msg. channel_id , msg. group_channel_id ) ,
355+ msg => panic ! (
356+ "Expected OpenExtendedMiningChannelSuccess message, found: {:?}" ,
357+ msg
358+ ) ,
359+ } ;
360+
361+ sniffer
362+ . wait_for_message_type_and_clean_queue (
363+ MessageDirection :: ToDownstream ,
364+ MESSAGE_TYPE_NEW_EXTENDED_MINING_JOB ,
365+ )
366+ . await ;
367+ sniffer
368+ . wait_for_message_type_and_clean_queue (
369+ MessageDirection :: ToDownstream ,
370+ MESSAGE_TYPE_MINING_SET_NEW_PREV_HASH ,
371+ )
372+ . await ;
373+
374+ assert_ne ! (
375+ channel_id_a, group_channel_id,
376+ "Channel ID must be different from the group channel ID"
377+ ) ;
378+
379+ // connect second minerd process
380+ let ( _minerd_process_2, _minerd_addr_2) = start_minerd ( tproxy_addr, None , None , false ) . await ;
381+
382+ sniffer
383+ . wait_for_message_type_and_clean_queue (
384+ MessageDirection :: ToUpstream ,
385+ MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL ,
386+ )
387+ . await ;
388+
389+ sniffer
390+ . wait_for_message_type (
391+ MessageDirection :: ToDownstream ,
392+ MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL_SUCCESS ,
393+ )
394+ . await ;
395+
396+ let ( channel_id_b, group_channel_id) = match sniffer. next_message_from_upstream ( ) {
397+ Some ( (
398+ _,
399+ AnyMessage :: Mining ( parsers_sv2:: Mining :: OpenExtendedMiningChannelSuccess ( msg) ) ,
400+ ) ) => ( msg. channel_id , msg. group_channel_id ) ,
401+ msg => panic ! (
402+ "Expected OpenExtendedMiningChannelSuccess message, found: {:?}" ,
403+ msg
404+ ) ,
405+ } ;
406+
407+ assert_ne ! (
408+ channel_id_b, group_channel_id,
409+ "Channel ID must be different from the group channel ID"
410+ ) ;
411+
412+ sniffer
413+ . wait_for_message_type_and_clean_queue (
414+ MessageDirection :: ToDownstream ,
415+ MESSAGE_TYPE_NEW_EXTENDED_MINING_JOB ,
416+ )
417+ . await ;
418+ sniffer
419+ . wait_for_message_type_and_clean_queue (
420+ MessageDirection :: ToDownstream ,
421+ MESSAGE_TYPE_MINING_SET_NEW_PREV_HASH ,
422+ )
423+ . await ;
424+
425+ // NewExtendedMiningJob and SetNewPrevHash messages arrived to tProxy
426+ // eventually a share will be submitted
427+
428+ sniffer
429+ . wait_for_message_type (
430+ MessageDirection :: ToUpstream ,
431+ MESSAGE_TYPE_SUBMIT_SHARES_EXTENDED ,
432+ )
433+ . await ;
434+ let share_channel_id = match sniffer. next_message_from_downstream ( ) {
435+ Some ( ( _, AnyMessage :: Mining ( parsers_sv2:: Mining :: SubmitSharesExtended ( msg) ) ) ) => {
436+ msg. channel_id
437+ }
438+ msg => panic ! ( "Expected SubmitSharesExtended message, found: {:?}" , msg) ,
439+ } ;
440+
441+ assert ! (
442+ share_channel_id == channel_id_a || share_channel_id == channel_id_b,
443+ "Share submitted to the correct channel ID"
444+ ) ;
445+
446+ assert_ne ! (
447+ share_channel_id, group_channel_id,
448+ "Share NOT submitted to the group channel ID"
449+ ) ;
450+ }
0 commit comments