Commit b20ca5db authored by Axel Kingsley's avatar Axel Kingsley Committed by GitHub

Handle ErrParentTo from PreviousDerivedFrom (#12833)

parent d627f118
...@@ -189,7 +189,8 @@ func (db *DB) PreviousDerivedFrom(derivedFrom eth.BlockID) (prevDerivedFrom type ...@@ -189,7 +189,8 @@ func (db *DB) PreviousDerivedFrom(derivedFrom eth.BlockID) (prevDerivedFrom type
if self.derivedFrom.Number == 0 { if self.derivedFrom.Number == 0 {
return types.BlockSeal{}, nil return types.BlockSeal{}, nil
} else { } else {
return types.BlockSeal{}, fmt.Errorf("cannot find previous derived before start of database: %s", derivedFrom) return types.BlockSeal{},
fmt.Errorf("cannot find previous derived before start of database: %s (%w)", derivedFrom, types.ErrPreviousToFirst)
} }
} }
prev, err := db.readAt(selfIndex - 1) prev, err := db.readAt(selfIndex - 1)
......
...@@ -154,7 +154,11 @@ func (db *ChainsDB) CrossDerivedFromBlockRef(chainID types.ChainID, derived eth. ...@@ -154,7 +154,11 @@ func (db *ChainsDB) CrossDerivedFromBlockRef(chainID types.ChainID, derived eth.
return eth.BlockRef{}, err return eth.BlockRef{}, err
} }
parent, err := xdb.PreviousDerivedFrom(res.ID()) parent, err := xdb.PreviousDerivedFrom(res.ID())
if err != nil { // if we are working with the first item in the database, PreviousDerivedFrom will return ErrPreviousToFirst
// in which case we can attach a zero parent to the cross-derived-from block, as the parent block is unknown
if errors.Is(err, types.ErrPreviousToFirst) {
return res.ForceWithParent(eth.BlockID{}), nil
} else if err != nil {
return eth.BlockRef{}, err return eth.BlockRef{}, err
} }
return res.MustWithParent(parent.ID()), nil return res.MustWithParent(parent.ID()), nil
...@@ -266,7 +270,11 @@ func (db *ChainsDB) CandidateCrossSafe(chain types.ChainID) (derivedFromScope, c ...@@ -266,7 +270,11 @@ func (db *ChainsDB) CandidateCrossSafe(chain types.ChainID) (derivedFromScope, c
candidateRef := candidate.MustWithParent(crossDerived.ID()) candidateRef := candidate.MustWithParent(crossDerived.ID())
parentDerivedFrom, err := lDB.PreviousDerivedFrom(candidateFrom.ID()) parentDerivedFrom, err := lDB.PreviousDerivedFrom(candidateFrom.ID())
if err != nil { // if we are working with the first item in the database, PreviousDerivedFrom will return ErrPreviousToFirst
// in which case we can attach a zero parent to the cross-derived-from block, as the parent block is unknown
if errors.Is(err, types.ErrPreviousToFirst) {
parentDerivedFrom = types.BlockSeal{}
} else if err != nil {
return eth.BlockRef{}, eth.BlockRef{}, fmt.Errorf("failed to find parent-block of derived-from %s: %w", candidateFrom, err) return eth.BlockRef{}, eth.BlockRef{}, fmt.Errorf("failed to find parent-block of derived-from %s: %w", candidateFrom, err)
} }
candidateFromRef := candidateFrom.MustWithParent(parentDerivedFrom.ID()) candidateFromRef := candidateFrom.MustWithParent(parentDerivedFrom.ID())
...@@ -275,12 +283,18 @@ func (db *ChainsDB) CandidateCrossSafe(chain types.ChainID) (derivedFromScope, c ...@@ -275,12 +283,18 @@ func (db *ChainsDB) CandidateCrossSafe(chain types.ChainID) (derivedFromScope, c
if candidateFrom.Number > crossDerivedFrom.Number+1 { if candidateFrom.Number > crossDerivedFrom.Number+1 {
// If we are not ready to process the candidate block, // If we are not ready to process the candidate block,
// then we need to stick to the current scope, so the caller can bump up from there. // then we need to stick to the current scope, so the caller can bump up from there.
var crossDerivedFromRef eth.BlockRef
parent, err := lDB.PreviousDerivedFrom(crossDerivedFrom.ID()) parent, err := lDB.PreviousDerivedFrom(crossDerivedFrom.ID())
if err != nil { // if we are working with the first item in the database, PreviousDerivedFrom will return ErrPreviousToFirst
return eth.BlockRef{}, eth.BlockRef{}, fmt.Errorf("failed to find parent-block of cross-derived-from %s: %w", // in which case we can attach a zero parent to the cross-derived-from block, as the parent block is unknown
crossDerivedFrom, err) if errors.Is(err, types.ErrPreviousToFirst) {
crossDerivedFromRef = crossDerivedFrom.ForceWithParent(eth.BlockID{})
} else if err != nil {
return eth.BlockRef{}, eth.BlockRef{},
fmt.Errorf("failed to find parent-block of cross-derived-from %s: %w", crossDerivedFrom, err)
} else {
crossDerivedFromRef = crossDerivedFrom.MustWithParent(parent.ID())
} }
crossDerivedFromRef := crossDerivedFrom.MustWithParent(parent.ID())
return crossDerivedFromRef, eth.BlockRef{}, return crossDerivedFromRef, eth.BlockRef{},
fmt.Errorf("candidate is from %s, while current scope is %s: %w", fmt.Errorf("candidate is from %s, while current scope is %s: %w",
candidateFrom, crossDerivedFrom, types.ErrOutOfScope) candidateFrom, crossDerivedFrom, types.ErrOutOfScope)
......
...@@ -20,6 +20,9 @@ var ( ...@@ -20,6 +20,9 @@ var (
// ErrOutOfScope is when data is accessed, but access is not allowed, because of a limited scope. // ErrOutOfScope is when data is accessed, but access is not allowed, because of a limited scope.
// E.g. when limiting scope to L2 blocks derived from a specific subset of the L1 chain. // E.g. when limiting scope to L2 blocks derived from a specific subset of the L1 chain.
ErrOutOfScope = errors.New("out of scope") ErrOutOfScope = errors.New("out of scope")
// ErrPreviousToFirst is when you try to get the previous block of the first block
// E.g. when calling PreviousDerivedFrom on the first L1 block in the DB.
ErrPreviousToFirst = errors.New("cannot get parent of first block in the database")
// ErrUnknownChain is when a chain is unknown, not in the dependency set. // ErrUnknownChain is when a chain is unknown, not in the dependency set.
ErrUnknownChain = errors.New("unknown chain") ErrUnknownChain = errors.New("unknown chain")
// ErrNoRPCSource happens when a sub-service needs an RPC data source, but is not configured with one. // ErrNoRPCSource happens when a sub-service needs an RPC data source, but is not configured with one.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment