github.com/ethereum-optimism/optimism@v1.7.2/op-node/rollup/driver/driver.go (about) 1 package driver 2 3 import ( 4 "context" 5 "time" 6 7 "github.com/ethereum/go-ethereum/common" 8 "github.com/ethereum/go-ethereum/log" 9 10 "github.com/ethereum-optimism/optimism/op-node/rollup" 11 "github.com/ethereum-optimism/optimism/op-node/rollup/async" 12 "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" 13 "github.com/ethereum-optimism/optimism/op-node/rollup/derive" 14 "github.com/ethereum-optimism/optimism/op-node/rollup/sync" 15 "github.com/ethereum-optimism/optimism/op-service/eth" 16 ) 17 18 type Metrics interface { 19 RecordPipelineReset() 20 RecordPublishingError() 21 RecordDerivationError() 22 23 RecordReceivedUnsafePayload(payload *eth.ExecutionPayloadEnvelope) 24 25 RecordL1Ref(name string, ref eth.L1BlockRef) 26 RecordL2Ref(name string, ref eth.L2BlockRef) 27 RecordChannelInputBytes(inputCompressedBytes int) 28 RecordHeadChannelOpened() 29 RecordChannelTimedOut() 30 RecordFrame() 31 32 RecordDerivedBatches(batchType string) 33 34 RecordUnsafePayloadsBuffer(length uint64, memSize uint64, next eth.BlockID) 35 36 SetDerivationIdle(idle bool) 37 38 RecordL1ReorgDepth(d uint64) 39 40 EngineMetrics 41 L1FetcherMetrics 42 SequencerMetrics 43 } 44 45 type L1Chain interface { 46 derive.L1Fetcher 47 L1BlockRefByLabel(context.Context, eth.BlockLabel) (eth.L1BlockRef, error) 48 } 49 50 type L2Chain interface { 51 derive.Engine 52 L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L2BlockRef, error) 53 L2BlockRefByHash(ctx context.Context, l2Hash common.Hash) (eth.L2BlockRef, error) 54 L2BlockRefByNumber(ctx context.Context, num uint64) (eth.L2BlockRef, error) 55 } 56 57 type DerivationPipeline interface { 58 Reset() 59 Step(ctx context.Context) error 60 AddUnsafePayload(payload *eth.ExecutionPayloadEnvelope) 61 Finalize(ref eth.L1BlockRef) 62 FinalizedL1() eth.L1BlockRef 63 Origin() eth.L1BlockRef 64 EngineReady() bool 65 LowestQueuedUnsafeBlock() eth.L2BlockRef 66 } 67 68 type L1StateIface interface { 69 HandleNewL1HeadBlock(head eth.L1BlockRef) 70 HandleNewL1SafeBlock(safe eth.L1BlockRef) 71 HandleNewL1FinalizedBlock(finalized eth.L1BlockRef) 72 73 L1Head() eth.L1BlockRef 74 L1Safe() eth.L1BlockRef 75 L1Finalized() eth.L1BlockRef 76 } 77 78 type SequencerIface interface { 79 StartBuildingBlock(ctx context.Context) error 80 CompleteBuildingBlock(ctx context.Context, agossip async.AsyncGossiper, sequencerConductor conductor.SequencerConductor) (*eth.ExecutionPayloadEnvelope, error) 81 PlanNextSequencerAction() time.Duration 82 RunNextSequencerAction(ctx context.Context, agossip async.AsyncGossiper, sequencerConductor conductor.SequencerConductor) (*eth.ExecutionPayloadEnvelope, error) 83 BuildingOnto() eth.L2BlockRef 84 CancelBuildingBlock(ctx context.Context) 85 } 86 87 type Network interface { 88 // PublishL2Payload is called by the driver whenever there is a new payload to publish, synchronously with the driver main loop. 89 PublishL2Payload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error 90 } 91 92 type AltSync interface { 93 // RequestL2Range informs the sync source that the given range of L2 blocks is missing, 94 // and should be retrieved from any available alternative syncing source. 95 // The start and end of the range are exclusive: 96 // the start is the head we already have, the end is the first thing we have queued up. 97 // It's the task of the alt-sync mechanism to use this hint to fetch the right payloads. 98 // Note that the end and start may not be consistent: in this case the sync method should fetch older history 99 // 100 // If the end value is zeroed, then the sync-method may determine the end free of choice, 101 // e.g. sync till the chain head meets the wallclock time. This functionality is optional: 102 // a fixed target to sync towards may be determined by picking up payloads through P2P gossip or other sources. 103 // 104 // The sync results should be returned back to the driver via the OnUnsafeL2Payload(ctx, payload) method. 105 // The latest requested range should always take priority over previous requests. 106 // There may be overlaps in requested ranges. 107 // An error may be returned if the scheduling fails immediately, e.g. a context timeout. 108 RequestL2Range(ctx context.Context, start, end eth.L2BlockRef) error 109 } 110 111 type SequencerStateListener interface { 112 SequencerStarted() error 113 SequencerStopped() error 114 } 115 116 // NewDriver composes an events handler that tracks L1 state, triggers L2 derivation, and optionally sequences new L2 blocks. 117 func NewDriver( 118 driverCfg *Config, 119 cfg *rollup.Config, 120 l2 L2Chain, 121 l1 L1Chain, 122 l1Blobs derive.L1BlobsFetcher, 123 altSync AltSync, 124 network Network, 125 log log.Logger, 126 snapshotLog log.Logger, 127 metrics Metrics, 128 sequencerStateListener SequencerStateListener, 129 safeHeadListener derive.SafeHeadListener, 130 syncCfg *sync.Config, 131 sequencerConductor conductor.SequencerConductor, 132 plasma derive.PlasmaInputFetcher, 133 ) *Driver { 134 l1 = NewMeteredL1Fetcher(l1, metrics) 135 l1State := NewL1State(log, metrics) 136 sequencerConfDepth := NewConfDepth(driverCfg.SequencerConfDepth, l1State.L1Head, l1) 137 findL1Origin := NewL1OriginSelector(log, cfg, sequencerConfDepth) 138 verifConfDepth := NewConfDepth(driverCfg.VerifierConfDepth, l1State.L1Head, l1) 139 engine := derive.NewEngineController(l2, log, metrics, cfg, syncCfg.SyncMode) 140 derivationPipeline := derive.NewDerivationPipeline(log, cfg, verifConfDepth, l1Blobs, plasma, l2, engine, metrics, syncCfg, safeHeadListener) 141 attrBuilder := derive.NewFetchingAttributesBuilder(cfg, l1, l2) 142 meteredEngine := NewMeteredEngine(cfg, engine, metrics, log) // Only use the metered engine in the sequencer b/c it records sequencing metrics. 143 sequencer := NewSequencer(log, cfg, meteredEngine, attrBuilder, findL1Origin, metrics) 144 driverCtx, driverCancel := context.WithCancel(context.Background()) 145 asyncGossiper := async.NewAsyncGossiper(driverCtx, network, log, metrics) 146 return &Driver{ 147 l1State: l1State, 148 derivation: derivationPipeline, 149 engineController: engine, 150 stateReq: make(chan chan struct{}), 151 forceReset: make(chan chan struct{}, 10), 152 startSequencer: make(chan hashAndErrorChannel, 10), 153 stopSequencer: make(chan chan hashAndError, 10), 154 sequencerActive: make(chan chan bool, 10), 155 sequencerNotifs: sequencerStateListener, 156 config: cfg, 157 syncCfg: syncCfg, 158 driverConfig: driverCfg, 159 driverCtx: driverCtx, 160 driverCancel: driverCancel, 161 log: log, 162 snapshotLog: snapshotLog, 163 l1: l1, 164 l2: l2, 165 sequencer: sequencer, 166 network: network, 167 metrics: metrics, 168 l1HeadSig: make(chan eth.L1BlockRef, 10), 169 l1SafeSig: make(chan eth.L1BlockRef, 10), 170 l1FinalizedSig: make(chan eth.L1BlockRef, 10), 171 unsafeL2Payloads: make(chan *eth.ExecutionPayloadEnvelope, 10), 172 altSync: altSync, 173 asyncGossiper: asyncGossiper, 174 sequencerConductor: sequencerConductor, 175 } 176 }