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  }