SingleAttestation implementation (#6488)

* First pass

* Add restrictions to RuntimeVariableList api

* Use empty_uninitialized and fix warnings

* Fix some todos

* Merge branch 'unstable' into max-blobs-preset

* Fix take impl on RuntimeFixedList

* cleanup

* Fix test compilations

* Fix some more tests

* Fix test from unstable

* Merge branch 'unstable' into max-blobs-preset

* SingleAttestation

* Add post attestation v2 endpoint logic to attestation service

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into single_attestation

* Implement "Bugfix and more withdrawal tests"

* Implement "Add missed exit checks to consolidation processing"

* Implement "Update initial earliest_exit_epoch calculation"

* Implement "Limit consolidating balance by validator.effective_balance"

* Implement "Use 16-bit random value in validator filter"

* Implement "Do not change creds type on consolidation"

* some tests and fixed attestqtion calc

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into single_attestation

* Rename PendingPartialWithdraw index field to validator_index

* Skip slots to get test to pass and add TODO

* Implement "Synchronously check all transactions to have non-zero length"

* Merge remote-tracking branch 'origin/unstable' into max-blobs-preset

* Remove footgun function

* Minor simplifications

* Move from preset to config

* Fix typo

* Revert "Remove footgun function"

This reverts commit de01f923c7.

* Try fixing tests

* Implement "bump minimal preset MAX_BLOB_COMMITMENTS_PER_BLOCK and KZG_COMMITMENT_INCLUSION_PROOF_DEPTH"

* Thread through ChainSpec

* Fix release tests

* Move RuntimeFixedVector into module and rename

* Add test

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into single_attestation

* Added more test coverage, simplified Attestation conversion, and other minor refactors

* Removed unusued codepaths

* Fix failing test

* Implement "Remove post-altair `initialize_beacon_state_from_eth1` from specs"

* Update preset YAML

* Remove empty RuntimeVarList awefullness

* Make max_blobs_per_block a config parameter (#6329)

Squashed commit of the following:

commit 04b3743ec1
Author: Michael Sproul <michael@sigmaprime.io>
Date:   Mon Jan 6 17:36:58 2025 +1100

    Add test

commit 440e854199
Author: Michael Sproul <michael@sigmaprime.io>
Date:   Mon Jan 6 17:24:50 2025 +1100

    Move RuntimeFixedVector into module and rename

commit f66e179a40
Author: Michael Sproul <michael@sigmaprime.io>
Date:   Mon Jan 6 17:17:17 2025 +1100

    Fix release tests

commit e4bfe71cd1
Author: Michael Sproul <michael@sigmaprime.io>
Date:   Mon Jan 6 17:05:30 2025 +1100

    Thread through ChainSpec

commit 063b79c16a
Author: Michael Sproul <michael@sigmaprime.io>
Date:   Mon Jan 6 15:32:16 2025 +1100

    Try fixing tests

commit 88bedf09bc
Author: Michael Sproul <michael@sigmaprime.io>
Date:   Mon Jan 6 15:04:37 2025 +1100

    Revert "Remove footgun function"

    This reverts commit de01f923c7.

commit 32483d385b
Author: Michael Sproul <michael@sigmaprime.io>
Date:   Mon Jan 6 15:04:32 2025 +1100

    Fix typo

commit 2e86585b47
Author: Michael Sproul <michael@sigmaprime.io>
Date:   Mon Jan 6 15:04:15 2025 +1100

    Move from preset to config

commit 1095d60a40
Author: Michael Sproul <michael@sigmaprime.io>
Date:   Mon Jan 6 14:38:40 2025 +1100

    Minor simplifications

commit de01f923c7
Author: Michael Sproul <michael@sigmaprime.io>
Date:   Mon Jan 6 14:06:57 2025 +1100

    Remove footgun function

commit 0c2c8c4224
Merge: 21ecb58ff f51a292f7
Author: Michael Sproul <michael@sigmaprime.io>
Date:   Mon Jan 6 14:02:50 2025 +1100

    Merge remote-tracking branch 'origin/unstable' into max-blobs-preset

commit f51a292f77
Author: Daniel Knopik <107140945+dknopik@users.noreply.github.com>
Date:   Fri Jan 3 20:27:21 2025 +0100

    fully lint only explicitly to avoid unnecessary rebuilds (#6753)

    * fully lint only explicitly to avoid unnecessary rebuilds

commit 7e0cddef32
Author: Akihito Nakano <sora.akatsuki@gmail.com>
Date:   Tue Dec 24 10:38:56 2024 +0900

    Make sure we have fanout peers when publish (#6738)

    * Ensure that `fanout_peers` is always non-empty if it's `Some`

commit 21ecb58ff8
Merge: 2fcb2935e 9aefb5539
Author: Pawan Dhananjay <pawandhananjay@gmail.com>
Date:   Mon Oct 21 14:46:00 2024 -0700

    Merge branch 'unstable' into max-blobs-preset

commit 2fcb2935ec
Author: Pawan Dhananjay <pawandhananjay@gmail.com>
Date:   Fri Sep 6 18:28:31 2024 -0700

    Fix test from unstable

commit 12c6ef118a
Author: Pawan Dhananjay <pawandhananjay@gmail.com>
Date:   Wed Sep 4 16:16:36 2024 -0700

    Fix some more tests

commit d37733b846
Author: Pawan Dhananjay <pawandhananjay@gmail.com>
Date:   Wed Sep 4 12:47:36 2024 -0700

    Fix test compilations

commit 52bb581e07
Author: Pawan Dhananjay <pawandhananjay@gmail.com>
Date:   Tue Sep 3 18:38:19 2024 -0700

    cleanup

commit e71020e3e6
Author: Pawan Dhananjay <pawandhananjay@gmail.com>
Date:   Tue Sep 3 17:16:10 2024 -0700

    Fix take impl on RuntimeFixedList

commit 13f9bba647
Merge: 60100fc6b 4e675cf5d
Author: Pawan Dhananjay <pawandhananjay@gmail.com>
Date:   Tue Sep 3 16:08:59 2024 -0700

    Merge branch 'unstable' into max-blobs-preset

commit 60100fc6be
Author: Pawan Dhananjay <pawandhananjay@gmail.com>
Date:   Fri Aug 30 16:04:11 2024 -0700

    Fix some todos

commit a9cb329a22
Author: Pawan Dhananjay <pawandhananjay@gmail.com>
Date:   Fri Aug 30 15:54:00 2024 -0700

    Use empty_uninitialized and fix warnings

commit 4dc6e6515e
Author: Pawan Dhananjay <pawandhananjay@gmail.com>
Date:   Fri Aug 30 15:53:18 2024 -0700

    Add restrictions to RuntimeVariableList api

commit 25feedfde3
Author: Pawan Dhananjay <pawandhananjay@gmail.com>
Date:   Thu Aug 29 16:11:19 2024 -0700

    First pass

* Fix tests

* Implement max_blobs_per_block_electra

* Fix config issues

* Simplify BlobSidecarListFromRoot

* Disable PeerDAS tests

* Cleanup single attestation imports

* Fix some single attestation network plumbing

* Merge remote-tracking branch 'origin/unstable' into max-blobs-preset

* Bump quota to account for new target (6)

* Remove clone

* Fix issue from review

* Try to remove ugliness

* Merge branch 'unstable' into max-blobs-preset

* Merge remote-tracking branch 'origin/unstable' into electra-alpha10

* Merge commit '04b3743ec1e0b650269dd8e58b540c02430d1c0d' into electra-alpha10

* Merge remote-tracking branch 'pawan/max-blobs-preset' into electra-alpha10

* Update tests to v1.5.0-beta.0

* Merge remote-tracking branch 'origin/electra-alpha10' into single_attestation

* Fix some tests

* Cargo fmt

* lint

* fmt

* Resolve merge conflicts

* Merge branch 'electra-alpha10' of https://github.com/sigp/lighthouse into single_attestation

* lint

* Linting

* fmt

* Merge branch 'electra-alpha10' of https://github.com/sigp/lighthouse into single_attestation

* Fmt

* Fix test and add TODO

* Gracefully handle slashed proposers in fork choice tests

* Merge remote-tracking branch 'origin/unstable' into electra-alpha10

* Keep latest changes from max_blobs_per_block PR in codec.rs

* Revert a few more regressions and add a comment

* Merge branch 'electra-alpha10' of https://github.com/sigp/lighthouse into single_attestation

* Disable more DAS tests

* Improve validator monitor test a little

* Make test more robust

* Fix sync test that didn't understand blobs

* Fill out cropped comment

* Merge remote-tracking branch 'origin/electra-alpha10' into single_attestation

* Merge remote-tracking branch 'origin/unstable' into single_attestation

* Merge remote-tracking branch 'origin/unstable' into single_attestation

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into single_attestation

* publish_attestations should accept Either<Attestation,SingleAttestation>

* log an error when failing to convert to SingleAttestation

* Use Cow to avoid clone

* Avoid reconverting to SingleAttestation

* Tweak VC error message

* update comments

* update comments

* pass in single attestation as ref to subnetid calculation method

* Improved API, new error variants and other minor tweaks

* Fix single_attestation event topic boilerplate

* fix sse event failure

* Add single_attestation event topic test coverage
This commit is contained in:
Eitan Seri-Levi
2025-01-17 01:27:08 +07:00
committed by GitHub
parent 669932aa67
commit 06329ec2d1
22 changed files with 831 additions and 104 deletions

View File

@@ -12,8 +12,8 @@ use test_random_derive::TestRandom;
use tree_hash_derive::TreeHash;
use super::{
AggregateSignature, AttestationData, BitList, ChainSpec, Domain, EthSpec, Fork, SecretKey,
Signature, SignedRoot,
AggregateSignature, AttestationData, BitList, ChainSpec, CommitteeIndex, Domain, EthSpec, Fork,
SecretKey, Signature, SignedRoot,
};
#[derive(Debug, PartialEq)]
@@ -24,6 +24,10 @@ pub enum Error {
IncorrectStateVariant,
InvalidCommitteeLength,
InvalidCommitteeIndex,
AttesterNotInCommittee(usize),
InvalidCommittee,
MissingCommittee,
NoCommitteeForSlotAndIndex { slot: Slot, index: CommitteeIndex },
}
impl From<ssz_types::Error> for Error {
@@ -231,6 +235,16 @@ impl<E: EthSpec> Attestation<E> {
Attestation::Electra(att) => att.aggregation_bits.get(index),
}
}
pub fn to_single_attestation_with_attester_index(
&self,
attester_index: usize,
) -> Result<SingleAttestation, Error> {
match self {
Self::Base(_) => Err(Error::IncorrectStateVariant),
Self::Electra(attn) => attn.to_single_attestation_with_attester_index(attester_index),
}
}
}
impl<E: EthSpec> AttestationRef<'_, E> {
@@ -287,6 +301,14 @@ impl<E: EthSpec> AttestationElectra<E> {
self.get_committee_indices().first().cloned()
}
pub fn get_aggregation_bits(&self) -> Vec<u64> {
self.aggregation_bits
.iter()
.enumerate()
.filter_map(|(index, bit)| if bit { Some(index as u64) } else { None })
.collect()
}
pub fn get_committee_indices(&self) -> Vec<u64> {
self.committee_bits
.iter()
@@ -350,6 +372,22 @@ impl<E: EthSpec> AttestationElectra<E> {
Ok(())
}
}
pub fn to_single_attestation_with_attester_index(
&self,
attester_index: usize,
) -> Result<SingleAttestation, Error> {
let Some(committee_index) = self.committee_index() else {
return Err(Error::InvalidCommitteeIndex);
};
Ok(SingleAttestation {
committee_index: committee_index as usize,
attester_index,
data: self.data.clone(),
signature: self.signature.clone(),
})
}
}
impl<E: EthSpec> AttestationBase<E> {
@@ -527,6 +565,58 @@ impl<E: EthSpec> ForkVersionDeserialize for Vec<Attestation<E>> {
}
}
#[derive(
Debug,
Clone,
Serialize,
Deserialize,
Decode,
Encode,
TestRandom,
Derivative,
arbitrary::Arbitrary,
TreeHash,
PartialEq,
)]
pub struct SingleAttestation {
pub committee_index: usize,
pub attester_index: usize,
pub data: AttestationData,
pub signature: AggregateSignature,
}
impl SingleAttestation {
pub fn to_attestation<E: EthSpec>(&self, committee: &[usize]) -> Result<Attestation<E>, Error> {
let aggregation_bit = committee
.iter()
.enumerate()
.find_map(|(i, &validator_index)| {
if self.attester_index == validator_index {
return Some(i);
}
None
})
.ok_or(Error::AttesterNotInCommittee(self.attester_index))?;
let mut committee_bits: BitVector<E::MaxCommitteesPerSlot> = BitVector::default();
committee_bits
.set(self.committee_index, true)
.map_err(|_| Error::InvalidCommitteeIndex)?;
let mut aggregation_bits =
BitList::with_capacity(committee.len()).map_err(|_| Error::InvalidCommitteeLength)?;
aggregation_bits.set(aggregation_bit, true)?;
Ok(Attestation::Electra(AttestationElectra {
aggregation_bits,
committee_bits,
data: self.data.clone(),
signature: self.signature.clone(),
}))
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -118,7 +118,7 @@ pub use crate::aggregate_and_proof::{
};
pub use crate::attestation::{
Attestation, AttestationBase, AttestationElectra, AttestationRef, AttestationRefMut,
Error as AttestationError,
Error as AttestationError, SingleAttestation,
};
pub use crate::attestation_data::AttestationData;
pub use crate::attestation_duty::AttestationDuty;

View File

@@ -1,4 +1,5 @@
//! Identifies each shard by an integer identifier.
use crate::SingleAttestation;
use crate::{AttestationRef, ChainSpec, CommitteeIndex, EthSpec, Slot};
use alloy_primitives::{bytes::Buf, U256};
use safe_arith::{ArithError, SafeArith};
@@ -57,6 +58,21 @@ impl SubnetId {
)
}
/// Compute the subnet for an attestation where each slot in the
/// attestation epoch contains `committee_count_per_slot` committees.
pub fn compute_subnet_for_single_attestation<E: EthSpec>(
attestation: &SingleAttestation,
committee_count_per_slot: u64,
spec: &ChainSpec,
) -> Result<SubnetId, ArithError> {
Self::compute_subnet::<E>(
attestation.data.slot,
attestation.committee_index as u64,
committee_count_per_slot,
spec,
)
}
/// Compute the subnet for an attestation with `attestation.data.slot == slot` and
/// `attestation.data.index == committee_index` where each slot in the attestation epoch
/// contains `committee_count_at_slot` committees.