Skip to content

Commit

Permalink
Interop: Add error case for parent of start of database (ethereum-opt…
Browse files Browse the repository at this point in the history
…imism#12818)

* Add error case for parent of start of database

* fix unit tests
  • Loading branch information
axelKingsley authored and GrapeBaBa committed Nov 13, 2024
1 parent 035430c commit 7eb2481
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 21 deletions.
9 changes: 7 additions & 2 deletions op-supervisor/supervisor/backend/db/fromda/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,13 @@ func (db *DB) PreviousDerivedFrom(derivedFrom eth.BlockID) (prevDerivedFrom type
if self.derivedFrom.ID() != derivedFrom {
return types.BlockSeal{}, fmt.Errorf("found %s, but expected %s: %w", self.derivedFrom, derivedFrom, types.ErrConflict)
}
if selfIndex == 0 { // genesis block has a zeroed block as parent block
return types.BlockSeal{}, nil
if selfIndex == 0 {
// genesis block has a zeroed block as parent block
if self.derivedFrom.Number == 0 {
return types.BlockSeal{}, nil
} else {
return types.BlockSeal{}, fmt.Errorf("cannot find previous derived before start of database: %s", derivedFrom)
}
}
prev, err := db.readAt(selfIndex - 1)
if err != nil {
Expand Down
59 changes: 40 additions & 19 deletions op-supervisor/supervisor/backend/db/fromda/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,74 +131,95 @@ func toRef(seal types.BlockSeal, parentHash common.Hash) eth.BlockRef {
}

func TestSingleEntryDB(t *testing.T) {
expectedDerivedFrom := mockL1(1)
expectedDerivedFrom := mockL1(0)
expectedDerived := mockL2(2)
runDBTest(t,
func(t *testing.T, db *DB, m *stubMetrics) {
require.NoError(t, db.AddDerived(toRef(expectedDerivedFrom, mockL1(0).Hash), toRef(expectedDerived, mockL2(0).Hash)))
},
func(t *testing.T, db *DB, m *stubMetrics) {
derivedFrom, derived, err := db.Latest()
// First
derivedFrom, derived, err := db.First()
require.NoError(t, err)
require.Equal(t, expectedDerivedFrom, derivedFrom)
require.Equal(t, expectedDerived, derived)

derivedFrom, derived, err = db.First()
// Latest
derivedFrom, derived, err = db.Latest()
require.NoError(t, err)
require.Equal(t, expectedDerivedFrom, derivedFrom)
require.Equal(t, expectedDerived, derived)

// FirstAfter Latest
_, _, err = db.FirstAfter(derivedFrom.ID(), derived.ID())
require.ErrorIs(t, err, types.ErrFuture)

// LastDerivedAt
derived, err = db.LastDerivedAt(expectedDerivedFrom.ID())
require.NoError(t, err)
require.Equal(t, expectedDerived, derived)

// LastDerivedAt with a non-existent block
_, err = db.LastDerivedAt(eth.BlockID{Hash: common.Hash{0xaa}, Number: expectedDerivedFrom.Number})
require.ErrorIs(t, err, types.ErrConflict)

// No block known, yet, after the given block pair
_, _, err = db.FirstAfter(derivedFrom.ID(), derived.ID())
require.ErrorIs(t, err, types.ErrFuture)

// Not after a non-existent block pair
// FirstAfter with a non-existent block (derived and derivedFrom)
_, _, err = db.FirstAfter(eth.BlockID{Hash: common.Hash{0xaa}, Number: expectedDerivedFrom.Number}, expectedDerived.ID())
require.ErrorIs(t, err, types.ErrConflict)
_, _, err = db.FirstAfter(expectedDerivedFrom.ID(), eth.BlockID{Hash: common.Hash{0xaa}, Number: expectedDerived.Number})
require.ErrorIs(t, err, types.ErrConflict)

// DerivedFrom
derivedFrom, err = db.DerivedFrom(expectedDerived.ID())
require.NoError(t, err)
require.Equal(t, expectedDerivedFrom, derivedFrom)

// DerivedFrom with a non-existent block
_, err = db.DerivedFrom(eth.BlockID{Hash: common.Hash{0xbb}, Number: expectedDerived.Number})
require.ErrorIs(t, err, types.ErrConflict)

// PreviousDerived
prev, err := db.PreviousDerived(expectedDerived.ID())
require.NoError(t, err)
require.Equal(t, types.BlockSeal{}, prev, "zeroed seal before first entry")

_, _, err = db.NextDerived(expectedDerived.ID())
require.ErrorIs(t, err, types.ErrFuture)

// if 1 was the first inserted entry, then we skipped 0
_, _, err = db.NextDerived(mockL2(0).ID())
require.ErrorIs(t, err, types.ErrSkipped)

// PreviousDerivedFrom
prev, err = db.PreviousDerivedFrom(expectedDerivedFrom.ID())
require.NoError(t, err)
require.Equal(t, types.BlockSeal{}, prev, "zeroed seal before first entry")

_, err = db.NextDerivedFrom(expectedDerivedFrom.ID())
// NextDerived
_, _, err = db.NextDerived(expectedDerived.ID())
require.ErrorIs(t, err, types.ErrFuture)

// if 1 was the first inserted entry, then we skipped 0
_, err = db.NextDerivedFrom(mockL1(0).ID())
require.ErrorIs(t, err, types.ErrSkipped)
// NextDerivedFrom
_, err = db.NextDerivedFrom(expectedDerivedFrom.ID())
require.ErrorIs(t, err, types.ErrFuture)

// FirstAfter
_, _, err = db.FirstAfter(expectedDerivedFrom.ID(), expectedDerived.ID())
require.ErrorIs(t, err, types.ErrFuture)
})
}

func TestGap(t *testing.T) {
// mockL1 starts at block 1 to produce a gap
expectedDerivedFrom := mockL1(1)
// mockL2 starts at block 2 to produce a gap
expectedDerived := mockL2(2)
runDBTest(t,
func(t *testing.T, db *DB, m *stubMetrics) {
require.NoError(t, db.AddDerived(toRef(expectedDerivedFrom, mockL1(0).Hash), toRef(expectedDerived, mockL2(0).Hash)))
},
func(t *testing.T, db *DB, m *stubMetrics) {
_, _, err := db.NextDerived(mockL2(0).ID())
require.ErrorIs(t, err, types.ErrSkipped)

_, err = db.NextDerivedFrom(mockL1(0).ID())
require.ErrorIs(t, err, types.ErrSkipped)
})
}

func TestThreeEntryDB(t *testing.T) {
l1Block0 := mockL1(0)
l1Block1 := mockL1(1)
Expand Down

0 comments on commit 7eb2481

Please sign in to comment.