Commit ecf0cc59 authored by Matthew Slipper's avatar Matthew Slipper

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.
parent 585a94a8
---
'@eth-optimism/indexer': minor
---
Fix startup issues, add L2 conf depth
...@@ -65,9 +65,13 @@ type Config struct { ...@@ -65,9 +65,13 @@ type Config struct {
// L1StartBlockNumber is the block number to start indexing L1 from. // L1StartBlockNumber is the block number to start indexing L1 from.
L1StartBlockNumber uint64 L1StartBlockNumber uint64
// ConfDepth is the number of confirmations after which headers are // L1ConfDepth is the number of confirmations after which headers are
// considered confirmed. // considered confirmed on L1.
ConfDepth uint64 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 // MaxHeaderBatchSize is the maximum number of headers to request as a
// batch. // batch.
...@@ -122,7 +126,8 @@ func NewConfig(ctx *cli.Context) (Config, error) { ...@@ -122,7 +126,8 @@ func NewConfig(ctx *cli.Context) (Config, error) {
LogLevel: ctx.GlobalString(flags.LogLevelFlag.Name), LogLevel: ctx.GlobalString(flags.LogLevelFlag.Name),
LogTerminal: ctx.GlobalBool(flags.LogTerminalFlag.Name), LogTerminal: ctx.GlobalBool(flags.LogTerminalFlag.Name),
L1StartBlockNumber: ctx.GlobalUint64(flags.L1StartBlockNumberFlag.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), MaxHeaderBatchSize: ctx.GlobalUint64(flags.MaxHeaderBatchSizeFlag.Name),
MetricsServerEnable: ctx.GlobalBool(flags.MetricsServerEnableFlag.Name), MetricsServerEnable: ctx.GlobalBool(flags.MetricsServerEnableFlag.Name),
RESTHostname: ctx.GlobalString(flags.RESTHostnameFlag.Name), RESTHostname: ctx.GlobalString(flags.RESTHostnameFlag.Name),
......
...@@ -137,11 +137,17 @@ var ( ...@@ -137,11 +137,17 @@ var (
Value: 0, Value: 0,
EnvVar: prefixEnvVar("START_BLOCK_NUMBER"), EnvVar: prefixEnvVar("START_BLOCK_NUMBER"),
} }
ConfDepthFlag = cli.Uint64Flag{ L1ConfDepthFlag = cli.Uint64Flag{
Name: "conf-depth", Name: "l1-conf-depth",
Usage: "The number of confirmations after which headers are considered confirmed", Usage: "The number of confirmations after which headers are considered confirmed on L1",
Value: 20, 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{ MaxHeaderBatchSizeFlag = cli.Uint64Flag{
Name: "max-header-batch-size", Name: "max-header-batch-size",
...@@ -203,7 +209,8 @@ var optionalFlags = []cli.Flag{ ...@@ -203,7 +209,8 @@ var optionalFlags = []cli.Flag{
SentryEnableFlag, SentryEnableFlag,
SentryDsnFlag, SentryDsnFlag,
SentryTraceRateFlag, SentryTraceRateFlag,
ConfDepthFlag, L1ConfDepthFlag,
L2ConfDepthFlag,
MaxHeaderBatchSizeFlag, MaxHeaderBatchSizeFlag,
L1StartBlockNumberFlag, L1StartBlockNumberFlag,
RESTHostnameFlag, RESTHostnameFlag,
......
...@@ -164,7 +164,7 @@ func NewIndexer(cfg Config) (*Indexer, error) { ...@@ -164,7 +164,7 @@ func NewIndexer(cfg Config) (*Indexer, error) {
ChainID: new(big.Int).SetUint64(cfg.ChainID), ChainID: new(big.Int).SetUint64(cfg.ChainID),
AddressManager: addrManager, AddressManager: addrManager,
DB: db, DB: db,
ConfDepth: cfg.ConfDepth, ConfDepth: cfg.L1ConfDepth,
MaxHeaderBatchSize: cfg.MaxHeaderBatchSize, MaxHeaderBatchSize: cfg.MaxHeaderBatchSize,
StartBlockNumber: cfg.L1StartBlockNumber, StartBlockNumber: cfg.L1StartBlockNumber,
Bedrock: cfg.Bedrock, Bedrock: cfg.Bedrock,
...@@ -179,7 +179,7 @@ func NewIndexer(cfg Config) (*Indexer, error) { ...@@ -179,7 +179,7 @@ func NewIndexer(cfg Config) (*Indexer, error) {
L2RPC: l2RPC, L2RPC: l2RPC,
L2Client: l2Client, L2Client: l2Client,
DB: db, DB: db,
ConfDepth: cfg.ConfDepth, ConfDepth: cfg.L2ConfDepth,
MaxHeaderBatchSize: cfg.MaxHeaderBatchSize, MaxHeaderBatchSize: cfg.MaxHeaderBatchSize,
StartBlockNumber: uint64(0), StartBlockNumber: uint64(0),
Bedrock: cfg.Bedrock, Bedrock: cfg.Bedrock,
......
...@@ -73,7 +73,8 @@ func TestBedrockIndexer(t *testing.T) { ...@@ -73,7 +73,8 @@ func TestBedrockIndexer(t *testing.T) {
LogLevel: "info", LogLevel: "info",
LogTerminal: true, LogTerminal: true,
L1StartBlockNumber: 0, L1StartBlockNumber: 0,
ConfDepth: 1, L1ConfDepth: 1,
L2ConfDepth: 1,
MaxHeaderBatchSize: 2, MaxHeaderBatchSize: 2,
RESTHostname: "127.0.0.1", RESTHostname: "127.0.0.1",
RESTPort: 7980, RESTPort: 7980,
......
...@@ -71,6 +71,7 @@ type Service struct { ...@@ -71,6 +71,7 @@ type Service struct {
batchScanner *scc.StateCommitmentChainFilterer batchScanner *scc.StateCommitmentChainFilterer
latestHeader uint64 latestHeader uint64
headerSelector *ConfirmedHeaderSelector headerSelector *ConfirmedHeaderSelector
l1Client *ethclient.Client
metrics *metrics.Metrics metrics *metrics.Metrics
tokenCache map[common.Address]*db.Token tokenCache map[common.Address]*db.Token
...@@ -143,6 +144,7 @@ func NewService(cfg ServiceConfig) (*Service, error) { ...@@ -143,6 +144,7 @@ func NewService(cfg ServiceConfig) (*Service, error) {
ZeroAddress: db.ETHL1Token, ZeroAddress: db.ETHL1Token,
}, },
isBedrock: cfg.Bedrock, isBedrock: cfg.Bedrock,
l1Client: cfg.L1Client,
} }
service.wg.Add(1) service.wg.Add(1)
return service, nil return service, nil
...@@ -202,16 +204,22 @@ func (s *Service) loop() { ...@@ -202,16 +204,22 @@ func (s *Service) loop() {
} }
func (s *Service) Update(newHeader *types.Header) error { func (s *Service) Update(newHeader *types.Header) error {
var lowest = db.BlockLocator{ var lowest db.BlockLocator
Number: s.cfg.StartBlockNumber,
}
highestConfirmed, err := s.cfg.DB.GetHighestL1Block() highestConfirmed, err := s.cfg.DB.GetHighestL1Block()
if err != nil { if err != nil {
return err return err
} }
if highestConfirmed != nil { if highestConfirmed == nil {
lowest = *highestConfirmed 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) headers, err := s.headerSelector.NewHead(s.ctx, lowest.Number, newHeader, s.cfg.RawL1Client)
if err != nil { if err != nil {
...@@ -260,22 +268,28 @@ func (s *Service) Update(newHeader *types.Header) error { ...@@ -260,22 +268,28 @@ func (s *Service) Update(newHeader *types.Header) error {
bridgeDepositsCh <- deposits bridgeDepositsCh <- deposits
}(bridgeImpl) }(bridgeImpl)
} }
go func() {
provenWithdrawals, err := s.portal.GetProvenWithdrawalsByBlockRange(s.ctx, startHeight, endHeight) if s.isBedrock {
if err != nil { go func() {
errCh <- err provenWithdrawals, err := s.portal.GetProvenWithdrawalsByBlockRange(s.ctx, startHeight, endHeight)
return if err != nil {
} errCh <- err
provenWithdrawalsCh <- provenWithdrawals return
}() }
go func() { provenWithdrawalsCh <- provenWithdrawals
finalizedWithdrawals, err := s.portal.GetFinalizedWithdrawalsByBlockRange(s.ctx, startHeight, endHeight) }()
if err != nil { go func() {
errCh <- err finalizedWithdrawals, err := s.portal.GetFinalizedWithdrawalsByBlockRange(s.ctx, startHeight, endHeight)
return if err != nil {
} errCh <- err
finalizedWithdrawalsCh <- finalizedWithdrawals return
}() }
finalizedWithdrawalsCh <- finalizedWithdrawals
}()
} else {
provenWithdrawalsCh <- make(bridge.ProvenWithdrawalsMap)
finalizedWithdrawalsCh <- make(bridge.FinalizedWithdrawalsMap)
}
var receives int var receives int
for { for {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment