@@ -199,6 +199,7 @@ func (s *DASubmitter) Close() {
199199 s .wg .Wait ()
200200}
201201
202+ // SubmitHeaders submits pending headers to DA layer
202203func (s * DASubmitter ) SubmitHeaders (ctx context.Context , headers []* types.SignedHeader , marshalledHeaders [][]byte , cache cache.Manager , signer signer.Signer , onSubmitSuccess func (), onSubmitError func (error )) error {
203204 if len (headers ) == 0 {
204205 return nil
@@ -257,6 +258,7 @@ func (s *DASubmitter) makeHeaderPostSubmit(ctx context.Context, cache cache.Mana
257258 }
258259}
259260
261+ // SubmitData submits pending data to DA layer
260262func (s * DASubmitter ) SubmitData (ctx context.Context , unsignedDataList []* types.SignedData , marshalledData [][]byte , cache cache.Manager , signer signer.Signer , genesis genesis.Genesis , onSubmitSuccess func (), onSubmitError func (error )) error {
261263 if len (unsignedDataList ) == 0 {
262264 return nil
@@ -459,6 +461,7 @@ func limitBatchBySizeBytes(marshaled [][]byte, maxBytes uint64) ([][]byte, bool)
459461 return marshaled [:count ], false
460462}
461463
464+ // recordFailure records a DA submission failure in metrics
462465func (s * DASubmitter ) recordFailure (reason common.DASubmitterFailureReason ) {
463466 counter , ok := s .metrics .DASubmitterFailures [reason ]
464467 if ! ok {
@@ -472,10 +475,13 @@ func (s *DASubmitter) recordFailure(reason common.DASubmitterFailureReason) {
472475 }
473476}
474477
478+ // createDAEnvelopes creates signed DA envelopes for the given headers.
479+ // It uses caching to avoid re-signing on retries and parallel signing for new envelopes.
475480func (s * DASubmitter ) createDAEnvelopes (ctx context.Context , headers []* types.SignedHeader , marshalledHeaders [][]byte , signer signer.Signer ) ([][]byte , error ) {
476481 envelopes := make ([][]byte , len (headers ))
477482
478- var needSigning []int
483+ // First pass: check cache for already-signed envelopes
484+ var needSigning []int // indices that need signing
479485 for i , header := range headers {
480486 height := header .Height ()
481487 if cached := s .getCachedEnvelope (height ); cached != nil {
@@ -485,6 +491,7 @@ func (s *DASubmitter) createDAEnvelopes(ctx context.Context, headers []*types.Si
485491 }
486492 }
487493
494+ // If all envelopes were cached, we're done
488495 if len (needSigning ) == 0 {
489496 s .logger .Debug ().Int ("cached" , len (headers )).Msg ("all envelopes retrieved from cache" )
490497 return envelopes , nil
@@ -495,7 +502,9 @@ func (s *DASubmitter) createDAEnvelopes(ctx context.Context, headers []*types.Si
495502 Int ("to_sign" , len (needSigning )).
496503 Msg ("signing DA envelopes" )
497504
505+ // For small batches, sign sequentially to avoid goroutine overhead
498506 if len (needSigning ) <= 2 || s .signingWorkers <= 1 {
507+ // Send jobs
499508 for _ , i := range needSigning {
500509 envelope , err := s .signAndCacheEnvelope (ctx , headers [i ], marshalledHeaders [i ], signer )
501510 if err != nil {
@@ -506,9 +515,11 @@ func (s *DASubmitter) createDAEnvelopes(ctx context.Context, headers []*types.Si
506515 return envelopes , nil
507516 }
508517
518+ // Parallel signing for larger batches
509519 return s .signEnvelopesParallel (ctx , headers , marshalledHeaders , envelopes , needSigning , signer )
510520}
511521
522+ // signEnvelopesParallel signs envelopes in parallel using a worker pool.
512523func (s * DASubmitter ) signEnvelopesParallel (
513524 ctx context.Context ,
514525 headers []* types.SignedHeader ,
@@ -529,6 +540,7 @@ func (s *DASubmitter) signEnvelopesParallel(
529540 jobs := make (chan signJob , len (needSigning ))
530541 results := make (chan signResult , len (needSigning ))
531542
543+ // Start workers
532544 numWorkers := min (s .signingWorkers , len (needSigning ))
533545 var wg sync.WaitGroup
534546 for range numWorkers {
@@ -545,11 +557,13 @@ func (s *DASubmitter) signEnvelopesParallel(
545557 }
546558 close (jobs )
547559
560+ // Wait for workers to finish and close results
548561 go func () {
549562 wg .Wait ()
550563 close (results )
551564 }()
552565
566+ // Collect results
553567 var firstErr error
554568 for result := range results {
555569 if result .err != nil && firstErr == nil {
@@ -568,26 +582,33 @@ func (s *DASubmitter) signEnvelopesParallel(
568582 return envelopes , nil
569583}
570584
585+ // signAndCacheEnvelope signs a single header and caches the result.
571586func (s * DASubmitter ) signAndCacheEnvelope (ctx context.Context , header * types.SignedHeader , marshalledHeader []byte , signer signer.Signer ) ([]byte , error ) {
587+ // Sign the pre-marshalled header content
572588 envelopeSignature , err := signer .Sign (ctx , marshalledHeader )
573589 if err != nil {
574590 return nil , fmt .Errorf ("failed to sign envelope: %w" , err )
575591 }
576592
593+ // Create the envelope and marshal it
577594 envelope , err := header .MarshalDAEnvelope (envelopeSignature )
578595 if err != nil {
579596 return nil , fmt .Errorf ("failed to marshal DA envelope: %w" , err )
580597 }
581598
599+ // Cache for potential retries
582600 s .setCachedEnvelope (header .Height (), envelope )
583601
584602 return envelope , nil
585603}
586604
605+ // getCachedEnvelope retrieves a cached envelope for the given height.
606+ // Uses lazy invalidation: entries at or below lastSubmittedHeight are considered invalid.
587607func (s * DASubmitter ) getCachedEnvelope (height uint64 ) []byte {
588608 if s .envelopeCache == nil {
589609 return nil
590610 }
611+ // Lazy invalidation: don't return cached data for already-submitted heights
591612 if height <= s .lastSubmittedHeight .Load () {
592613 return nil
593614 }
@@ -597,16 +618,20 @@ func (s *DASubmitter) getCachedEnvelope(height uint64) []byte {
597618 return nil
598619}
599620
621+ // setCachedEnvelope stores an envelope in the cache.
622+ // Does not cache heights that have already been submitted.
600623func (s * DASubmitter ) setCachedEnvelope (height uint64 , envelope []byte ) {
601624 if s .envelopeCache == nil {
602625 return
603626 }
627+ // Don't cache already-submitted heights
604628 if height <= s .lastSubmittedHeight .Load () {
605629 return
606630 }
607631 s .envelopeCache .Add (height , envelope )
608632}
609633
634+ // signData signs unsigned SignedData structs returned from cache
610635func (s * DASubmitter ) signData (ctx context.Context , unsignedDataList []* types.SignedData , unsignedDataListBz [][]byte , signer signer.Signer , genesis genesis.Genesis ) ([]* types.SignedData , [][]byte , error ) {
611636 if signer == nil {
612637 return nil , nil , fmt .Errorf ("signer is nil" )
@@ -635,6 +660,7 @@ func (s *DASubmitter) signData(ctx context.Context, unsignedDataList []*types.Si
635660 signedDataListBz := make ([][]byte , 0 , len (unsignedDataListBz ))
636661
637662 for i , unsignedData := range unsignedDataList {
663+ // Skip empty data
638664 if len (unsignedData .Txs ) == 0 {
639665 continue
640666 }
@@ -663,6 +689,10 @@ func (s *DASubmitter) signData(ctx context.Context, unsignedDataList []*types.Si
663689 return signedDataList , signedDataListBz , nil
664690}
665691
692+ // mergeSubmitOptions merges the base submit options with a signing address.
693+ // If the base options are valid JSON, the signing address is added to the JSON object.
694+ // Otherwise, a new JSON object is created with just the signing address.
695+ // Returns the base options unchanged if no signing address is provided.
666696func mergeSubmitOptions (baseOptions []byte , signingAddress string ) ([]byte , error ) {
667697 if signingAddress == "" {
668698 return baseOptions , nil
0 commit comments