@@ -116,6 +116,8 @@ const EARLY_ATTESTER_CACHE_HISTORIC_SLOTS: u64 = 4;
116116pub const INVALID_JUSTIFIED_PAYLOAD_SHUTDOWN_REASON : & str =
117117 "Justified block has an invalid execution payload." ;
118118
119+ const PAYLOAD_PREPARATION_LOOKAHEAD_FACTOR : u32 = 3 ;
120+
119121/// Defines the behaviour when a block/block-root for a skipped slot is requested.
120122pub enum WhenSlotSkipped {
121123 /// If the slot is a skip slot, return `None`.
@@ -3710,6 +3712,11 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
37103712 . clone ( )
37113713 . ok_or ( Error :: ExecutionLayerMissing ) ?;
37123714
3715+ if !execution_layer. has_proposers ( ) . await {
3716+ // Nothing to do if there are no proposers registered with the EL.
3717+ return Ok ( ( ) ) ;
3718+ }
3719+
37133720 let head = self . head_info ( ) ?;
37143721 let head_epoch = head. slot . epoch ( T :: EthSpec :: slots_per_epoch ( ) ) ;
37153722 let prepare_slot = self . slot ( ) ? + 1 ;
@@ -3769,8 +3776,25 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
37693776 self . log,
37703777 "Prepared beacon proposer" ;
37713778 "already_known" => already_known,
3779+ "prepare_slot" => prepare_slot,
37723780 "validator" => proposer. index,
37733781 ) ;
3782+
3783+ if let Some ( duration) = self . slot_clock . duration_to_slot ( prepare_slot) {
3784+ if duration
3785+ <= self . slot_clock . slot_duration ( )
3786+ / PAYLOAD_PREPARATION_LOOKAHEAD_FACTOR
3787+ {
3788+ // TODO(paul): update fork choice.
3789+ }
3790+ } else {
3791+ warn ! (
3792+ self . log,
3793+ "Delayed proposer preparation" ;
3794+ "prepare_slot" => prepare_slot,
3795+ "validator" => proposer. index,
3796+ ) ;
3797+ }
37743798 }
37753799 } else {
37763800 debug ! (
0 commit comments