77 "fmt"
88 "runtime"
99 "sync"
10+ "sync/atomic"
1011 "time"
1112
1213 lru "github.com/hashicorp/golang-lru/v2"
@@ -118,6 +119,10 @@ type DASubmitter struct {
118119 envelopeCache * lru.Cache [uint64 , []byte ]
119120 envelopeCacheMu sync.RWMutex
120121
122+ // lastSubmittedHeight tracks the last successfully submitted height for lazy cache invalidation.
123+ // This avoids O(N) iteration over the cache on every submission.
124+ lastSubmittedHeight atomic.Uint64
125+
121126 // signingWorkers is the number of parallel workers for signing
122127 signingWorkers int
123128}
@@ -223,8 +228,8 @@ func (s *DASubmitter) SubmitHeaders(ctx context.Context, headers []*types.Signed
223228 if l := len (submitted ); l > 0 {
224229 lastHeight := submitted [l - 1 ].Height ()
225230 cache .SetLastSubmittedHeaderHeight (ctx , lastHeight )
226- // Clear envelope cache for successfully submitted heights
227- s .clearEnvelopeCacheUpTo (lastHeight )
231+ // Update last submitted height for lazy cache invalidation (O(1) instead of O(N))
232+ s .lastSubmittedHeight . Store (lastHeight )
228233 }
229234 },
230235 "header" ,
@@ -361,10 +366,15 @@ func (s *DASubmitter) signAndCacheEnvelope(header *types.SignedHeader, marshalle
361366}
362367
363368// getCachedEnvelope retrieves a cached envelope for the given height.
369+ // Uses lazy invalidation: entries at or below lastSubmittedHeight are considered invalid.
364370func (s * DASubmitter ) getCachedEnvelope (height uint64 ) []byte {
365371 if s .envelopeCache == nil {
366372 return nil
367373 }
374+ // Lazy invalidation: don't return cached data for already-submitted heights
375+ if height <= s .lastSubmittedHeight .Load () {
376+ return nil
377+ }
368378 s .envelopeCacheMu .RLock ()
369379 defer s .envelopeCacheMu .RUnlock ()
370380
@@ -375,30 +385,19 @@ func (s *DASubmitter) getCachedEnvelope(height uint64) []byte {
375385}
376386
377387// setCachedEnvelope stores an envelope in the cache.
388+ // Does not cache heights that have already been submitted.
378389func (s * DASubmitter ) setCachedEnvelope (height uint64 , envelope []byte ) {
379390 if s .envelopeCache == nil {
380391 return
381392 }
382- s .envelopeCacheMu .Lock ()
383- defer s .envelopeCacheMu .Unlock ()
384-
385- s .envelopeCache .Add (height , envelope )
386- }
387-
388- // clearEnvelopeCacheUpTo removes cached envelopes up to and including the given height.
389- func (s * DASubmitter ) clearEnvelopeCacheUpTo (height uint64 ) {
390- if s .envelopeCache == nil {
393+ // Don't cache already-submitted heights
394+ if height <= s .lastSubmittedHeight .Load () {
391395 return
392396 }
393397 s .envelopeCacheMu .Lock ()
394398 defer s .envelopeCacheMu .Unlock ()
395399
396- keys := s .envelopeCache .Keys ()
397- for _ , h := range keys {
398- if h <= height {
399- s .envelopeCache .Remove (h )
400- }
401- }
400+ s .envelopeCache .Add (height , envelope )
402401}
403402
404403// SubmitData submits pending data to DA layer
0 commit comments