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

     1  package derive
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/ethereum/go-ethereum/common"
     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  // L2BlockRefSource is a source for the generation of a L2BlockRef. E.g. a
    14  // *types.Block is a L2BlockRefSource.
    15  //
    16  // L2BlockToBlockRef extracts L2BlockRef from a L2BlockRefSource. The first
    17  // transaction of a source must be a Deposit transaction.
    18  type L2BlockRefSource interface {
    19  	Hash() common.Hash
    20  	ParentHash() common.Hash
    21  	NumberU64() uint64
    22  	Time() uint64
    23  	Transactions() types.Transactions
    24  }
    25  
    26  // L2BlockToBlockRef extracts the essential L2BlockRef information from an L2
    27  // block ref source, falling back to genesis information if necessary.
    28  func L2BlockToBlockRef(rollupCfg *rollup.Config, block L2BlockRefSource) (eth.L2BlockRef, error) {
    29  	hash, number := block.Hash(), block.NumberU64()
    30  
    31  	var l1Origin eth.BlockID
    32  	var sequenceNumber uint64
    33  	genesis := &rollupCfg.Genesis
    34  	if number == genesis.L2.Number {
    35  		if hash != genesis.L2.Hash {
    36  			return eth.L2BlockRef{}, fmt.Errorf("expected L2 genesis hash to match L2 block at genesis block number %d: %s <> %s", genesis.L2.Number, hash, genesis.L2.Hash)
    37  		}
    38  		l1Origin = genesis.L1
    39  		sequenceNumber = 0
    40  	} else {
    41  		txs := block.Transactions()
    42  		if txs.Len() == 0 {
    43  			return eth.L2BlockRef{}, fmt.Errorf("l2 block is missing L1 info deposit tx, block hash: %s", hash)
    44  		}
    45  		tx := txs[0]
    46  		if tx.Type() != types.DepositTxType {
    47  			return eth.L2BlockRef{}, fmt.Errorf("first payload tx has unexpected tx type: %d", tx.Type())
    48  		}
    49  		info, err := L1BlockInfoFromBytes(rollupCfg, block.Time(), tx.Data())
    50  		if err != nil {
    51  			return eth.L2BlockRef{}, fmt.Errorf("failed to parse L1 info deposit tx from L2 block: %w", err)
    52  		}
    53  		l1Origin = eth.BlockID{Hash: info.BlockHash, Number: info.Number}
    54  		sequenceNumber = info.SequenceNumber
    55  	}
    56  
    57  	return eth.L2BlockRef{
    58  		Hash:           hash,
    59  		Number:         number,
    60  		ParentHash:     block.ParentHash(),
    61  		Time:           block.Time(),
    62  		L1Origin:       l1Origin,
    63  		SequenceNumber: sequenceNumber,
    64  	}, nil
    65  }