mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
Optimise and refine SingleAttestation conversion (#6934)
Closes - https://github.com/sigp/lighthouse/issues/6805 - Use a new `WorkEvent::GossipAttestationToConvert` to handle the conversion from `SingleAttestation` to `Attestation` _on_ the beacon processor (prevents a Tokio thread being blocked). - Improve the error handling for single attestations. I think previously we had no ability to reprocess single attestations for unknown blocks -- we would just error. This seemed to be the case in both gossip processing and processing of `SingleAttestation`s from the HTTP API. - Move the `SingleAttestation -> Attestation` conversion function into `beacon_chain` so that it can return the `attestation_verification::Error` type, which has well-defined error handling and peer penalties. The now-unused variants of `types::Attestation::Error` have been removed.
This commit is contained in:
@@ -36,8 +36,8 @@
|
||||
//! attestations and there's no immediate cause for concern.
|
||||
use crate::task_spawner::{Priority, TaskSpawner};
|
||||
use beacon_chain::{
|
||||
validator_monitor::timestamp_now, AttestationError, BeaconChain, BeaconChainError,
|
||||
BeaconChainTypes,
|
||||
single_attestation::single_attestation_to_attestation, validator_monitor::timestamp_now,
|
||||
AttestationError, BeaconChain, BeaconChainError, BeaconChainTypes,
|
||||
};
|
||||
use beacon_processor::work_reprocessing_queue::{QueuedUnaggregate, ReprocessQueueMessage};
|
||||
use either::Either;
|
||||
@@ -183,10 +183,10 @@ fn convert_to_attestation<'a, T: BeaconChainTypes>(
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
attestation: &'a Either<Attestation<T::EthSpec>, SingleAttestation>,
|
||||
) -> Result<Cow<'a, Attestation<T::EthSpec>>, Error> {
|
||||
let a = match attestation {
|
||||
Either::Left(a) => Cow::Borrowed(a),
|
||||
Either::Right(single_attestation) => chain
|
||||
.with_committee_cache(
|
||||
match attestation {
|
||||
Either::Left(a) => Ok(Cow::Borrowed(a)),
|
||||
Either::Right(single_attestation) => {
|
||||
let conversion_result = chain.with_committee_cache(
|
||||
single_attestation.data.target.root,
|
||||
single_attestation
|
||||
.data
|
||||
@@ -197,24 +197,33 @@ fn convert_to_attestation<'a, T: BeaconChainTypes>(
|
||||
single_attestation.data.slot,
|
||||
single_attestation.committee_index,
|
||||
) else {
|
||||
return Err(BeaconChainError::AttestationError(
|
||||
types::AttestationError::NoCommitteeForSlotAndIndex {
|
||||
slot: single_attestation.data.slot,
|
||||
index: single_attestation.committee_index,
|
||||
},
|
||||
));
|
||||
return Ok(Err(AttestationError::NoCommitteeForSlotAndIndex {
|
||||
slot: single_attestation.data.slot,
|
||||
index: single_attestation.committee_index,
|
||||
}));
|
||||
};
|
||||
|
||||
let attestation =
|
||||
single_attestation.to_attestation::<T::EthSpec>(committee.committee)?;
|
||||
|
||||
Ok(Cow::Owned(attestation))
|
||||
Ok(single_attestation_to_attestation::<T::EthSpec>(
|
||||
single_attestation,
|
||||
committee.committee,
|
||||
)
|
||||
.map(Cow::Owned))
|
||||
},
|
||||
)
|
||||
.map_err(Error::FailedConversion)?,
|
||||
};
|
||||
|
||||
Ok(a)
|
||||
);
|
||||
match conversion_result {
|
||||
Ok(Ok(attestation)) => Ok(attestation),
|
||||
Ok(Err(e)) => Err(Error::Validation(e)),
|
||||
// Map the error returned by `with_committee_cache` for unknown blocks into the
|
||||
// `UnknownHeadBlock` error that is gracefully handled.
|
||||
Err(BeaconChainError::MissingBeaconBlock(beacon_block_root)) => {
|
||||
Err(Error::Validation(AttestationError::UnknownHeadBlock {
|
||||
beacon_block_root,
|
||||
}))
|
||||
}
|
||||
Err(e) => Err(Error::FailedConversion(e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn publish_attestations<T: BeaconChainTypes>(
|
||||
|
||||
Reference in New Issue
Block a user