Skip to content
This repository was archived by the owner on Feb 17, 2025. It is now read-only.

Commit d803870

Browse files
committed
Add sanity-check on checkL1InfoTreeUpdate to check state L1 blockhash matches ethereum blockhash (L1 reorg check) (#3480)
* Add sanity check on checkL1InfoTreeUpdate to check state L1 blockhash matches ethereum blockhash (L1 reorg check) * fix L1 block is 0 (empty l1infotree) * Update Prover image to v5.0.9
1 parent bf4aa03 commit d803870

File tree

3 files changed

+65
-4
lines changed

3 files changed

+65
-4
lines changed

sequencer/finalizer.go

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,19 @@ func (f *finalizer) updateFlushIDs(newPendingFlushID, newStoredFlushID uint64) {
222222

223223
func (f *finalizer) checkL1InfoTreeUpdate(ctx context.Context) {
224224
firstL1InfoRootUpdate := true
225+
skipFirstSleep := true
225226

226227
for {
228+
if skipFirstSleep {
229+
skipFirstSleep = false
230+
} else {
231+
time.Sleep(f.cfg.L1InfoTreeCheckInterval.Duration)
232+
}
233+
227234
lastL1BlockNumber, err := f.etherman.GetLatestBlockNumber(ctx)
228235
if err != nil {
229236
log.Errorf("error getting latest L1 block number, error: %v", err)
237+
continue
230238
}
231239

232240
maxBlockNumber := uint64(0)
@@ -246,9 +254,30 @@ func (f *finalizer) checkL1InfoTreeUpdate(ctx context.Context) {
246254
}
247255

248256
if firstL1InfoRootUpdate || l1InfoRoot.L1InfoTreeIndex > f.lastL1InfoTree.L1InfoTreeIndex {
249-
firstL1InfoRootUpdate = false
257+
log.Infof("received new L1InfoRoot, l1InfoTreeIndex: %d, l1InfoTreeRoot: %s, l1Block: %d",
258+
l1InfoRoot.L1InfoTreeIndex, l1InfoRoot.L1InfoTreeRoot, l1InfoRoot.BlockNumber)
250259

251-
log.Debugf("received new L1InfoRoot. L1InfoTreeIndex: %d", l1InfoRoot.L1InfoTreeIndex)
260+
// Sanity check l1BlockState (l1InfoRoot.BlockNumber) blockhash matches blockhash on ethereum. We skip it if l1InfoRoot.BlockNumber == 0 (empty tree)
261+
if l1InfoRoot.BlockNumber > 0 {
262+
l1BlockState, err := f.stateIntf.GetBlockByNumber(ctx, l1InfoRoot.BlockNumber, nil)
263+
if err != nil {
264+
log.Errorf("error getting L1 block %d from the state, error: %v", l1InfoRoot.BlockNumber, err)
265+
continue
266+
}
267+
268+
l1BlockEth, err := f.etherman.HeaderByNumber(ctx, new(big.Int).SetUint64(l1InfoRoot.BlockNumber))
269+
if err != nil {
270+
log.Errorf("error getting L1 block %d from ethereum, error: %v", l1InfoRoot.BlockNumber, err)
271+
continue
272+
}
273+
if l1BlockState.BlockHash != l1BlockEth.Hash() {
274+
log.Warnf("skipping use of l1InfoTreeIndex %d, L1 block %d blockhash %s doesn't match blockhash on ethereum %s (L1 reorg?)",
275+
l1InfoRoot.L1InfoTreeIndex, l1InfoRoot.BlockNumber, l1BlockState.BlockHash, l1BlockEth.Hash())
276+
continue
277+
}
278+
}
279+
280+
firstL1InfoRootUpdate = false
252281

253282
f.lastL1InfoTreeMux.Lock()
254283
f.lastL1InfoTree = l1InfoRoot
@@ -261,8 +290,6 @@ func (f *finalizer) checkL1InfoTreeUpdate(ctx context.Context) {
261290
f.lastL1InfoTreeCond.L.Unlock()
262291
}
263292
}
264-
265-
time.Sleep(f.cfg.L1InfoTreeCheckInterval.Duration)
266293
}
267294
}
268295

sequencer/interfaces.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type etherman interface {
3535
TrustedSequencer() (common.Address, error)
3636
GetLatestBatchNumber() (uint64, error)
3737
GetLatestBlockNumber(ctx context.Context) (uint64, error)
38+
HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
3839
}
3940

4041
// stateInterface gathers the methods required to interact with the state.

sequencer/mock_etherman.go

Lines changed: 33 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)