Commit 5b6bd794 authored by Joshua Gutow's avatar Joshua Gutow Committed by GitHub

op-node: Call FCU on new unsafe payload (#3418)

This calls a FCU to set the unsafe head of the L2 execution client
immediately after NewPayload is called on the execution client. This
means that the unsafe head in the node state matches the unsafe head
on the execution client.

This commit removes the FCU prior to the NewPayload call because
we assert that the unsafe block that we are inserting extends the
current unsafe head. As such, the L2 execution client is in a state
to accept the new block.
parent 0e6af08e
...@@ -217,6 +217,7 @@ func (eq *EngineQueue) tryNextUnsafePayload(ctx context.Context) error { ...@@ -217,6 +217,7 @@ func (eq *EngineQueue) tryNextUnsafePayload(ctx context.Context) error {
return nil return nil
} }
// Ensure that the unsafe payload builds upon the current unsafe head
// TODO: once we support snap-sync we can remove this condition, and handle the "SYNCING" status of the execution engine. // TODO: once we support snap-sync we can remove this condition, and handle the "SYNCING" status of the execution engine.
if first.ParentHash != eq.unsafeHead.Hash { if first.ParentHash != eq.unsafeHead.Hash {
if uint64(first.BlockNumber) == eq.unsafeHead.Number+1 { if uint64(first.BlockNumber) == eq.unsafeHead.Number+1 {
...@@ -233,12 +234,19 @@ func (eq *EngineQueue) tryNextUnsafePayload(ctx context.Context) error { ...@@ -233,12 +234,19 @@ func (eq *EngineQueue) tryNextUnsafePayload(ctx context.Context) error {
return nil return nil
} }
// Note: the parent hash does not have to equal the existing unsafe head, status, err := eq.engine.NewPayload(ctx, first)
// the unsafe part of the chain may reorg freely without resetting the derivation pipeline. if err != nil {
return NewTemporaryError(fmt.Errorf("failed to update insert payload: %w", err))
}
if status.Status != eth.ExecutionValid {
eq.unsafePayloads.Pop()
return NewTemporaryError(fmt.Errorf("cannot process unsafe payload: new - %v; parent: %v; err: %w",
first.ID(), first.ParentID(), eth.NewPayloadErr(first, status)))
}
// prepare for processing the unsafe payload // Mark the new payload as valid
fc := eth.ForkchoiceState{ fc := eth.ForkchoiceState{
HeadBlockHash: first.ParentHash, HeadBlockHash: first.BlockHash,
SafeBlockHash: eq.safeHead.Hash, // this should guarantee we do not reorg past the safe head SafeBlockHash: eq.safeHead.Hash, // this should guarantee we do not reorg past the safe head
FinalizedBlockHash: eq.finalized.Hash, FinalizedBlockHash: eq.finalized.Hash,
} }
...@@ -261,15 +269,7 @@ func (eq *EngineQueue) tryNextUnsafePayload(ctx context.Context) error { ...@@ -261,15 +269,7 @@ func (eq *EngineQueue) tryNextUnsafePayload(ctx context.Context) error {
return NewTemporaryError(fmt.Errorf("cannot prepare unsafe chain for new payload: new - %v; parent: %v; err: %w", return NewTemporaryError(fmt.Errorf("cannot prepare unsafe chain for new payload: new - %v; parent: %v; err: %w",
first.ID(), first.ParentID(), eth.ForkchoiceUpdateErr(fcRes.PayloadStatus))) first.ID(), first.ParentID(), eth.ForkchoiceUpdateErr(fcRes.PayloadStatus)))
} }
status, err := eq.engine.NewPayload(ctx, first)
if err != nil {
return NewTemporaryError(fmt.Errorf("failed to update insert payload: %w", err))
}
if status.Status != eth.ExecutionValid {
eq.unsafePayloads.Pop()
return NewTemporaryError(fmt.Errorf("cannot process unsafe payload: new - %v; parent: %v; err: %w",
first.ID(), first.ParentID(), eth.ForkchoiceUpdateErr(fcRes.PayloadStatus)))
}
eq.unsafeHead = ref eq.unsafeHead = ref
eq.unsafePayloads.Pop() eq.unsafePayloads.Pop()
eq.metrics.RecordL2Ref("l2_unsafe", ref) eq.metrics.RecordL2Ref("l2_unsafe", ref)
......
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