Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions op-node/rollup/sequencing/sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,8 @@ func (d *Sequencer) startBuildingBlock() {
// Figure out which L1 origin block we're going to be building on top of.
l1Origin, err := d.l1OriginSelector.FindL1Origin(ctx, l2Head)
if err != nil {
d.nextAction = d.timeNow().Add(time.Second)
d.nextActionOK = d.active.Load()
d.log.Error("Error finding next L1 Origin", "err", err)
d.emitter.Emit(rollup.L1TemporaryErrorEvent{Err: err})
return
Expand Down
54 changes: 54 additions & 0 deletions op-node/rollup/sequencing/sequencer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package sequencing
import (
"context"
"encoding/binary"
"fmt"
"math/rand" // nosemgrep
"testing"
"time"
Expand Down Expand Up @@ -613,6 +614,59 @@ func TestSequencerBuild(t *testing.T) {
require.Equal(t, testClock.Now(), nextTime, "start asap on the next block")
}

func TestSequencerL1TemporaryErrorEvent(t *testing.T) {
logger := testlog.Logger(t, log.LevelError)
seq, deps := createSequencer(logger)
testClock := clock.NewSimpleClock()
seq.timeNow = testClock.Now
testClock.SetTime(30000)
emitter := &testutils.MockEmitter{}
seq.AttachEmitter(emitter)

// Init will request a forkchoice update
emitter.ExpectOnce(engine.ForkchoiceRequestEvent{})
require.NoError(t, seq.Init(context.Background(), true))
emitter.AssertExpectations(t)
require.True(t, seq.Active(), "started in active mode")

// It will request a forkchoice update, it needs the head before being able to build on top of it
emitter.ExpectOnce(engine.ForkchoiceRequestEvent{})
seq.OnEvent(SequencerActionEvent{})
emitter.AssertExpectations(t)

// Now send the forkchoice data, for the sequencer to learn what to build on top of.
head := eth.L2BlockRef{
Hash: common.Hash{0x22},
Number: 100,
L1Origin: eth.BlockID{
Hash: common.Hash{0x11, 0xa},
Number: 1000,
},
Time: uint64(testClock.Now().Unix()),
}
seq.OnEvent(engine.ForkchoiceUpdateEvent{UnsafeL2Head: head})
emitter.AssertExpectations(t)

// force FindL1Origin to return an error
deps.l1OriginSelector.l1OriginFn = func(l2Head eth.L2BlockRef) (eth.L1BlockRef, error) {
return eth.L1BlockRef{}, fmt.Errorf("l1OriginFn error")
}

emitter.ExpectOnceRun(func(ev event.Event) {
_, ok := ev.(rollup.L1TemporaryErrorEvent)
require.True(t, ok)
})

sealTargetTime1, ok1 := seq.NextAction()
seq.OnEvent(SequencerActionEvent{})
emitter.AssertExpectations(t)

// FindL1Origin error will updating d.nextAction
sealTargetTime2, ok2 := seq.NextAction()

require.True(t, ok1 == ok2 && sealTargetTime2.After(sealTargetTime1))
}

type sequencerTestDeps struct {
cfg *rollup.Config
attribBuilder *FakeAttributesBuilder
Expand Down