Skip to content

Commit 8fb610c

Browse files
committed
Tidy
1 parent 7e008cb commit 8fb610c

1 file changed

Lines changed: 123 additions & 81 deletions

File tree

beacon_node/beacon_chain/src/beacon_chain.rs

Lines changed: 123 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -3704,14 +3704,27 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
37043704
Ok(())
37053705
}
37063706

3707+
/// Determines the beacon proposer for the next slot. If that proposer is registered in the
3708+
/// `execution_layer`, provide the `execution_layer` with the necessary information to produce
3709+
/// `PayloadAttributes` for future calls to fork choice.
3710+
///
3711+
/// The `PayloadAttributes` are used by the EL to give it a look-ahead for preparing an optimal
3712+
/// set of transactions for a new `ExecutionPayload`.
3713+
///
3714+
/// This function will result in a call to `forkchoiceUpdated` on the EL if:
3715+
///
3716+
/// 1. We're in the tail-end of the slot (as defined by PAYLOAD_PREPARATION_LOOKAHEAD_FACTOR)
3717+
/// 2. The head block is one slot (or less) behind the prepare slot (e.g., we're preparing for
3718+
/// the next slot and the block at the current slot is already known).
37073719
pub async fn prepare_beacon_proposer(&self) -> Result<(), Error> {
37083720
let execution_layer = self
37093721
.execution_layer
37103722
.clone()
37113723
.ok_or(Error::ExecutionLayerMissing)?;
37123724

3725+
// Nothing to do if there are no proposers registered with the EL, exit early to avoid
3726+
// wasting cycles.
37133727
if !execution_layer.has_proposers().await {
3714-
// Nothing to do if there are no proposers registered with the EL.
37153728
return Ok(());
37163729
}
37173730

@@ -3721,105 +3734,134 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
37213734
let prepare_slot = current_slot + 1;
37223735
let prepare_epoch = prepare_slot.epoch(T::EthSpec::slots_per_epoch());
37233736

3737+
// Ensure that the shuffling decision root is correct relative to the epoch we wish to
3738+
// query.
37243739
let shuffling_decision_root = if head_epoch == prepare_epoch {
37253740
head.proposer_shuffling_decision_root
37263741
} else {
37273742
head.block_root
37283743
};
37293744

3730-
let proposer_opt = self
3745+
// Read the proposer from the proposer cache.
3746+
let proposer = if let Some(proposer) = self
37313747
.beacon_proposer_cache
37323748
.lock()
3733-
.get_slot::<T::EthSpec>(shuffling_decision_root, prepare_slot);
3749+
.get_slot::<T::EthSpec>(shuffling_decision_root, prepare_slot)
3750+
{
3751+
proposer
3752+
} else {
3753+
debug!(
3754+
self.log,
3755+
"No proposers for preparation";
3756+
"prepare_slot" => prepare_slot,
3757+
);
3758+
// Nothing more to do.
3759+
return Ok(());
3760+
};
37343761

3735-
if let Some(proposer) = proposer_opt {
3736-
if execution_layer
3737-
.has_proposer_preparation_data(proposer.index as u64)
3738-
.await
3739-
{
3740-
let suggested_fee_recipient = execution_layer
3741-
.get_suggested_fee_recipient(proposer.index as u64)
3742-
.await;
3743-
3744-
let timestamp = self
3745-
.slot_clock
3746-
.start_of(prepare_slot)
3747-
.ok_or(Error::InvalidSlot(prepare_slot))?
3748-
.as_secs();
3749-
3750-
let payload_attributes = PayloadAttributes {
3751-
timestamp,
3752-
random: head.random,
3753-
suggested_fee_recipient,
3754-
};
3762+
// If the execution layer doesn't have any proposer data for this validator then we assume
3763+
// it's not connected to this BN and no action is required.
3764+
if !execution_layer
3765+
.has_proposer_preparation_data(proposer.index as u64)
3766+
.await
3767+
{
3768+
return Ok(());
3769+
}
37553770

3756-
debug!(
3757-
self.log,
3758-
"Preparing beacon proposer";
3759-
"payload_attributes" => ?payload_attributes,
3760-
"head_root" => ?head.block_root,
3761-
"prepare_slot" => prepare_slot,
3762-
"validator" => proposer.index,
3763-
);
3771+
let payload_attributes = PayloadAttributes {
3772+
timestamp: self
3773+
.slot_clock
3774+
.start_of(prepare_slot)
3775+
.ok_or(Error::InvalidSlot(prepare_slot))?
3776+
.as_secs(),
3777+
random: head.random,
3778+
suggested_fee_recipient: execution_layer
3779+
.get_suggested_fee_recipient(proposer.index as u64)
3780+
.await,
3781+
};
37643782

3765-
let already_known = execution_layer
3766-
.insert_proposer(
3767-
prepare_slot,
3768-
head.block_root,
3769-
proposer.index as u64,
3770-
payload_attributes,
3771-
)
3772-
.await;
3783+
debug!(
3784+
self.log,
3785+
"Preparing beacon proposer";
3786+
"payload_attributes" => ?payload_attributes,
3787+
"head_root" => ?head.block_root,
3788+
"prepare_slot" => prepare_slot,
3789+
"validator" => proposer.index,
3790+
);
3791+
3792+
let already_known = execution_layer
3793+
.insert_proposer(
3794+
prepare_slot,
3795+
head.block_root,
3796+
proposer.index as u64,
3797+
payload_attributes,
3798+
)
3799+
.await;
3800+
// Only push a log to the user if this is the first time we've seen this proposer for this
3801+
// slot.
3802+
if !already_known {
3803+
info!(
3804+
self.log,
3805+
"Prepared beacon proposer";
3806+
"already_known" => already_known,
3807+
"prepare_slot" => prepare_slot,
3808+
"validator" => proposer.index,
3809+
);
3810+
}
37733811

3774-
if !already_known {
3775-
info!(
3812+
// If the head block has has execution enabled, then it might be a good idea to push
3813+
// a `forkchoiceUpdated` message to the EL to provide the payload attributes.
3814+
//
3815+
// There is no payload preparation for the transition block (i.e., the first block
3816+
// with execution enabled in some chain).
3817+
if let Some(head_block_hash) = head.execution_payload_block_hash {
3818+
// `SlotClock::duration_to_slot` will return `None` when we are past the start
3819+
// of `prepare_slot`. Don't bother sending a `forkchoiceUpdated` in that case,
3820+
// it's too late.
3821+
if let Some(till_prepare_slot) = self.slot_clock.duration_to_slot(prepare_slot) {
3822+
// If either of the following are true, send a fork-choice update message to the
3823+
// EL:
3824+
//
3825+
// 1. We're in the tail-end of the slot (as defined by
3826+
// PAYLOAD_PREPARATION_LOOKAHEAD_FACTOR)
3827+
// 2. The head block is one slot (or less) behind the prepare slot (e.g., we're
3828+
// preparing for the next slot and the block at the current slot is already
3829+
// known).
3830+
if till_prepare_slot
3831+
<= self.slot_clock.slot_duration() / PAYLOAD_PREPARATION_LOOKAHEAD_FACTOR
3832+
|| head.slot + 1 >= prepare_slot
3833+
{
3834+
debug!(
37763835
self.log,
3777-
"Prepared beacon proposer";
3778-
"already_known" => already_known,
3779-
"prepare_slot" => prepare_slot,
3780-
"validator" => proposer.index,
3836+
"Pushing update to prepare proposer";
3837+
"till_prepare_slot" => ?till_prepare_slot,
3838+
"prepare_slot" => prepare_slot
37813839
);
37823840

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-
if let Some(head_block_hash) = head.execution_payload_block_hash {
3789-
let finalized_root = head.finalized_checkpoint.root;
3790-
let finalized_hash = self
3791-
.fork_choice
3792-
.read()
3793-
.get_block(&finalized_root)
3794-
.ok_or(Error::FinalizedBlockMissingFromForkChoice(
3795-
finalized_root,
3796-
))?
3797-
.execution_status
3798-
.block_hash()
3799-
.unwrap_or_else(ExecutionBlockHash::zero);
3800-
3801-
self.update_execution_engine_forkchoice_blocking(
3802-
finalized_hash,
3803-
head.block_root,
3804-
head_block_hash,
3805-
current_slot,
3806-
)?;
3807-
}
3808-
}
3809-
} else {
3810-
warn!(
3811-
self.log,
3812-
"Delayed proposer preparation";
3813-
"prepare_slot" => prepare_slot,
3814-
"validator" => proposer.index,
3815-
);
3816-
}
3841+
let finalized_root = head.finalized_checkpoint.root;
3842+
let finalized_hash = self
3843+
.fork_choice
3844+
.read()
3845+
.get_block(&finalized_root)
3846+
.ok_or(Error::FinalizedBlockMissingFromForkChoice(finalized_root))?
3847+
.execution_status
3848+
.block_hash()
3849+
.unwrap_or_else(ExecutionBlockHash::zero);
3850+
3851+
self.update_execution_engine_forkchoice_blocking(
3852+
finalized_hash,
3853+
head.block_root,
3854+
head_block_hash,
3855+
current_slot,
3856+
)?;
38173857
}
38183858
} else {
3819-
debug!(
3859+
// This scenario might occur on an overloaded/under-resourced node.
3860+
warn!(
38203861
self.log,
3821-
"No proposers for preparation";
3862+
"Delayed proposer preparation";
38223863
"prepare_slot" => prepare_slot,
3864+
"validator" => proposer.index,
38233865
);
38243866
}
38253867
}

0 commit comments

Comments
 (0)