mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-25 16:58:28 +00:00
Fix parent_beacon_block_root during proposer prep (#4703)
* Fix `parent_beacon_block_root` during prep/reorg * Fix another bug and add tests * Remove overzealous payload attributes check
This commit is contained in:
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
@@ -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),
|
||||
@@ -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,
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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> {
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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`.
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user