From ecf0cc59bb612dedc1dcdec2716d3a6bcb1a1934 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Tue, 10 Jan 2023 23:11:17 -0700 Subject: [PATCH] indexer: Fix startup errors - The block locator was being initialized with a zero hash, which caused `Update` return `nil` and crash the process. - Adds an L2 conf depth parameter, since L2 can now reorg. --- .changeset/slimy-files-suffer.md | 5 ++ indexer/config.go | 13 ++++-- indexer/flags/flags.go | 17 +++++-- indexer/indexer.go | 4 +- indexer/integration_tests/bedrock_test.go | 3 +- indexer/services/l1/service.go | 56 ++++++++++++++--------- 6 files changed, 65 insertions(+), 33 deletions(-) create mode 100644 .changeset/slimy-files-suffer.md diff --git a/.changeset/slimy-files-suffer.md b/.changeset/slimy-files-suffer.md new file mode 100644 index 000000000000..b657606ddf22 --- /dev/null +++ b/.changeset/slimy-files-suffer.md @@ -0,0 +1,5 @@ +--- +'@eth-optimism/indexer': minor +--- + +Fix startup issues, add L2 conf depth diff --git a/indexer/config.go b/indexer/config.go index b6a096c79485..ad6afef76f1a 100644 --- a/indexer/config.go +++ b/indexer/config.go @@ -65,9 +65,13 @@ type Config struct { // L1StartBlockNumber is the block number to start indexing L1 from. L1StartBlockNumber uint64 - // ConfDepth is the number of confirmations after which headers are - // considered confirmed. - ConfDepth uint64 + // L1ConfDepth is the number of confirmations after which headers are + // considered confirmed on L1. + L1ConfDepth uint64 + + // L2ConfDepth is the number of confirmations after which headers are + // considered confirmed on L2. + L2ConfDepth uint64 // MaxHeaderBatchSize is the maximum number of headers to request as a // batch. @@ -122,7 +126,8 @@ func NewConfig(ctx *cli.Context) (Config, error) { LogLevel: ctx.GlobalString(flags.LogLevelFlag.Name), LogTerminal: ctx.GlobalBool(flags.LogTerminalFlag.Name), L1StartBlockNumber: ctx.GlobalUint64(flags.L1StartBlockNumberFlag.Name), - ConfDepth: ctx.GlobalUint64(flags.ConfDepthFlag.Name), + L1ConfDepth: ctx.GlobalUint64(flags.L1ConfDepthFlag.Name), + L2ConfDepth: ctx.GlobalUint64(flags.L2ConfDepthFlag.Name), MaxHeaderBatchSize: ctx.GlobalUint64(flags.MaxHeaderBatchSizeFlag.Name), MetricsServerEnable: ctx.GlobalBool(flags.MetricsServerEnableFlag.Name), RESTHostname: ctx.GlobalString(flags.RESTHostnameFlag.Name), diff --git a/indexer/flags/flags.go b/indexer/flags/flags.go index fb6b76b81699..073e0bf09361 100644 --- a/indexer/flags/flags.go +++ b/indexer/flags/flags.go @@ -137,11 +137,17 @@ var ( Value: 0, EnvVar: prefixEnvVar("START_BLOCK_NUMBER"), } - ConfDepthFlag = cli.Uint64Flag{ - Name: "conf-depth", - Usage: "The number of confirmations after which headers are considered confirmed", + L1ConfDepthFlag = cli.Uint64Flag{ + Name: "l1-conf-depth", + Usage: "The number of confirmations after which headers are considered confirmed on L1", Value: 20, - EnvVar: prefixEnvVar("CONF_DEPTH"), + EnvVar: prefixEnvVar("L1_CONF_DEPTH"), + } + L2ConfDepthFlag = cli.Uint64Flag{ + Name: "l2-conf-depth", + Usage: "The number of confirmations after which headers are considered confirmed on L1", + Value: 24, + EnvVar: prefixEnvVar("L2_CONF_DEPTH"), } MaxHeaderBatchSizeFlag = cli.Uint64Flag{ Name: "max-header-batch-size", @@ -203,7 +209,8 @@ var optionalFlags = []cli.Flag{ SentryEnableFlag, SentryDsnFlag, SentryTraceRateFlag, - ConfDepthFlag, + L1ConfDepthFlag, + L2ConfDepthFlag, MaxHeaderBatchSizeFlag, L1StartBlockNumberFlag, RESTHostnameFlag, diff --git a/indexer/indexer.go b/indexer/indexer.go index e07181e8e6b6..0201e55effe0 100644 --- a/indexer/indexer.go +++ b/indexer/indexer.go @@ -164,7 +164,7 @@ func NewIndexer(cfg Config) (*Indexer, error) { ChainID: new(big.Int).SetUint64(cfg.ChainID), AddressManager: addrManager, DB: db, - ConfDepth: cfg.ConfDepth, + ConfDepth: cfg.L1ConfDepth, MaxHeaderBatchSize: cfg.MaxHeaderBatchSize, StartBlockNumber: cfg.L1StartBlockNumber, Bedrock: cfg.Bedrock, @@ -179,7 +179,7 @@ func NewIndexer(cfg Config) (*Indexer, error) { L2RPC: l2RPC, L2Client: l2Client, DB: db, - ConfDepth: cfg.ConfDepth, + ConfDepth: cfg.L2ConfDepth, MaxHeaderBatchSize: cfg.MaxHeaderBatchSize, StartBlockNumber: uint64(0), Bedrock: cfg.Bedrock, diff --git a/indexer/integration_tests/bedrock_test.go b/indexer/integration_tests/bedrock_test.go index b30a5d50b50a..34932d0ca2e4 100644 --- a/indexer/integration_tests/bedrock_test.go +++ b/indexer/integration_tests/bedrock_test.go @@ -73,7 +73,8 @@ func TestBedrockIndexer(t *testing.T) { LogLevel: "info", LogTerminal: true, L1StartBlockNumber: 0, - ConfDepth: 1, + L1ConfDepth: 1, + L2ConfDepth: 1, MaxHeaderBatchSize: 2, RESTHostname: "127.0.0.1", RESTPort: 7980, diff --git a/indexer/services/l1/service.go b/indexer/services/l1/service.go index cc93f5e5947b..505379e64045 100644 --- a/indexer/services/l1/service.go +++ b/indexer/services/l1/service.go @@ -71,6 +71,7 @@ type Service struct { batchScanner *scc.StateCommitmentChainFilterer latestHeader uint64 headerSelector *ConfirmedHeaderSelector + l1Client *ethclient.Client metrics *metrics.Metrics tokenCache map[common.Address]*db.Token @@ -143,6 +144,7 @@ func NewService(cfg ServiceConfig) (*Service, error) { ZeroAddress: db.ETHL1Token, }, isBedrock: cfg.Bedrock, + l1Client: cfg.L1Client, } service.wg.Add(1) return service, nil @@ -202,16 +204,22 @@ func (s *Service) loop() { } func (s *Service) Update(newHeader *types.Header) error { - var lowest = db.BlockLocator{ - Number: s.cfg.StartBlockNumber, - } + var lowest db.BlockLocator highestConfirmed, err := s.cfg.DB.GetHighestL1Block() if err != nil { return err } - if highestConfirmed != nil { - lowest = *highestConfirmed + if highestConfirmed == nil { + startHeader, err := s.l1Client.HeaderByNumber(s.ctx, new(big.Int).SetUint64(s.cfg.StartBlockNumber)) + if err != nil { + return fmt.Errorf("error fetching header by number: %w", err) + } + highestConfirmed = &db.BlockLocator{ + Number: s.cfg.StartBlockNumber, + Hash: startHeader.Hash(), + } } + lowest = *highestConfirmed headers, err := s.headerSelector.NewHead(s.ctx, lowest.Number, newHeader, s.cfg.RawL1Client) if err != nil { @@ -260,22 +268,28 @@ func (s *Service) Update(newHeader *types.Header) error { bridgeDepositsCh <- deposits }(bridgeImpl) } - go func() { - provenWithdrawals, err := s.portal.GetProvenWithdrawalsByBlockRange(s.ctx, startHeight, endHeight) - if err != nil { - errCh <- err - return - } - provenWithdrawalsCh <- provenWithdrawals - }() - go func() { - finalizedWithdrawals, err := s.portal.GetFinalizedWithdrawalsByBlockRange(s.ctx, startHeight, endHeight) - if err != nil { - errCh <- err - return - } - finalizedWithdrawalsCh <- finalizedWithdrawals - }() + + if s.isBedrock { + go func() { + provenWithdrawals, err := s.portal.GetProvenWithdrawalsByBlockRange(s.ctx, startHeight, endHeight) + if err != nil { + errCh <- err + return + } + provenWithdrawalsCh <- provenWithdrawals + }() + go func() { + finalizedWithdrawals, err := s.portal.GetFinalizedWithdrawalsByBlockRange(s.ctx, startHeight, endHeight) + if err != nil { + errCh <- err + return + } + finalizedWithdrawalsCh <- finalizedWithdrawals + }() + } else { + provenWithdrawalsCh <- make(bridge.ProvenWithdrawalsMap) + finalizedWithdrawalsCh <- make(bridge.FinalizedWithdrawalsMap) + } var receives int for {