Skip to content

Commit

Permalink
Handle first L1 Parent Ref in CandidateCrossSafe (#12830)
Browse files Browse the repository at this point in the history
  • Loading branch information
axelKingsley authored Nov 5, 2024
1 parent 8565b8f commit 39e6e6f
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 12 deletions.
2 changes: 1 addition & 1 deletion op-supervisor/supervisor/backend/cross/safe_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func CrossSafeUpdate(ctx context.Context, logger log.Logger, chainID types.Chain
if err != nil {
return fmt.Errorf("cannot find parent-block of cross-safe: %w", err)
}
crossSafeRef := currentCrossSafe.WithParent(parent.ID())
crossSafeRef := currentCrossSafe.MustWithParent(parent.ID())
logger.Debug("Bumping cross-safe scope", "scope", newScope, "crossSafe", crossSafeRef)
if err := d.UpdateCrossSafe(chainID, newScope, crossSafeRef); err != nil {
return fmt.Errorf("failed to update cross-safe head with L1 scope increment to %s and repeat of L2 block %s: %w", candidateScope, crossSafeRef, err)
Expand Down
2 changes: 1 addition & 1 deletion op-supervisor/supervisor/backend/cross/safe_update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func TestCrossSafeUpdate(t *testing.T) {
require.NoError(t, err)
require.Equal(t, chainID, updatingChain)
require.Equal(t, newScope, updatingCandidateScope)
crossSafeRef := currentCrossSafe.WithParent(parent.ID())
crossSafeRef := currentCrossSafe.MustWithParent(parent.ID())
require.Equal(t, crossSafeRef, updatingCandidate)
})
t.Run("NextDerivedFrom returns error", func(t *testing.T) {
Expand Down
23 changes: 15 additions & 8 deletions op-supervisor/supervisor/backend/db/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ func (db *ChainsDB) CrossDerivedFromBlockRef(chainID types.ChainID, derived eth.
if err != nil {
return eth.BlockRef{}, err
}
return res.WithParent(parent.ID()), nil
return res.MustWithParent(parent.ID()), nil
}

// Check calls the underlying logDB to determine if the given log entry exists at the given location.
Expand Down Expand Up @@ -238,9 +238,16 @@ func (db *ChainsDB) CandidateCrossSafe(chain types.ChainID) (derivedFromScope, c
if err != nil {
return eth.BlockRef{}, eth.BlockRef{}, fmt.Errorf("failed to find first local-safe block: %w", err)
}
// First block has no parent
return derivedFrom.WithParent(eth.BlockID{}),
derived.WithParent(eth.BlockID{}), nil
// the first derivedFrom (L1 block) is unlikely to be the genesis block,
derivedFromRef, err := derivedFrom.WithParent(eth.BlockID{})
if err != nil {
// if the first derivedFrom isn't the genesis block, just warn and continue anyway
db.logger.Warn("First DerivedFrom is not genesis block")
derivedFromRef = derivedFrom.ForceWithParent(eth.BlockID{})
}
// the first derived must be the genesis block, panic otherwise
derivedRef := derived.MustWithParent(derivedFrom.ID())
return derivedFromRef, derivedRef, nil
}
return eth.BlockRef{}, eth.BlockRef{}, err
}
Expand All @@ -256,13 +263,13 @@ func (db *ChainsDB) CandidateCrossSafe(chain types.ChainID) (derivedFromScope, c
return eth.BlockRef{}, eth.BlockRef{}, err
}

candidateRef := candidate.WithParent(crossDerived.ID())
candidateRef := candidate.MustWithParent(crossDerived.ID())

parentDerivedFrom, err := lDB.PreviousDerivedFrom(candidateFrom.ID())
if err != nil {
return eth.BlockRef{}, eth.BlockRef{}, fmt.Errorf("failed to find parent-block of derived-from %s: %w", candidateFrom, err)
}
candidateFromRef := candidateFrom.WithParent(parentDerivedFrom.ID())
candidateFromRef := candidateFrom.MustWithParent(parentDerivedFrom.ID())

// Allow increment of DA by 1, if we know the floor (due to local safety) is 1 ahead of the current cross-safe L1 scope.
if candidateFrom.Number > crossDerivedFrom.Number+1 {
Expand All @@ -273,7 +280,7 @@ func (db *ChainsDB) CandidateCrossSafe(chain types.ChainID) (derivedFromScope, c
return eth.BlockRef{}, eth.BlockRef{}, fmt.Errorf("failed to find parent-block of cross-derived-from %s: %w",
crossDerivedFrom, err)
}
crossDerivedFromRef := crossDerivedFrom.WithParent(parent.ID())
crossDerivedFromRef := crossDerivedFrom.MustWithParent(parent.ID())
return crossDerivedFromRef, eth.BlockRef{},
fmt.Errorf("candidate is from %s, while current scope is %s: %w",
candidateFrom, crossDerivedFrom, types.ErrOutOfScope)
Expand Down Expand Up @@ -306,7 +313,7 @@ func (db *ChainsDB) NextDerivedFrom(chain types.ChainID, derivedFrom eth.BlockID
if err != nil {
return eth.BlockRef{}, err
}
return v.WithParent(derivedFrom), nil
return v.MustWithParent(derivedFrom), nil
}

// Safest returns the strongest safety level that can be guaranteed for the given log entry.
Expand Down
21 changes: 19 additions & 2 deletions op-supervisor/supervisor/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,12 +240,29 @@ func (s BlockSeal) ID() eth.BlockID {
return eth.BlockID{Hash: s.Hash, Number: s.Number}
}

func (s BlockSeal) WithParent(parent eth.BlockID) eth.BlockRef {
func (s BlockSeal) MustWithParent(parent eth.BlockID) eth.BlockRef {
ref, err := s.WithParent(parent)
if err != nil {
panic(err)
}
return ref
}

func (s BlockSeal) WithParent(parent eth.BlockID) (eth.BlockRef, error) {
// prevent parent attachment if the parent is not the previous block,
// and the block is not the genesis block
if s.Number != parent.Number+1 && s.Number != 0 {
panic(fmt.Errorf("invalid parent block %s to combine with %s", parent, s))
return eth.BlockRef{}, fmt.Errorf("invalid parent block %s to combine with %s", parent, s)
}
return eth.BlockRef{
Hash: s.Hash,
Number: s.Number,
ParentHash: parent.Hash,
Time: s.Timestamp,
}, nil
}

func (s BlockSeal) ForceWithParent(parent eth.BlockID) eth.BlockRef {
return eth.BlockRef{
Hash: s.Hash,
Number: s.Number,
Expand Down

0 comments on commit 39e6e6f

Please sign in to comment.