Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interop: Add error case for parent of start of database #12818

Merged
merged 2 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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