github.com/ethereum-optimism/optimism@v1.7.2/op-node/rollup/driver/metered_engine.go (about) 1 package driver 2 3 import ( 4 "context" 5 "time" 6 7 "github.com/ethereum/go-ethereum/log" 8 9 "github.com/ethereum-optimism/optimism/op-node/rollup" 10 "github.com/ethereum-optimism/optimism/op-node/rollup/async" 11 "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" 12 "github.com/ethereum-optimism/optimism/op-node/rollup/derive" 13 "github.com/ethereum-optimism/optimism/op-service/eth" 14 ) 15 16 type EngineMetrics interface { 17 RecordSequencingError() 18 CountSequencedTxs(count int) 19 20 RecordSequencerBuildingDiffTime(duration time.Duration) 21 RecordSequencerSealingTime(duration time.Duration) 22 } 23 24 // MeteredEngine wraps an EngineControl and adds metrics such as block building time diff and sealing time 25 type MeteredEngine struct { 26 inner derive.EngineControl 27 28 cfg *rollup.Config 29 metrics EngineMetrics 30 log log.Logger 31 32 buildingStartTime time.Time 33 } 34 35 func NewMeteredEngine(cfg *rollup.Config, inner derive.EngineControl, metrics EngineMetrics, log log.Logger) *MeteredEngine { 36 return &MeteredEngine{ 37 inner: inner, 38 cfg: cfg, 39 metrics: metrics, 40 log: log, 41 } 42 } 43 44 func (m *MeteredEngine) Finalized() eth.L2BlockRef { 45 return m.inner.Finalized() 46 } 47 48 func (m *MeteredEngine) UnsafeL2Head() eth.L2BlockRef { 49 return m.inner.UnsafeL2Head() 50 } 51 52 func (m *MeteredEngine) SafeL2Head() eth.L2BlockRef { 53 return m.inner.SafeL2Head() 54 } 55 56 func (m *MeteredEngine) StartPayload(ctx context.Context, parent eth.L2BlockRef, attrs *derive.AttributesWithParent, updateSafe bool) (errType derive.BlockInsertionErrType, err error) { 57 m.buildingStartTime = time.Now() 58 errType, err = m.inner.StartPayload(ctx, parent, attrs, updateSafe) 59 if err != nil { 60 m.metrics.RecordSequencingError() 61 } 62 return errType, err 63 } 64 65 func (m *MeteredEngine) ConfirmPayload(ctx context.Context, agossip async.AsyncGossiper, sequencerConductor conductor.SequencerConductor) (out *eth.ExecutionPayloadEnvelope, errTyp derive.BlockInsertionErrType, err error) { 66 sealingStart := time.Now() 67 // Actually execute the block and add it to the head of the chain. 68 payload, errType, err := m.inner.ConfirmPayload(ctx, agossip, sequencerConductor) 69 if err != nil { 70 m.metrics.RecordSequencingError() 71 return payload, errType, err 72 } 73 now := time.Now() 74 sealTime := now.Sub(sealingStart) 75 buildTime := now.Sub(m.buildingStartTime) 76 m.metrics.RecordSequencerSealingTime(sealTime) 77 m.metrics.RecordSequencerBuildingDiffTime(buildTime - time.Duration(m.cfg.BlockTime)*time.Second) 78 79 txnCount := len(payload.ExecutionPayload.Transactions) 80 m.metrics.CountSequencedTxs(txnCount) 81 82 ref := m.inner.UnsafeL2Head() 83 84 m.log.Debug("Processed new L2 block", "l2_unsafe", ref, "l1_origin", ref.L1Origin, 85 "txs", txnCount, "time", ref.Time, "seal_time", sealTime, "build_time", buildTime) 86 87 return payload, errType, err 88 } 89 90 func (m *MeteredEngine) CancelPayload(ctx context.Context, force bool) error { 91 return m.inner.CancelPayload(ctx, force) 92 } 93 94 func (m *MeteredEngine) BuildingPayload() (onto eth.L2BlockRef, id eth.PayloadID, safe bool) { 95 return m.inner.BuildingPayload() 96 }