github.com/ethereum-optimism/optimism@v1.7.2/op-node/rollup/derive/payload_util.go (about)

     1  package derive
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  
     7  	"github.com/ethereum/go-ethereum/core/types"
     8  
     9  	"github.com/ethereum-optimism/optimism/op-node/rollup"
    10  	"github.com/ethereum-optimism/optimism/op-service/eth"
    11  )
    12  
    13  // PayloadToBlockRef extracts the essential L2BlockRef information from an execution payload,
    14  // falling back to genesis information if necessary.
    15  func PayloadToBlockRef(rollupCfg *rollup.Config, payload *eth.ExecutionPayload) (eth.L2BlockRef, error) {
    16  	genesis := &rollupCfg.Genesis
    17  	var l1Origin eth.BlockID
    18  	var sequenceNumber uint64
    19  	if uint64(payload.BlockNumber) == genesis.L2.Number {
    20  		if payload.BlockHash != genesis.L2.Hash {
    21  			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)
    22  		}
    23  		l1Origin = genesis.L1
    24  		sequenceNumber = 0
    25  	} else {
    26  		if len(payload.Transactions) == 0 {
    27  			return eth.L2BlockRef{}, fmt.Errorf("l2 block is missing L1 info deposit tx, block hash: %s", payload.BlockHash)
    28  		}
    29  		var tx types.Transaction
    30  		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  		if tx.Type() != types.DepositTxType {
    34  			return eth.L2BlockRef{}, fmt.Errorf("first payload tx has unexpected tx type: %d", tx.Type())
    35  		}
    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  		l1Origin = eth.BlockID{Hash: info.BlockHash, Number: info.Number}
    41  		sequenceNumber = info.SequenceNumber
    42  	}
    43  
    44  	return eth.L2BlockRef{
    45  		Hash:           payload.BlockHash,
    46  		Number:         uint64(payload.BlockNumber),
    47  		ParentHash:     payload.ParentHash,
    48  		Time:           uint64(payload.Timestamp),
    49  		L1Origin:       l1Origin,
    50  		SequenceNumber: sequenceNumber,
    51  	}, nil
    52  }
    53  
    54  func PayloadToSystemConfig(rollupCfg *rollup.Config, payload *eth.ExecutionPayload) (eth.SystemConfig, error) {
    55  	if uint64(payload.BlockNumber) == rollupCfg.Genesis.L2.Number {
    56  		if payload.BlockHash != rollupCfg.Genesis.L2.Hash {
    57  			return eth.SystemConfig{}, fmt.Errorf(
    58  				"expected L2 genesis hash to match L2 block at genesis block number %d: %s <> %s",
    59  				rollupCfg.Genesis.L2.Number, payload.BlockHash, rollupCfg.Genesis.L2.Hash)
    60  		}
    61  		return rollupCfg.Genesis.SystemConfig, nil
    62  	} else {
    63  		if len(payload.Transactions) == 0 {
    64  			return eth.SystemConfig{}, fmt.Errorf("l2 block is missing L1 info deposit tx, block hash: %s", payload.BlockHash)
    65  		}
    66  		var tx types.Transaction
    67  		if err := tx.UnmarshalBinary(payload.Transactions[0]); err != nil {
    68  			return eth.SystemConfig{}, fmt.Errorf("failed to decode first tx to read l1 info from: %w", err)
    69  		}
    70  		if tx.Type() != types.DepositTxType {
    71  			return eth.SystemConfig{}, fmt.Errorf("first payload tx has unexpected tx type: %d", tx.Type())
    72  		}
    73  		info, err := L1BlockInfoFromBytes(rollupCfg, uint64(payload.Timestamp), tx.Data())
    74  		if err != nil {
    75  			return eth.SystemConfig{}, fmt.Errorf("failed to parse L1 info deposit tx from L2 block: %w", err)
    76  		}
    77  		if isEcotoneButNotFirstBlock(rollupCfg, uint64(payload.Timestamp)) {
    78  			// Translate Ecotone values back into encoded scalar if needed.
    79  			// We do not know if it was derived from a v0 or v1 scalar,
    80  			// but v1 is fine, a 0 blob base fee has the same effect.
    81  			info.L1FeeScalar[0] = 1
    82  			binary.BigEndian.PutUint32(info.L1FeeScalar[24:28], info.BlobBaseFeeScalar)
    83  			binary.BigEndian.PutUint32(info.L1FeeScalar[28:32], info.BaseFeeScalar)
    84  		}
    85  		return eth.SystemConfig{
    86  			BatcherAddr: info.BatcherAddr,
    87  			Overhead:    info.L1FeeOverhead,
    88  			Scalar:      info.L1FeeScalar,
    89  			GasLimit:    uint64(payload.GasLimit),
    90  		}, err
    91  	}
    92  }