From 48bba206f6ee50e573b6c425c52fbcb558989013 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 26 Jun 2023 04:11:58 +0800 Subject: [PATCH] feat(driver): check the mismatch of last verified block (#296) --- driver/chain_syncer/calldata/syncer.go | 43 +++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/driver/chain_syncer/calldata/syncer.go b/driver/chain_syncer/calldata/syncer.go index ffb8a0ddd..11295fa40 100644 --- a/driver/chain_syncer/calldata/syncer.go +++ b/driver/chain_syncer/calldata/syncer.go @@ -116,12 +116,35 @@ func (s *Syncer) onBlockProposed( if !s.progressTracker.Triggered() { // Check whteher we need to reorg the L2 chain at first. - reorged, l1CurrentToReset, lastInsertedBlockIDToReset, err := s.rpc.CheckL1Reorg( - ctx, - new(big.Int).Sub(event.Id, common.Big1), + // 1. Last verified block + var ( + reorged bool + l1CurrentToReset *types.Header + lastInsertedBlockIDToReset *big.Int + err error ) + reorged, err = s.checkLastVerifiedBlockMismatch(ctx) if err != nil { - return fmt.Errorf("failed to check whether L1 chain has been reorged: %w", err) + return fmt.Errorf("failed to check if last verified block in L2 EE has been reorged: %w", err) + } + + // 2. Parent block + if reorged { + genesisL1Header, err := s.rpc.GetGenesisL1Header(ctx) + if err != nil { + return fmt.Errorf("failed to fetch genesis L1 header: %w", err) + } + + l1CurrentToReset = genesisL1Header + lastInsertedBlockIDToReset = common.Big0 + } else { + reorged, l1CurrentToReset, lastInsertedBlockIDToReset, err = s.rpc.CheckL1Reorg( + ctx, + new(big.Int).Sub(event.Id, common.Big1), + ) + if err != nil { + return fmt.Errorf("failed to check whether L1 chain has been reorged: %w", err) + } } if reorged { @@ -427,3 +450,15 @@ func (s *Syncer) createExecutionPayloads( return payload, nil } + +// checkLastVerifiedBlockMismatch checks if there is a mismatch between protocol's last verified block hash and +// the corresponding L2 EE block hash. +func (s *Syncer) checkLastVerifiedBlockMismatch(ctx context.Context) (bool, error) { + lastVerifiedBlockInfo := s.state.GetLatestVerifiedBlock() + l2Header, err := s.rpc.L2.HeaderByNumber(ctx, lastVerifiedBlockInfo.Height) + if err != nil { + return false, err + } + + return l2Header.Hash() != lastVerifiedBlockInfo.Hash, nil +}