mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-14 10:22:38 +00:00
Gloas attestation verification (#8705)
https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/p2p-interface.md#attestation-subnets Implements attestation verification logic for Gloas and adds a few gloas related tests. Note that a few of these tests rely on gloas test harness block production which hasn't been built out yet. So for now those tests are ignored. Co-Authored-By: Eitan Seri- Levi <eserilev@gmail.com> Co-Authored-By: Eitan Seri-Levi <eserilev@ucsc.edu>
This commit is contained in:
@@ -61,8 +61,9 @@ use tracing::{debug, error};
|
||||
use tree_hash::TreeHash;
|
||||
use types::{
|
||||
Attestation, AttestationData, AttestationRef, BeaconCommittee,
|
||||
BeaconStateError::NoCommitteeFound, ChainSpec, CommitteeIndex, Epoch, EthSpec, Hash256,
|
||||
IndexedAttestation, SelectionProof, SignedAggregateAndProof, SingleAttestation, Slot, SubnetId,
|
||||
BeaconStateError::NoCommitteeFound, ChainSpec, CommitteeIndex, Epoch, EthSpec, ForkName,
|
||||
Hash256, IndexedAttestation, SelectionProof, SignedAggregateAndProof, SingleAttestation, Slot,
|
||||
SubnetId,
|
||||
};
|
||||
|
||||
pub use batch::{batch_verify_aggregated_attestations, batch_verify_unaggregated_attestations};
|
||||
@@ -160,6 +161,12 @@ pub enum Error {
|
||||
///
|
||||
/// The peer has sent an invalid message.
|
||||
CommitteeIndexNonZero(usize),
|
||||
/// The validator index is set to an invalid value after Gloas.
|
||||
///
|
||||
/// ## Peer scoring
|
||||
///
|
||||
/// The peer has sent an invalid message.
|
||||
CommitteeIndexInvalid,
|
||||
/// The `attestation.data.beacon_block_root` block is unknown.
|
||||
///
|
||||
/// ## Peer scoring
|
||||
@@ -550,8 +557,12 @@ impl<'a, T: BeaconChainTypes> IndexedAggregatedAttestation<'a, T> {
|
||||
}
|
||||
.tree_hash_root();
|
||||
|
||||
let fork_name = chain
|
||||
.spec
|
||||
.fork_name_at_slot::<T::EthSpec>(attestation.data().slot);
|
||||
|
||||
// [New in Electra:EIP7549]
|
||||
verify_committee_index(attestation)?;
|
||||
verify_committee_index(attestation, fork_name)?;
|
||||
|
||||
if chain
|
||||
.observed_attestations
|
||||
@@ -595,6 +606,17 @@ impl<'a, T: BeaconChainTypes> IndexedAggregatedAttestation<'a, T> {
|
||||
// attestation and do not delay consideration for later.
|
||||
let head_block = verify_head_block_is_known(chain, attestation.data(), None)?;
|
||||
|
||||
// [New in Gloas]: If the attested block is from the same slot as the attestation,
|
||||
// index must be 0.
|
||||
if fork_name.gloas_enabled()
|
||||
&& head_block.slot == attestation.data().slot
|
||||
&& attestation.data().index != 0
|
||||
{
|
||||
return Err(Error::CommitteeIndexNonZero(
|
||||
attestation.data().index as usize,
|
||||
));
|
||||
}
|
||||
|
||||
// Check the attestation target root is consistent with the head root.
|
||||
//
|
||||
// This check is not in the specification, however we guard against it since it opens us up
|
||||
@@ -871,7 +893,12 @@ impl<'a, T: BeaconChainTypes> IndexedUnaggregatedAttestation<'a, T> {
|
||||
let fork_name = chain
|
||||
.spec
|
||||
.fork_name_at_slot::<T::EthSpec>(attestation.data.slot);
|
||||
if fork_name.electra_enabled() {
|
||||
if fork_name.gloas_enabled() {
|
||||
// [New in Gloas]
|
||||
if attestation.data.index >= 2 {
|
||||
return Err(Error::CommitteeIndexInvalid);
|
||||
}
|
||||
} else if fork_name.electra_enabled() {
|
||||
// [New in Electra:EIP7549]
|
||||
if attestation.data.index != 0 {
|
||||
return Err(Error::CommitteeIndexNonZero(
|
||||
@@ -890,6 +917,17 @@ impl<'a, T: BeaconChainTypes> IndexedUnaggregatedAttestation<'a, T> {
|
||||
chain.config.import_max_skip_slots,
|
||||
)?;
|
||||
|
||||
// [New in Gloas]: If the attested block is from the same slot as the attestation,
|
||||
// index must be 0.
|
||||
if fork_name.gloas_enabled()
|
||||
&& head_block.slot == attestation.data.slot
|
||||
&& attestation.data.index != 0
|
||||
{
|
||||
return Err(Error::CommitteeIndexNonZero(
|
||||
attestation.data.index as usize,
|
||||
));
|
||||
}
|
||||
|
||||
// Check the attestation target root is consistent with the head root.
|
||||
verify_attestation_target_root::<T::EthSpec>(&head_block, &attestation.data)?;
|
||||
|
||||
@@ -1404,7 +1442,10 @@ pub fn verify_signed_aggregate_signatures<T: BeaconChainTypes>(
|
||||
|
||||
/// Verify that the `attestation` committee index is properly set for the attestation's fork.
|
||||
/// This function will only apply verification post-Electra.
|
||||
pub fn verify_committee_index<E: EthSpec>(attestation: AttestationRef<E>) -> Result<(), Error> {
|
||||
pub fn verify_committee_index<E: EthSpec>(
|
||||
attestation: AttestationRef<E>,
|
||||
fork_name: ForkName,
|
||||
) -> Result<(), Error> {
|
||||
if let Ok(committee_bits) = attestation.committee_bits() {
|
||||
// Check to ensure that the attestation is for a single committee.
|
||||
let num_committee_bits = get_committee_indices::<E>(committee_bits);
|
||||
@@ -1414,11 +1455,18 @@ pub fn verify_committee_index<E: EthSpec>(attestation: AttestationRef<E>) -> Res
|
||||
));
|
||||
}
|
||||
|
||||
// Ensure the attestation index is set to zero post Electra.
|
||||
if attestation.data().index != 0 {
|
||||
return Err(Error::CommitteeIndexNonZero(
|
||||
attestation.data().index as usize,
|
||||
));
|
||||
// Ensure the attestation index is valid for the fork.
|
||||
let index = attestation.data().index;
|
||||
if fork_name.gloas_enabled() {
|
||||
// [New in Gloas]: index must be < 2.
|
||||
if index >= 2 {
|
||||
return Err(Error::CommitteeIndexInvalid);
|
||||
}
|
||||
} else {
|
||||
// [New in Electra:EIP7549]: index must be 0.
|
||||
if index != 0 {
|
||||
return Err(Error::CommitteeIndexNonZero(index as usize));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user