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 }