payload_util.go 3.72 KB
Newer Older
1 2 3
package derive

import (
4
	"encoding/binary"
5 6
	"fmt"

7 8
	"github.com/ethereum/go-ethereum/core/types"

9
	"github.com/ethereum-optimism/optimism/op-node/rollup"
10
	"github.com/ethereum-optimism/optimism/op-service/eth"
11 12 13 14
)

// PayloadToBlockRef extracts the essential L2BlockRef information from an execution payload,
// falling back to genesis information if necessary.
15 16
func PayloadToBlockRef(rollupCfg *rollup.Config, payload *eth.ExecutionPayload) (eth.L2BlockRef, error) {
	genesis := &rollupCfg.Genesis
17 18 19 20 21 22 23 24 25 26 27 28 29 30
	var l1Origin eth.BlockID
	var sequenceNumber uint64
	if uint64(payload.BlockNumber) == genesis.L2.Number {
		if payload.BlockHash != genesis.L2.Hash {
			return eth.L2BlockRef{}, fmt.Errorf("expected L2 genesis hash to match L2 block at genesis block number %d: %s <> %s", genesis.L2.Number, payload.BlockHash, genesis.L2.Hash)
		}
		l1Origin = genesis.L1
		sequenceNumber = 0
	} else {
		if len(payload.Transactions) == 0 {
			return eth.L2BlockRef{}, fmt.Errorf("l2 block is missing L1 info deposit tx, block hash: %s", payload.BlockHash)
		}
		var tx types.Transaction
		if err := tx.UnmarshalBinary(payload.Transactions[0]); err != nil {
31
			return eth.L2BlockRef{}, fmt.Errorf("failed to decode first tx to read l1 info from: %w", err)
32 33 34 35
		}
		if tx.Type() != types.DepositTxType {
			return eth.L2BlockRef{}, fmt.Errorf("first payload tx has unexpected tx type: %d", tx.Type())
		}
36
		info, err := L1BlockInfoFromBytes(rollupCfg, uint64(payload.Timestamp), tx.Data())
37
		if err != nil {
38
			return eth.L2BlockRef{}, fmt.Errorf("failed to parse L1 info deposit tx from L2 block: %w", err)
39 40 41 42 43 44 45 46 47 48 49 50 51 52
		}
		l1Origin = eth.BlockID{Hash: info.BlockHash, Number: info.Number}
		sequenceNumber = info.SequenceNumber
	}

	return eth.L2BlockRef{
		Hash:           payload.BlockHash,
		Number:         uint64(payload.BlockNumber),
		ParentHash:     payload.ParentHash,
		Time:           uint64(payload.Timestamp),
		L1Origin:       l1Origin,
		SequenceNumber: sequenceNumber,
	}, nil
}
53

54 55 56 57 58 59
func PayloadToSystemConfig(rollupCfg *rollup.Config, payload *eth.ExecutionPayload) (eth.SystemConfig, error) {
	if uint64(payload.BlockNumber) == rollupCfg.Genesis.L2.Number {
		if payload.BlockHash != rollupCfg.Genesis.L2.Hash {
			return eth.SystemConfig{}, fmt.Errorf(
				"expected L2 genesis hash to match L2 block at genesis block number %d: %s <> %s",
				rollupCfg.Genesis.L2.Number, payload.BlockHash, rollupCfg.Genesis.L2.Hash)
60
		}
61
		return rollupCfg.Genesis.SystemConfig, nil
62 63 64 65 66 67 68 69 70 71 72
	} else {
		if len(payload.Transactions) == 0 {
			return eth.SystemConfig{}, fmt.Errorf("l2 block is missing L1 info deposit tx, block hash: %s", payload.BlockHash)
		}
		var tx types.Transaction
		if err := tx.UnmarshalBinary(payload.Transactions[0]); err != nil {
			return eth.SystemConfig{}, fmt.Errorf("failed to decode first tx to read l1 info from: %w", err)
		}
		if tx.Type() != types.DepositTxType {
			return eth.SystemConfig{}, fmt.Errorf("first payload tx has unexpected tx type: %d", tx.Type())
		}
73
		info, err := L1BlockInfoFromBytes(rollupCfg, uint64(payload.Timestamp), tx.Data())
74 75 76
		if err != nil {
			return eth.SystemConfig{}, fmt.Errorf("failed to parse L1 info deposit tx from L2 block: %w", err)
		}
77 78 79 80 81 82 83 84
		if isEcotoneButNotFirstBlock(rollupCfg, uint64(payload.Timestamp)) {
			// Translate Ecotone values back into encoded scalar if needed.
			// We do not know if it was derived from a v0 or v1 scalar,
			// but v1 is fine, a 0 blob base fee has the same effect.
			info.L1FeeScalar[0] = 1
			binary.BigEndian.PutUint32(info.L1FeeScalar[24:28], info.BlobBaseFeeScalar)
			binary.BigEndian.PutUint32(info.L1FeeScalar[28:32], info.BaseFeeScalar)
		}
85
		return eth.SystemConfig{
86 87 88 89
			BatcherAddr: info.BatcherAddr,
			Overhead:    info.L1FeeOverhead,
			Scalar:      info.L1FeeScalar,
			GasLimit:    uint64(payload.GasLimit),
90 91 92
		}, err
	}
}