l2_processor.go 1.84 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
package processor

import (
	"github.com/ethereum-optimism/optimism/indexer/database"
	"github.com/ethereum-optimism/optimism/indexer/node"

	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/log"
)

type L2Processor struct {
	processor
}

func NewL2Processor(ethClient node.EthClient, db *database.DB) (*L2Processor, error) {
	l2ProcessLog := log.New("processor", "l2")
17
	l2ProcessLog.Info("initializing processor")
18 19 20 21 22 23 24 25

	latestHeader, err := db.Blocks.FinalizedL2BlockHeader()
	if err != nil {
		return nil, err
	}

	var fromL2Header *types.Header
	if latestHeader != nil {
26
		l2ProcessLog.Info("detected last indexed block", "height", latestHeader.Number.Int, "hash", latestHeader.Hash)
27 28
		l2Header, err := ethClient.BlockHeaderByHash(latestHeader.Hash)
		if err != nil {
29
			l2ProcessLog.Error("unable to fetch header for last indexed block", "hash", latestHeader.Hash, "err", err)
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
			return nil, err
		}

		fromL2Header = l2Header
	} else {
		l2ProcessLog.Info("no indexed state, starting from genesis")
		fromL2Header = nil
	}

	l2Processor := &L2Processor{
		processor: processor{
			fetcher:    node.NewFetcher(ethClient, fromL2Header),
			db:         db,
			processFn:  l2ProcessFn(ethClient),
			processLog: l2ProcessLog,
		},
	}

	return l2Processor, nil
}

func l2ProcessFn(ethClient node.EthClient) func(db *database.DB, headers []*types.Header) error {
	return func(db *database.DB, headers []*types.Header) error {

		// index all l2 blocks for now
		l2Headers := make([]*database.L2BlockHeader, len(headers))
		for i, header := range headers {
			l2Headers[i] = &database.L2BlockHeader{
				BlockHeader: database.BlockHeader{
					Hash:       header.Hash(),
					ParentHash: header.ParentHash,
					Number:     database.U256{Int: header.Number},
					Timestamp:  header.Time,
				},
			}
		}

		return db.Blocks.StoreL2BlockHeaders(l2Headers)
	}
}