@@ -35,6 +35,10 @@ import (
3535 "github.com/rollkit/rollkit/types"
3636)
3737
38+ // defaultLazyBufferTime is the additional time to wait to accumulate transactions
39+ // in lazy mode
40+ const defaultLazyBufferTime = 1 * time .Second
41+
3842// defaultDABlockTime is used only if DABlockTime is not configured for manager
3943const defaultDABlockTime = 15 * time .Second
4044
@@ -347,6 +351,34 @@ func (m *Manager) IsDAIncluded(hash types.Hash) bool {
347351 return m .blockCache .isDAIncluded (hash .String ())
348352}
349353
354+ // getRemainingSleep calculates the remaining sleep time based on config and a start time.
355+ func (m * Manager ) getRemainingSleep (start time.Time ) time.Duration {
356+ elapsed := time .Since (start )
357+ interval := m .conf .BlockTime
358+
359+ if m .conf .LazyAggregator {
360+ if m .buildingBlock {
361+ interval = m .conf .BlockTime
362+ // defaultLazyBufferTime is used to give time for transactions to
363+ // accumulate if we are coming out of a period of inactivity. If we
364+ // had recently produced a block (i.e. within the block time) then
365+ // we will sleep for the remaining time within the block time
366+ // interval.
367+ if elapsed >= interval {
368+ return defaultLazyBufferTime
369+ }
370+ } else {
371+ interval = m .conf .LazyBlockTime
372+ }
373+ }
374+
375+ if elapsed < interval {
376+ return interval - elapsed
377+ }
378+
379+ return 0
380+ }
381+
350382// AggregationLoop is responsible for aggregating transactions into rollup-blocks.
351383func (m * Manager ) AggregationLoop (ctx context.Context ) {
352384 initialHeight := uint64 (m .genesis .InitialHeight )
@@ -376,71 +408,69 @@ func (m *Manager) AggregationLoop(ctx context.Context) {
376408 // In Lazy Aggregator mode, blocks are built only when there are
377409 // transactions or every LazyBlockTime.
378410 if m .conf .LazyAggregator {
379- // start is used to track the start time of the block production period
380- var start time.Time
381-
382- // lazyTimer is used to signal when a block should be built in
383- // lazy mode to signal that the chain is still live during long
384- // periods of inactivity.
385- lazyTimer := time .NewTimer (0 )
386- defer lazyTimer .Stop ()
387- for {
388- select {
389- case <- ctx .Done ():
390- return
391- // the txsAvailable channel is signalled when Txns become available
392- // in the mempool, or after transactions remain in the mempool after
393- // building a block.
394- case _ , ok := <- m .txsAvailable :
395- if ok && ! m .buildingBlock {
396- // set the buildingBlock flag to prevent multiple calls to reset the timer
397- m .buildingBlock = true
398- // Reset the block timer based on the block time and the default sleep.
399- // The default sleep is used to give time for transactions to accumulate
400- // if we are coming out of a period of inactivity. If we had recently
401- // produced a block (i.e. within the block time) then we will sleep for
402- // the remaining time within the block time interval.
403- blockTimer .Reset (m .getRemainingSleep (start ))
411+ m .lazyAggregationLoop (ctx , blockTimer )
412+ return
413+ }
404414
405- }
406- continue
407- case <- lazyTimer .C :
408- case <- blockTimer .C :
409- }
410- // Define the start time for the block production period
411- start = time .Now ()
412- err := m .publishBlock (ctx )
413- if err != nil && ctx .Err () == nil {
414- m .logger .Error ("error while publishing block" , "error" , err )
415+ m .normalAggregationLoop (ctx , blockTimer )
416+ }
417+
418+ func (m * Manager ) lazyAggregationLoop (ctx context.Context , blockTimer * time.Timer ) {
419+ // start is used to track the start time of the block production period
420+ start := time .Now ()
421+ // lazyTimer is used to signal when a block should be built in
422+ // lazy mode to signal that the chain is still live during long
423+ // periods of inactivity.
424+ lazyTimer := time .NewTimer (0 )
425+ defer lazyTimer .Stop ()
426+
427+ for {
428+ select {
429+ case <- ctx .Done ():
430+ return
431+ // the txsAvailable channel is signalled when Txns become available
432+ // in the mempool, or after transactions remain in the mempool after
433+ // building a block.
434+ case _ , ok := <- m .txsAvailable :
435+ if ok && ! m .buildingBlock {
436+ // set the buildingBlock flag to prevent multiple calls to reset the time
437+ m .buildingBlock = true
438+ // Reset the block timer based on the block time.
439+ blockTimer .Reset (m .getRemainingSleep (start ))
415440 }
416- // unset the buildingBlocks flag
417- m .buildingBlock = false
418- // Reset the lazyTimer to produce a block even if there
419- // are no transactions as a way to signal that the chain
420- // is still live. Default sleep is set to 0 because care
421- // about producing blocks on time vs giving time for
422- // transactions to accumulate.
423- lazyTimer .Reset (m .getRemainingSleep (start ))
441+ continue
442+ case <- lazyTimer .C :
443+ case <- blockTimer .C :
424444 }
445+ // Define the start time for the block production period
446+ start = time .Now ()
447+ if err := m .publishBlock (ctx ); err != nil && ctx .Err () == nil {
448+ m .logger .Error ("error while publishing block" , "error" , err )
449+ }
450+ // unset the buildingBlocks flag
451+ m .buildingBlock = false
452+ // Reset the lazyTimer to produce a block even if there
453+ // are no transactions as a way to signal that the chain
454+ // is still live.
455+ lazyTimer .Reset (m .getRemainingSleep (start ))
425456 }
457+ }
426458
427- // Normal Aggregator mode
459+ func ( m * Manager ) normalAggregationLoop ( ctx context. Context , blockTimer * time. Timer ) {
428460 for {
429461 select {
430462 case <- ctx .Done ():
431463 return
432464 case <- blockTimer .C :
465+ // Define the start time for the block production period
466+ start := time .Now ()
467+ if err := m .publishBlock (ctx ); err != nil && ctx .Err () == nil {
468+ m .logger .Error ("error while publishing block" , "error" , err )
469+ }
470+ // Reset the blockTimer to signal the next block production
471+ // period based on the block time.
472+ blockTimer .Reset (m .getRemainingSleep (start ))
433473 }
434- start := time .Now ()
435- err := m .publishBlock (ctx )
436- if err != nil && ctx .Err () == nil {
437- m .logger .Error ("error while publishing block" , "error" , err )
438- }
439- // Reset the blockTimer to signal the next block production
440- // period based on the block time. Default sleep is set to 0
441- // because care about producing blocks on time vs giving time
442- // for transactions to accumulate.
443- blockTimer .Reset (m .getRemainingSleep (start ))
444474 }
445475}
446476
@@ -759,34 +789,6 @@ func (m *Manager) fetchBlock(ctx context.Context, daHeight uint64) (da.ResultRet
759789 return blockRes , err
760790}
761791
762- // getRemainingSleep calculates the remaining sleep time based on config and a start time.
763- func (m * Manager ) getRemainingSleep (start time.Time ) time.Duration {
764- // Initialize the sleep duration to the default sleep duration to cover
765- // the case where more time has past than the interval duration.
766- sleepDuration := time .Duration (0 )
767- // Calculate the time elapsed since the start time.
768- elapse := time .Since (start )
769-
770- interval := m .conf .BlockTime
771- if m .conf .LazyAggregator {
772- // If it's in lazy aggregator mode and is buildingBlock, reset sleepDuration for
773- // blockTimer, else reset interval for lazyTimer
774- if m .buildingBlock {
775- sleepDuration = m .conf .BlockTime
776- } else {
777- interval = m .conf .LazyBlockTime
778- }
779- }
780-
781- // If less time has elapsed than the interval duration, calculate the
782- // remaining time to sleep.
783- if elapse < interval {
784- sleepDuration = interval - elapse
785- }
786-
787- return sleepDuration
788- }
789-
790792func (m * Manager ) getSignature (header types.Header ) (* types.Signature , error ) {
791793 // note: for compatibility with tendermint light client
792794 consensusVote := header .MakeCometBFTVote ()
0 commit comments