Skip to content

Commit

Permalink
fix(l1-watcher): soft delete blocks when reorg (#923)
Browse files Browse the repository at this point in the history
Co-authored-by: colinlyguo <colinlyguo@users.noreply.github.com>
  • Loading branch information
colinlyguo and colinlyguo authored Sep 5, 2023
1 parent 25b956f commit 8e27052
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 11 deletions.
2 changes: 1 addition & 1 deletion common/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"runtime/debug"
)

var tag = "v4.2.21"
var tag = "v4.2.22"

var commit = func() string {
if info, ok := debug.ReadBuildInfo(); ok {
Expand Down
21 changes: 16 additions & 5 deletions rollup/internal/orm/l1_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,26 @@ func (o *L1Block) InsertL1Blocks(ctx context.Context, blocks []L1Block) error {
}

return o.db.Transaction(func(tx *gorm.DB) error {
var blockNumbers []uint64
for _, block := range blocks {
blockNumbers = append(blockNumbers, block.Number)
minBlockNumber := blocks[0].Number
for _, block := range blocks[1:] {
if block.Number < minBlockNumber {
minBlockNumber = block.Number
}
}

db := tx.WithContext(ctx)
db = db.Model(&L1Block{})
if err := db.Where("number IN (?)", blockNumbers).Delete(&L1Block{}).Error; err != nil {
return fmt.Errorf("L1Block.InsertL1Blocks error: soft deleting blocks failed, block numbers: %v, error: %w", blockNumbers, err)
db = db.Where("number >= ?", minBlockNumber)
result := db.Delete(&L1Block{})

if result.Error != nil {
return fmt.Errorf("L1Block.InsertL1Blocks error: soft deleting blocks failed, block numbers starting from: %v, error: %w", minBlockNumber, result.Error)
}

// If the number of deleted blocks exceeds the limit (input length + 64), treat it as an anomaly.
// Because reorg with >= 64 blocks is very unlikely to happen.
if result.RowsAffected >= int64(len(blocks)+64) {
return fmt.Errorf("L1Block.InsertL1Blocks error: too many blocks were deleted, count: %d", result.RowsAffected)
}

if err := db.Create(&blocks).Error; err != nil {
Expand Down
12 changes: 7 additions & 5 deletions rollup/internal/orm/orm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,20 +99,22 @@ func TestL1BlockOrm(t *testing.T) {
// mock blocks
block1 := L1Block{Number: 1, Hash: "hash1"}
block2 := L1Block{Number: 2, Hash: "hash2"}
block2AfterReorg := L1Block{Number: 2, Hash: "hash3"}
block3 := L1Block{Number: 3, Hash: "hash3"}
block2AfterReorg := L1Block{Number: 2, Hash: "hash2-reorg"}

err = l1BlockOrm.InsertL1Blocks(context.Background(), []L1Block{block1, block2})
err = l1BlockOrm.InsertL1Blocks(context.Background(), []L1Block{block1, block2, block3})
assert.NoError(t, err)

height, err := l1BlockOrm.GetLatestL1BlockHeight(context.Background())
assert.NoError(t, err)
assert.Equal(t, uint64(2), height)
assert.Equal(t, uint64(3), height)

blocks, err := l1BlockOrm.GetL1Blocks(context.Background(), map[string]interface{}{})
assert.NoError(t, err)
assert.Len(t, blocks, 2)
assert.Len(t, blocks, 3)
assert.Equal(t, "hash1", blocks[0].Hash)
assert.Equal(t, "hash2", blocks[1].Hash)
assert.Equal(t, "hash3", blocks[2].Hash)

// reorg handling: insert another block with same height and different hash
err = l1BlockOrm.InsertL1Blocks(context.Background(), []L1Block{block2AfterReorg})
Expand All @@ -122,7 +124,7 @@ func TestL1BlockOrm(t *testing.T) {
assert.NoError(t, err)
assert.Len(t, blocks, 2)
assert.Equal(t, "hash1", blocks[0].Hash)
assert.Equal(t, "hash3", blocks[1].Hash)
assert.Equal(t, "hash2-reorg", blocks[1].Hash)

err = l1BlockOrm.UpdateL1GasOracleStatusAndOracleTxHash(context.Background(), "hash1", types.GasOracleImported, "txhash1")
assert.NoError(t, err)
Expand Down

0 comments on commit 8e27052

Please sign in to comment.