@@ -467,6 +467,72 @@ proc addBackfillBlock*(
467467
468468 ok ()
469469
470+ proc addHeadExecutionPayload * (
471+ dag: ChainDAGRef ,
472+ signedBlock: gloas.SignedBeaconBlock ,
473+ signedEnvelope: gloas.SignedExecutionPayloadEnvelope ,
474+ ): Result [BlockRef , VerifierError ] =
475+ # # Try adding the execution payload envelope to the head block, which should
476+ # # usually be invoked after the call of addHeadBlockWithParent()
477+ # #
478+ # # First check that the block and envelope are matched with the DAG block.
479+ # # Then verify that it passes the state transition function.
480+
481+ template envelopeBlockRoot (): auto =
482+ signedEnvelope.message.beacon_block_root
483+
484+ logScope:
485+ blockRoot = shortLog (envelopeBlockRoot ())
486+ builderIdx = signedEnvelope.message.builder_index
487+ slot = signedEnvelope.message.slot
488+ signature = shortLog (signedEnvelope.signature)
489+
490+ # Quick check between the received block and envelope.
491+ template bid (): auto =
492+ signedBlock.message.body.signed_execution_payload_bid.message
493+ if not (
494+ signedBlock.message.slot == signedEnvelope.message.slot and
495+ signedBlock.root == envelopeBlockRoot () and
496+ bid.builder_index == signedEnvelope.message.builder_index and
497+ bid.block_hash == signedEnvelope.message.payload.block_hash
498+ ):
499+ info " Envelope mismatches with this block"
500+ return err (VerifierError .Invalid )
501+
502+ # Check with the DAG head.
503+ let blck = dag.head
504+ if not (
505+ blck.root () == envelopeBlockRoot () and
506+ blck.slot () == signedEnvelope.message.slot
507+ ):
508+ debug " Envelope is not for the current head"
509+ return err (VerifierError .Invalid )
510+
511+ var cache: StateCache
512+ const consensusFork = typeof (signedBlock).kind
513+
514+ # Load state cache for state transition function.
515+ loadStateCache (dag, cache, blck.bid,
516+ getStateField (dag.clearanceState, slot).epoch ())
517+
518+ # Verify with state transition function.
519+ process_execution_payload (
520+ dag.cfg,
521+ dag.clearanceState.forky (consensusFork),
522+ signedEnvelope,
523+ func (_: deneb.ExecutionPayload ): bool = true ,
524+ cache,
525+ ).isOkOr:
526+ assign (dag.clearanceState, dag.headState)
527+ info " Envelope transition failed" , msg = error
528+ return err (VerifierError .Invalid )
529+
530+ # Put the envelope into db and update optimistic status for the block.
531+ dag.db.putExecutionPayloadEnvelope (signedEnvelope)
532+ blck.markExecutionValid (true )
533+
534+ ok (blck)
535+
470536proc verifyBlockSignatures * (
471537 verifier: var BatchVerifier ,
472538 fork: Fork ,
0 commit comments