payload_process.go 1.72 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
package engine

import (
	"context"
	"fmt"

	"github.com/ethereum-optimism/optimism/op-node/rollup"
	"github.com/ethereum-optimism/optimism/op-service/eth"
)

type PayloadProcessEvent struct {
12 13
	// if payload should be promoted to (local) safe (must also be pending safe, see DerivedFrom)
	Concluding bool
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
	// payload is promoted to pending-safe if non-zero
	DerivedFrom eth.L1BlockRef

	Envelope *eth.ExecutionPayloadEnvelope
	Ref      eth.L2BlockRef
}

func (ev PayloadProcessEvent) String() string {
	return "payload-process"
}

func (eq *EngDeriver) onPayloadProcess(ev PayloadProcessEvent) {
	ctx, cancel := context.WithTimeout(eq.ctx, payloadProcessTimeout)
	defer cancel()

	status, err := eq.ec.engine.NewPayload(ctx,
		ev.Envelope.ExecutionPayload, ev.Envelope.ParentBeaconBlockRoot)
	if err != nil {
		eq.emitter.Emit(rollup.EngineTemporaryErrorEvent{
33 34
			Err: fmt.Errorf("failed to insert execution payload: %w", err),
		})
35 36 37 38
		return
	}
	switch status.Status {
	case eth.ExecutionInvalid, eth.ExecutionInvalidBlockHash:
39 40 41 42 43 44 45
		// Depending on execution engine, not all block-validity checks run immediately on build-start
		// at the time of the forkchoiceUpdated engine-API call, nor during getPayload.
		if ev.DerivedFrom != (eth.L1BlockRef{}) && eq.cfg.IsHolocene(ev.DerivedFrom.Time) {
			eq.emitDepositsOnlyPayloadAttributesRequest(ev.Ref.ParentID(), ev.DerivedFrom)
			return
		}

46 47
		eq.emitter.Emit(PayloadInvalidEvent{
			Envelope: ev.Envelope,
48 49
			Err:      eth.NewPayloadErr(ev.Envelope.ExecutionPayload, status),
		})
50 51 52 53 54 55
		return
	case eth.ExecutionValid:
		eq.emitter.Emit(PayloadSuccessEvent(ev))
		return
	default:
		eq.emitter.Emit(rollup.EngineTemporaryErrorEvent{
56 57
			Err: eth.NewPayloadErr(ev.Envelope.ExecutionPayload, status),
		})
58 59 60
		return
	}
}