Skip to content

Commit

Permalink
opt(op-node): refactor sequencer step schedule (ethereum-optimism#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
bnoieh authored Jan 2, 2024
1 parent 7947c25 commit 5f592b5
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
11 changes: 11 additions & 0 deletions op-node/rollup/driver/sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ type Sequencer struct {
timeNow func() time.Time

nextAction time.Time

// if accEmptyBlocks>10, will delay nextAction 600ms for full block building
accEmptyBlocks int
}

func NewSequencer(log log.Logger, cfg *rollup.Config, engine derive.ResettableEngineControl, attributesBuilder derive.AttributesBuilder, l1OriginSelector L1OriginSelectorIface, metrics SequencerMetrics) *Sequencer {
Expand Down Expand Up @@ -227,6 +230,9 @@ func (d *Sequencer) RunNextSequencerAction(ctx context.Context) (*eth.ExecutionP
return nil, nil
} else {
d.attrBuilder.CachePayloadByHash(payload)
if len(payload.Transactions) == 1 {
d.accEmptyBlocks += 1
}
d.log.Info("sequencer successfully built a new block", "block", payload.ID(), "time", uint64(payload.Timestamp), "txs", len(payload.Transactions))
return payload, nil
}
Expand All @@ -249,6 +255,11 @@ func (d *Sequencer) RunNextSequencerAction(ctx context.Context) (*eth.ExecutionP
}
} else {
parent, buildingID, _ := d.engine.BuildingPayload() // we should have a new payload ID now that we're building a block
if d.accEmptyBlocks > 10 {
d.nextAction = d.timeNow().Add(600 * time.Millisecond)
d.accEmptyBlocks = 0
d.log.Info("sequencer delay next action 600ms and reset accEmptyBlocks")
}
d.log.Info("sequencer started building new block", "payload_id", buildingID, "l2_parent_block", parent, "l2_parent_block_time", parent.Time)
}
return nil, nil
Expand Down
42 changes: 39 additions & 3 deletions op-node/rollup/driver/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,24 @@ func (s *Driver) eventLoop() {
// This may adjust at any time based on fork-choice changes or previous errors.
//
// update sequencer time if the head changed
planSequencerAction()
delay := s.sequencer.PlanNextSequencerAction()
if delay == 0 {
select {
case newL1Head := <-s.l1HeadSig: // sequencerStep may depend on this when FindL1Origin
s.l1State.HandleNewL1HeadBlock(newL1Head)
reqStep() // a new L1 head may mean we have the data to not get an EOF again.
continue
default:
// immediately do sequencerStep if time is ready
if err := sequencerStep(); err != nil {
return
}
// sequencerStep was already done, so we continue to next round
continue
}
} else {
planSequencerAction()
}
}
} else {
sequencerCh = nil
Expand All @@ -282,8 +299,8 @@ func (s *Driver) eventLoop() {
altSyncTicker.Reset(syncCheckInterval)
}

// Following cases are high priority
if s.driverConfig.SequencerPriority {
// help sequencerStep not interrupt by other steps
select {
case <-sequencerCh:
if err := sequencerStep(); err != nil {
Expand All @@ -294,6 +311,25 @@ func (s *Driver) eventLoop() {
s.l1State.HandleNewL1HeadBlock(newL1Head)
reqStep() // a new L1 head may mean we have the data to not get an EOF again.
continue
case respCh := <-s.stopSequencer:
if s.driverConfig.SequencerStopped {
respCh <- hashAndError{err: errors.New("sequencer not running")}
} else {
if err := s.sequencerNotifs.SequencerStopped(); err != nil {
respCh <- hashAndError{err: fmt.Errorf("sequencer start notification: %w", err)}
continue
}
s.log.Warn("Sequencer has been stopped")
s.driverConfig.SequencerStopped = true
respCh <- hashAndError{hash: s.derivation.UnsafeL2Head().Hash}
}
continue
case respCh := <-s.sequencerActive:
respCh <- !s.driverConfig.SequencerStopped
continue
case respCh := <-s.stateReq:
respCh <- struct{}{}
continue
default:
}
}
Expand Down Expand Up @@ -334,7 +370,7 @@ func (s *Driver) eventLoop() {
s.metrics.SetDerivationIdle(false)
s.log.Debug("Derivation process step", "onto_origin", s.derivation.Origin(), "attempts", stepAttempts)
stepCtx := context.Background()
if s.driverConfig.SequencerEnabled && !s.driverConfig.SequencerStopped {
if s.driverConfig.SequencerEnabled && !s.driverConfig.SequencerStopped && s.driverConfig.SequencerPriority {
var cancelStep context.CancelFunc
stepCtx, cancelStep = context.WithTimeout(ctx, 3*time.Second)
defer cancelStep()
Expand Down

0 comments on commit 5f592b5

Please sign in to comment.