Bump ssz_types to v0.12.2 (#8032)

https://github.com/sigp/lighthouse/issues/8012


  Replace all instances of `VariableList::from` and `FixedVector::from` to their `try_from` variants.

While I tried to use proper error handling in most cases, there were certain situations where adding an `expect` for situations where `try_from` can trivially never fail avoided adding a lot of extra complexity.


Co-Authored-By: Mac L <mjladson@pm.me>

Co-Authored-By: Michael Sproul <michaelsproul@users.noreply.github.com>

Co-Authored-By: Michael Sproul <michael@sigmaprime.io>
This commit is contained in:
Mac L
2025-10-28 08:01:09 +04:00
committed by GitHub
parent 5840004c36
commit f5809aff87
39 changed files with 758 additions and 465 deletions

View File

@@ -57,7 +57,7 @@ use state_processing::{
};
use std::borrow::Cow;
use strum::AsRefStr;
use tracing::debug;
use tracing::{debug, error};
use tree_hash::TreeHash;
use types::{
Attestation, AttestationData, AttestationRef, BeaconCommittee,
@@ -267,6 +267,14 @@ pub enum Error {
/// We were unable to process this attestation due to an internal error. It's unclear if the
/// attestation is valid.
BeaconChainError(Box<BeaconChainError>),
/// A critical error occurred while converting SSZ types.
/// This can only occur when a VariableList was not able to be constructed from a single
/// attestation.
///
/// ## Peer scoring
///
/// The peer has sent an invalid message.
SszTypesError(ssz_types::Error),
}
impl From<BeaconChainError> for Error {
@@ -275,6 +283,12 @@ impl From<BeaconChainError> for Error {
}
}
impl From<ssz_types::Error> for Error {
fn from(e: ssz_types::Error) -> Self {
Self::SszTypesError(e)
}
}
/// Used to avoid double-checking signatures.
#[derive(Copy, Clone)]
enum CheckAttestationSignature {
@@ -442,7 +456,18 @@ fn process_slash_info<T: BeaconChainTypes>(
.spec
.fork_name_at_slot::<T::EthSpec>(attestation.data.slot);
let indexed_attestation = attestation.to_indexed(fork_name);
let indexed_attestation = match attestation.to_indexed(fork_name) {
Ok(indexed) => indexed,
Err(e) => {
error!(
attestation_root = ?attestation.data.tree_hash_root(),
error = ?e,
"Unable to construct VariableList from a single attestation. \
This indicates a serious bug in SSZ handling"
);
return Error::SszTypesError(e);
}
};
(indexed_attestation, true, err)
}
SignatureNotCheckedIndexed(indexed, err) => (indexed, true, err),
@@ -932,7 +957,9 @@ impl<'a, T: BeaconChainTypes> IndexedUnaggregatedAttestation<'a, T> {
.spec
.fork_name_at_slot::<T::EthSpec>(attestation.data.slot);
let indexed_attestation = attestation.to_indexed(fork_name);
let indexed_attestation = attestation
.to_indexed(fork_name)
.map_err(|e| SignatureNotCheckedSingle(attestation, Error::SszTypesError(e)))?;
let validator_index = match Self::verify_middle_checks(attestation, chain) {
Ok(t) => t,

View File

@@ -5483,11 +5483,21 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings: proposer_slashings.into(),
attester_slashings: attester_slashings_base.into(),
attestations: attestations_base.into(),
deposits: deposits.into(),
voluntary_exits: voluntary_exits.into(),
proposer_slashings: proposer_slashings
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attester_slashings: attester_slashings_base
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attestations: attestations_base
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
deposits: deposits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
voluntary_exits: voluntary_exits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
_phantom: PhantomData,
},
}),
@@ -5504,11 +5514,21 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings: proposer_slashings.into(),
attester_slashings: attester_slashings_base.into(),
attestations: attestations_base.into(),
deposits: deposits.into(),
voluntary_exits: voluntary_exits.into(),
proposer_slashings: proposer_slashings
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attester_slashings: attester_slashings_base
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attestations: attestations_base
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
deposits: deposits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
voluntary_exits: voluntary_exits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
sync_aggregate: sync_aggregate
.ok_or(BlockProductionError::MissingSyncAggregate)?,
_phantom: PhantomData,
@@ -5531,11 +5551,21 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings: proposer_slashings.into(),
attester_slashings: attester_slashings_base.into(),
attestations: attestations_base.into(),
deposits: deposits.into(),
voluntary_exits: voluntary_exits.into(),
proposer_slashings: proposer_slashings
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attester_slashings: attester_slashings_base
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attestations: attestations_base
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
deposits: deposits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
voluntary_exits: voluntary_exits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
sync_aggregate: sync_aggregate
.ok_or(BlockProductionError::MissingSyncAggregate)?,
execution_payload: block_proposal_contents
@@ -5563,18 +5593,30 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings: proposer_slashings.into(),
attester_slashings: attester_slashings_base.into(),
attestations: attestations_base.into(),
deposits: deposits.into(),
voluntary_exits: voluntary_exits.into(),
proposer_slashings: proposer_slashings
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attester_slashings: attester_slashings_base
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attestations: attestations_base
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
deposits: deposits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
voluntary_exits: voluntary_exits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
sync_aggregate: sync_aggregate
.ok_or(BlockProductionError::MissingSyncAggregate)?,
execution_payload: block_proposal_contents
.to_payload()
.try_into()
.map_err(|_| BlockProductionError::InvalidPayloadFork)?,
bls_to_execution_changes: bls_to_execution_changes.into(),
bls_to_execution_changes: bls_to_execution_changes
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
},
}),
None,
@@ -5602,17 +5644,29 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings: proposer_slashings.into(),
attester_slashings: attester_slashings_base.into(),
attestations: attestations_base.into(),
deposits: deposits.into(),
voluntary_exits: voluntary_exits.into(),
proposer_slashings: proposer_slashings
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attester_slashings: attester_slashings_base
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attestations: attestations_base
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
deposits: deposits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
voluntary_exits: voluntary_exits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
sync_aggregate: sync_aggregate
.ok_or(BlockProductionError::MissingSyncAggregate)?,
execution_payload: payload
.try_into()
.map_err(|_| BlockProductionError::InvalidPayloadFork)?,
bls_to_execution_changes: bls_to_execution_changes.into(),
bls_to_execution_changes: bls_to_execution_changes
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
blob_kzg_commitments: kzg_commitments.ok_or(
BlockProductionError::MissingKzgCommitment(
"Kzg commitments missing from block contents".to_string(),
@@ -5645,17 +5699,29 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings: proposer_slashings.into(),
attester_slashings: attester_slashings_electra.into(),
attestations: attestations_electra.into(),
deposits: deposits.into(),
voluntary_exits: voluntary_exits.into(),
proposer_slashings: proposer_slashings
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attester_slashings: attester_slashings_electra
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attestations: attestations_electra
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
deposits: deposits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
voluntary_exits: voluntary_exits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
sync_aggregate: sync_aggregate
.ok_or(BlockProductionError::MissingSyncAggregate)?,
execution_payload: payload
.try_into()
.map_err(|_| BlockProductionError::InvalidPayloadFork)?,
bls_to_execution_changes: bls_to_execution_changes.into(),
bls_to_execution_changes: bls_to_execution_changes
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
blob_kzg_commitments: kzg_commitments
.ok_or(BlockProductionError::InvalidPayloadFork)?,
execution_requests: maybe_requests
@@ -5687,17 +5753,29 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings: proposer_slashings.into(),
attester_slashings: attester_slashings_electra.into(),
attestations: attestations_electra.into(),
deposits: deposits.into(),
voluntary_exits: voluntary_exits.into(),
proposer_slashings: proposer_slashings
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attester_slashings: attester_slashings_electra
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attestations: attestations_electra
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
deposits: deposits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
voluntary_exits: voluntary_exits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
sync_aggregate: sync_aggregate
.ok_or(BlockProductionError::MissingSyncAggregate)?,
execution_payload: payload
.try_into()
.map_err(|_| BlockProductionError::InvalidPayloadFork)?,
bls_to_execution_changes: bls_to_execution_changes.into(),
bls_to_execution_changes: bls_to_execution_changes
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
blob_kzg_commitments: kzg_commitments
.ok_or(BlockProductionError::InvalidPayloadFork)?,
execution_requests: maybe_requests
@@ -5729,17 +5807,29 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings: proposer_slashings.into(),
attester_slashings: attester_slashings_electra.into(),
attestations: attestations_electra.into(),
deposits: deposits.into(),
voluntary_exits: voluntary_exits.into(),
proposer_slashings: proposer_slashings
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attester_slashings: attester_slashings_electra
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
attestations: attestations_electra
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
deposits: deposits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
voluntary_exits: voluntary_exits
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
sync_aggregate: sync_aggregate
.ok_or(BlockProductionError::MissingSyncAggregate)?,
execution_payload: payload
.try_into()
.map_err(|_| BlockProductionError::InvalidPayloadFork)?,
bls_to_execution_changes: bls_to_execution_changes.into(),
bls_to_execution_changes: bls_to_execution_changes
.try_into()
.map_err(BlockProductionError::SszTypesError)?,
blob_kzg_commitments: kzg_commitments
.ok_or(BlockProductionError::InvalidPayloadFork)?,
execution_requests: maybe_requests

View File

@@ -868,16 +868,16 @@ mod test {
let state = harness.get_current_state();
let ((block, _blobs_opt), _state) = harness
.make_block_with_modifier(state, slot, |block| {
*block.body_mut().blob_kzg_commitments_mut().unwrap() = vec![].into();
*block.body_mut().blob_kzg_commitments_mut().unwrap() = vec![].try_into().unwrap();
})
.await;
let index = 0;
let column_sidecar = DataColumnSidecar::<E> {
index,
column: vec![].into(),
kzg_commitments: vec![].into(),
kzg_proofs: vec![].into(),
column: vec![].try_into().unwrap(),
kzg_commitments: vec![].try_into().unwrap(),
kzg_proofs: vec![].try_into().unwrap(),
signed_block_header: block.signed_block_header(),
kzg_commitments_inclusion_proof: block
.message()
@@ -914,7 +914,9 @@ mod test {
let ((block, _blobs_opt), _state) = harness
.make_block_with_modifier(state, slot, |block| {
*block.body_mut().blob_kzg_commitments_mut().unwrap() =
vec![preloaded_commitments_single[0]; blob_count].into();
vec![preloaded_commitments_single[0]; blob_count]
.try_into()
.unwrap();
})
.await;

View File

@@ -318,6 +318,7 @@ pub enum BlockProductionError {
KzgError(kzg::Error),
FailedToBuildBlobSidecars(String),
MissingExecutionRequests,
SszTypesError(ssz_types::Error),
}
easy_from_to!(BlockProcessingError, BlockProductionError);

View File

@@ -576,7 +576,7 @@ fn create_test_block_and_blobs(
.map(|(blob, proofs)| {
BlobAndProof::V2(BlobAndProofV2 {
blob,
proofs: proofs.to_vec().into(),
proofs: proofs.to_vec().try_into().unwrap(),
})
})
.collect()

View File

@@ -258,7 +258,8 @@ pub(crate) fn build_data_column_sidecars<E: EthSpec>(
.get(col)
.ok_or(format!("Missing blob cell at index {col}"))?;
let cell: Vec<u8> = cell.to_vec();
let cell = Cell::<E>::from(cell);
let cell =
Cell::<E>::try_from(cell).map_err(|e| format!("BytesPerCell exceeded: {e:?}"))?;
let proof = blob_cell_proofs
.get(col)
@@ -276,23 +277,27 @@ pub(crate) fn build_data_column_sidecars<E: EthSpec>(
}
}
let sidecars: Vec<Arc<DataColumnSidecar<E>>> = columns
let sidecars: Result<Vec<Arc<DataColumnSidecar<E>>>, String> = columns
.into_iter()
.zip(column_kzg_proofs)
.enumerate()
.map(|(index, (col, proofs))| {
Arc::new(DataColumnSidecar {
index: index as u64,
column: DataColumn::<E>::from(col),
kzg_commitments: kzg_commitments.clone(),
kzg_proofs: VariableList::from(proofs),
signed_block_header: signed_block_header.clone(),
kzg_commitments_inclusion_proof: kzg_commitments_inclusion_proof.clone(),
})
})
.map(
|(index, (col, proofs))| -> Result<Arc<DataColumnSidecar<E>>, String> {
Ok(Arc::new(DataColumnSidecar {
index: index as u64,
column: DataColumn::<E>::try_from(col)
.map_err(|e| format!("MaxBlobCommitmentsPerBlock exceeded: {e:?}"))?,
kzg_commitments: kzg_commitments.clone(),
kzg_proofs: VariableList::try_from(proofs)
.map_err(|e| format!("MaxBlobCommitmentsPerBlock exceeded: {e:?}"))?,
signed_block_header: signed_block_header.clone(),
kzg_commitments_inclusion_proof: kzg_commitments_inclusion_proof.clone(),
}))
},
)
.collect();
Ok(sidecars)
sidecars
}
/// Reconstruct blobs from a subset of data column sidecars (requires at least 50%).

View File

@@ -2324,7 +2324,7 @@ where
.collect::<Vec<_>>();
// Building a VarList from leaves
let deposit_data_list = VariableList::<_, U4294967296>::from(leaves.clone());
let deposit_data_list = VariableList::<_, U4294967296>::try_from(leaves.clone()).unwrap();
// Setting the deposit_root to be the tree_hash_root of the VarList
state.eth1_data_mut().deposit_root = deposit_data_list.tree_hash_root();
@@ -2348,7 +2348,7 @@ where
let deposits = datas
.into_par_iter()
.zip(proofs.into_par_iter())
.map(|(data, proof)| (data, proof.into()))
.map(|(data, proof)| (data, proof.try_into().unwrap()))
.map(|(data, proof)| Deposit { proof, data })
.collect::<Vec<_>>();