@@ -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
@@ -198,6 +202,11 @@ func NewManager(
198202 conf .LazyBlockTime = defaultLazyBlockTime
199203 }
200204
205+ if conf .LazyBufferTime == 0 {
206+ logger .Info ("Using default lazy buffer time" , "LazyBufferTime" , defaultLazyBufferTime )
207+ conf .LazyBufferTime = defaultLazyBufferTime
208+ }
209+
201210 if conf .DAMempoolTTL == 0 {
202211 logger .Info ("Using default mempool ttl" , "MempoolTTL" , defaultMempoolTTL )
203212 conf .DAMempoolTTL = defaultMempoolTTL
@@ -347,8 +356,33 @@ func (m *Manager) IsDAIncluded(hash types.Hash) bool {
347356 return m .blockCache .isDAIncluded (hash .String ())
348357}
349358
359+ // getRemainingSleep calculates the remaining sleep time based on config and a start time.
360+ func (m * Manager ) getRemainingSleep (start time.Time ) time.Duration {
361+ elapsed := time .Since (start )
362+ interval := m .conf .BlockTime
363+
364+ if m .conf .LazyAggregator {
365+ if m .buildingBlock && elapsed >= interval {
366+ // LazyBufferTime is used to give time for transactions to
367+ // accumulate if we are coming out of a period of inactivity. If we
368+ // had recently produced a block (i.e. within the block time) then
369+ // we will sleep for the remaining time within the block time
370+ // interval.
371+ return m .conf .LazyBufferTime
372+ } else if ! m .buildingBlock {
373+ interval = m .conf .LazyBlockTime
374+ }
375+ }
376+
377+ if elapsed < interval {
378+ return interval - elapsed
379+ }
380+
381+ return 0
382+ }
383+
350384// AggregationLoop is responsible for aggregating transactions into rollup-blocks.
351- func (m * Manager ) AggregationLoop (ctx context.Context , lazy bool ) {
385+ func (m * Manager ) AggregationLoop (ctx context.Context ) {
352386 initialHeight := uint64 (m .genesis .InitialHeight )
353387 height := m .store .Height ()
354388 var delay time.Duration
@@ -375,76 +409,70 @@ func (m *Manager) AggregationLoop(ctx context.Context, lazy bool) {
375409 // Lazy Aggregator mode.
376410 // In Lazy Aggregator mode, blocks are built only when there are
377411 // transactions or every LazyBlockTime.
378- if lazy {
379- // start is used to track the start time of the block production period
380- var start time.Time
381-
382- // defaultSleep is used when coming out of a period of inactivity,
383- // to try and pull in more transactions in the first block
384- defaultSleep := time .Second
385-
386- // lazyTimer is used to signal when a block should be built in
387- // lazy mode to signal that the chain is still live during long
388- // periods of inactivity.
389- lazyTimer := time .NewTimer (0 )
390- defer lazyTimer .Stop ()
391- for {
392- select {
393- case <- ctx .Done ():
394- return
395- // the txsAvailable channel is signalled when Txns become available
396- // in the mempool, or after transactions remain in the mempool after
397- // building a block.
398- case _ , ok := <- m .txsAvailable :
399- if ok && ! m .buildingBlock {
400- // set the buildingBlock flag to prevent multiple calls to reset the timer
401- m .buildingBlock = true
402- // Reset the block timer based on the block time and the default sleep.
403- // The default sleep is used to give time for transactions to accumulate
404- // if we are coming out of a period of inactivity. If we had recently
405- // produced a block (i.e. within the block time) then we will sleep for
406- // the remaining time within the block time interval.
407- blockTimer .Reset (getRemainingSleep (start , m .conf .BlockTime , defaultSleep ))
412+ if m .conf .LazyAggregator {
413+ m .lazyAggregationLoop (ctx , blockTimer )
414+ return
415+ }
408416
409- }
410- continue
411- case <- lazyTimer .C :
412- case <- blockTimer .C :
413- }
414- // Define the start time for the block production period
415- start = time .Now ()
416- err := m .publishBlock (ctx )
417- if err != nil && ctx .Err () == nil {
418- m .logger .Error ("error while publishing block" , "error" , err )
417+ m .normalAggregationLoop (ctx , blockTimer )
418+ }
419+
420+ func (m * Manager ) lazyAggregationLoop (ctx context.Context , blockTimer * time.Timer ) {
421+ // start is used to track the start time of the block production period
422+ start := time .Now ()
423+ // lazyTimer is used to signal when a block should be built in
424+ // lazy mode to signal that the chain is still live during long
425+ // periods of inactivity.
426+ lazyTimer := time .NewTimer (0 )
427+ defer lazyTimer .Stop ()
428+
429+ for {
430+ select {
431+ case <- ctx .Done ():
432+ return
433+ // the txsAvailable channel is signalled when Txns become available
434+ // in the mempool, or after transactions remain in the mempool after
435+ // building a block.
436+ case _ , ok := <- m .txsAvailable :
437+ if ok && ! m .buildingBlock {
438+ // set the buildingBlock flag to prevent multiple calls to reset the time
439+ m .buildingBlock = true
440+ // Reset the block timer based on the block time.
441+ blockTimer .Reset (m .getRemainingSleep (start ))
419442 }
420- // unset the buildingBlocks flag
421- m . buildingBlock = false
422- // Reset the lazyTimer to produce a block even if there
423- // are no transactions as a way to signal that the chain
424- // is still live. Default sleep is set to 0 because care
425- // about producing blocks on time vs giving time for
426- // transactions to accumulate.
427- lazyTimer . Reset ( getRemainingSleep ( start , m . conf . LazyBlockTime , 0 ) )
443+ continue
444+ case <- lazyTimer . C :
445+ case <- blockTimer . C :
446+ }
447+ // Define the start time for the block production period
448+ start = time . Now ()
449+ if err := m . publishBlock ( ctx ); err != nil && ctx . Err () == nil {
450+ m . logger . Error ( "error while publishing block" , "error" , err )
428451 }
452+ // unset the buildingBlocks flag
453+ m .buildingBlock = false
454+ // Reset the lazyTimer to produce a block even if there
455+ // are no transactions as a way to signal that the chain
456+ // is still live.
457+ lazyTimer .Reset (m .getRemainingSleep (start ))
429458 }
459+ }
430460
431- // Normal Aggregator mode
461+ func ( m * Manager ) normalAggregationLoop ( ctx context. Context , blockTimer * time. Timer ) {
432462 for {
433463 select {
434464 case <- ctx .Done ():
435465 return
436466 case <- blockTimer .C :
467+ // Define the start time for the block production period
468+ start := time .Now ()
469+ if err := m .publishBlock (ctx ); err != nil && ctx .Err () == nil {
470+ m .logger .Error ("error while publishing block" , "error" , err )
471+ }
472+ // Reset the blockTimer to signal the next block production
473+ // period based on the block time.
474+ blockTimer .Reset (m .getRemainingSleep (start ))
437475 }
438- start := time .Now ()
439- err := m .publishBlock (ctx )
440- if err != nil && ctx .Err () == nil {
441- m .logger .Error ("error while publishing block" , "error" , err )
442- }
443- // Reset the blockTimer to signal the next block production
444- // period based on the block time. Default sleep is set to 0
445- // because care about producing blocks on time vs giving time
446- // for transactions to accumulate.
447- blockTimer .Reset (getRemainingSleep (start , m .conf .BlockTime , 0 ))
448476 }
449477}
450478
@@ -763,22 +791,6 @@ func (m *Manager) fetchBlock(ctx context.Context, daHeight uint64) (da.ResultRet
763791 return blockRes , err
764792}
765793
766- // getRemainingSleep calculates the remaining sleep time based on an interval
767- // and a start time.
768- func getRemainingSleep (start time.Time , interval , defaultSleep time.Duration ) time.Duration {
769- // Initialize the sleep duration to the default sleep duration to cover
770- // the case where more time has past than the interval duration.
771- sleepDuration := defaultSleep
772- // Calculate the time elapsed since the start time.
773- elapse := time .Since (start )
774- // If less time has elapsed than the interval duration, calculate the
775- // remaining time to sleep.
776- if elapse < interval {
777- sleepDuration = interval - elapse
778- }
779- return sleepDuration
780- }
781-
782794func (m * Manager ) getSignature (header types.Header ) (* types.Signature , error ) {
783795 // note: for compatibility with tendermint light client
784796 consensusVote := header .MakeCometBFTVote ()
0 commit comments