@@ -561,36 +561,16 @@ type sendTxResult struct {
561
561
ResultCode SendTxReturnCode
562
562
}
563
563
564
- // broadcastTxAsync - creates a goroutine that sends transaction to the node. Returns false, if MultiNode is Stopped
565
564
func (c * multiNode [CHAIN_ID , SEQ , ADDR , BLOCK_HASH , TX , TX_HASH , EVENT , EVENT_OPS , TX_RECEIPT , FEE , HEAD , RPC_CLIENT ]) broadcastTxAsync (ctx context.Context ,
566
- n SendOnlyNode [CHAIN_ID , RPC_CLIENT ], tx TX , txResults chan sendTxResult , wg * sync.WaitGroup ) {
567
- defer wg .Done ()
568
-
565
+ n SendOnlyNode [CHAIN_ID , RPC_CLIENT ], tx TX ) sendTxResult {
569
566
txErr := n .RPC ().SendTransaction (ctx , tx )
570
567
c .lggr .Debugw ("Node sent transaction" , "name" , n .String (), "tx" , tx , "err" , txErr )
571
568
resultCode := c .classifySendTxError (tx , txErr )
572
569
if resultCode != Successful && resultCode != TransactionAlreadyKnown {
573
570
c .lggr .Warnw ("RPC returned error" , "name" , n .String (), "tx" , tx , "err" , txErr )
574
571
}
575
572
576
- // we expected txResults to have sufficient buffer, otherwise we are not interested in the response
577
- // and can drop it
578
- select {
579
- case txResults <- sendTxResult {Err : txErr , ResultCode : resultCode }:
580
- default :
581
- }
582
- }
583
-
584
- func fanOut [T any ](source chan T , destinations ... chan T ) {
585
- for t := range source {
586
- for _ , dest := range destinations {
587
- dest <- t
588
- }
589
- }
590
-
591
- for _ , dest := range destinations {
592
- close (dest )
593
- }
573
+ return sendTxResult {Err : txErr , ResultCode : resultCode }
594
574
}
595
575
596
576
// collectTxResults - refer to SendTransaction comment for implementation details,
@@ -710,29 +690,31 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP
710
690
c .wg .Add (len (c .sendonlys ))
711
691
// fire-n-forget, as sendOnlyNodes can not be trusted with result reporting
712
692
for _ , n := range c .sendonlys {
713
- go c .broadcastTxAsync (ctx , n , tx , nil , & c .wg )
693
+ go func (n SendOnlyNode [CHAIN_ID , RPC_CLIENT ]) {
694
+ defer c .wg .Done ()
695
+ c .broadcastTxAsync (ctx , n , tx )
696
+ }(n )
714
697
}
715
698
716
- // signal when all the primary nodes done broadcasting tx
717
- inTxResults := make (chan sendTxResult , len (c .nodes ))
718
699
var primaryBroadcastWg sync.WaitGroup
719
700
primaryBroadcastWg .Add (len (c .nodes ))
720
- c .wg .Add (1 )
721
- go func () {
722
- // wait for primary nodes to finish the broadcast before closing the channel
723
- primaryBroadcastWg .Wait ()
724
- close (inTxResults )
725
- c .wg .Done ()
726
- }()
727
-
701
+ txResultsToReport := make (chan sendTxResult , len (c .nodes ))
728
702
for _ , n := range c .nodes {
729
- go c .broadcastTxAsync (ctx , n , tx , inTxResults , & primaryBroadcastWg )
703
+ go func (n SendOnlyNode [CHAIN_ID , RPC_CLIENT ]) {
704
+ defer primaryBroadcastWg .Done ()
705
+ result := c .broadcastTxAsync (ctx , n , tx )
706
+ // both channels are sufficiently buffered, so we won't be locked
707
+ txResultsToReport <- result
708
+ txResults <- result
709
+ }(n )
730
710
}
731
711
732
- txResultsToReport := make (chan sendTxResult , len (c .nodes ))
733
712
c .wg .Add (1 )
734
713
go func () {
735
- fanOut (inTxResults , txResultsToReport , txResults )
714
+ // wait for primary nodes to finish the broadcast before closing the channel
715
+ primaryBroadcastWg .Wait ()
716
+ close (txResultsToReport )
717
+ close (txResults )
736
718
c .wg .Done ()
737
719
}()
738
720
0 commit comments