Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,12 @@ pub enum ProduceBlockVerification {
pub struct PrePayloadAttributes {
pub proposer_index: u64,
pub prev_randao: Hash256,
/// The block number of the block being built upon (same block as fcU `headBlockHash`).
///
/// The parent block number is not part of the payload attributes sent to the EL, but *is*
/// sent to builders via SSE.
pub parent_block_number: u64,
/// The block root of the block being built upon (same block as fcU `headBlockHash`).
pub parent_beacon_block_root: Hash256,
}

Expand Down Expand Up @@ -4111,10 +4114,10 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let proposal_epoch = proposal_slot.epoch(T::EthSpec::slots_per_epoch());

let head_block_root = cached_head.head_block_root();
let parent_beacon_block_root = cached_head.parent_block_root();
let head_parent_block_root = cached_head.parent_block_root();

// The proposer head must be equal to the canonical head or its parent.
if proposer_head != head_block_root && proposer_head != parent_beacon_block_root {
if proposer_head != head_block_root && proposer_head != head_parent_block_root {
warn!(
self.log,
"Unable to compute payload attributes";
Expand Down Expand Up @@ -4193,7 +4196,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {

// Get the `prev_randao` and parent block number.
let head_block_number = cached_head.head_block_number()?;
let (prev_randao, parent_block_number) = if proposer_head == parent_beacon_block_root {
let (prev_randao, parent_block_number) = if proposer_head == head_parent_block_root {
(
cached_head.parent_random()?,
head_block_number.saturating_sub(1),
Expand All @@ -4206,7 +4209,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
proposer_index,
prev_randao,
parent_block_number,
parent_beacon_block_root,
parent_beacon_block_root: proposer_head,
}))
}

Expand Down Expand Up @@ -4589,8 +4592,13 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let prepare_payload_handle = match &state {
BeaconState::Base(_) | BeaconState::Altair(_) => None,
BeaconState::Merge(_) | BeaconState::Capella(_) | BeaconState::Deneb(_) => {
let prepare_payload_handle =
get_execution_payload(self.clone(), &state, proposer_index, builder_params)?;
let prepare_payload_handle = get_execution_payload(
self.clone(),
&state,
parent_root,
proposer_index,
builder_params,
)?;
Some(prepare_payload_handle)
}
};
Expand Down
7 changes: 4 additions & 3 deletions beacon_node/beacon_chain/src/execution_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ pub fn get_execution_payload<
>(
chain: Arc<BeaconChain<T>>,
state: &BeaconState<T::EthSpec>,
parent_block_root: Hash256,
proposer_index: u64,
builder_params: BuilderParams,
) -> Result<PreparePayloadHandle<T::EthSpec, Payload>, BlockProductionError> {
Expand All @@ -426,10 +427,10 @@ pub fn get_execution_payload<
&BeaconState::Base(_) | &BeaconState::Altair(_) => None,
};
let parent_beacon_block_root = match state {
&BeaconState::Deneb(_) => Some(state.latest_block_header().canonical_root()),
&BeaconState::Merge(_) | &BeaconState::Capella(_) => None,
BeaconState::Deneb(_) => Some(parent_block_root),
BeaconState::Merge(_) | BeaconState::Capella(_) => None,
// These shouldn't happen but they're here to make the pattern irrefutable
&BeaconState::Base(_) | &BeaconState::Altair(_) => None,
BeaconState::Base(_) | BeaconState::Altair(_) => None,
};

// Spawn a task to obtain the execution payload from the EL via a series of async calls. The
Expand Down
61 changes: 34 additions & 27 deletions beacon_node/beacon_chain/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -890,32 +890,10 @@ where
| SignedBeaconBlock::Altair(_)
| SignedBeaconBlock::Merge(_)
| SignedBeaconBlock::Capella(_) => (signed_block, None),
SignedBeaconBlock::Deneb(_) => {
if let Some(blobs) = maybe_blob_sidecars {
let signed_blobs: SignedSidecarList<E, BlobSidecar<E>> = Vec::from(blobs)
.into_iter()
.map(|blob| {
blob.sign(
&self.validator_keypairs[proposer_index].sk,
&state.fork(),
state.genesis_validators_root(),
&self.spec,
)
})
.collect::<Vec<_>>()
.into();
let mut guard = self.blob_signature_cache.write();
for blob in &signed_blobs {
guard.insert(
BlobSignatureKey::new(blob.message.block_root, blob.message.index),
blob.signature.clone(),
);
}
(signed_block, Some(signed_blobs))
} else {
(signed_block, None)
}
}
SignedBeaconBlock::Deneb(_) => (
signed_block,
maybe_blob_sidecars.map(|blobs| self.sign_blobs(blobs, &state, proposer_index)),
),
};

(block_contents, state)
Expand Down Expand Up @@ -1037,6 +1015,35 @@ where
)
}

/// Sign blobs, and cache their signatures.
pub fn sign_blobs(
&self,
blobs: BlobSidecarList<E>,
state: &BeaconState<E>,
proposer_index: usize,
) -> SignedSidecarList<E, BlobSidecar<E>> {
let signed_blobs: SignedSidecarList<E, BlobSidecar<E>> = Vec::from(blobs)
.into_iter()
.map(|blob| {
blob.sign(
&self.validator_keypairs[proposer_index].sk,
&state.fork(),
state.genesis_validators_root(),
&self.spec,
)
})
.collect::<Vec<_>>()
.into();
let mut guard = self.blob_signature_cache.write();
for blob in &signed_blobs {
guard.insert(
BlobSignatureKey::new(blob.message.block_root, blob.message.index),
blob.signature.clone(),
);
}
signed_blobs
}

/// Produces an "unaggregated" attestation for the given `slot` and `index` that attests to
/// `beacon_block_root`. The provided `state` should match the `block.state_root` for the
/// `block` identified by `beacon_block_root`.
Expand Down Expand Up @@ -1940,7 +1947,7 @@ where
)
.await?
.try_into()
.unwrap();
.expect("block blobs are available");
self.chain.recompute_head_at_current_slot().await;
Ok(block_hash)
}
Expand Down
Loading