@@ -47,10 +47,7 @@ use proto_array::Block as ProtoBlock;
4747use slog:: debug;
4848use slot_clock:: SlotClock ;
4949use state_processing:: {
50- common:: {
51- attesting_indices_base,
52- attesting_indices_electra:: { self , get_committee_indices} ,
53- } ,
50+ common:: { attesting_indices_base, attesting_indices_electra} ,
5451 per_block_processing:: errors:: { AttestationValidationError , BlockOperationError } ,
5552 signature_sets:: {
5653 indexed_attestation_signature_set_from_pubkeys,
@@ -61,8 +58,9 @@ use std::borrow::Cow;
6158use strum:: AsRefStr ;
6259use tree_hash:: TreeHash ;
6360use types:: {
64- Attestation , AttestationRef , BeaconCommittee , ChainSpec , CommitteeIndex , Epoch , EthSpec ,
65- ForkName , Hash256 , IndexedAttestation , SelectionProof , SignedAggregateAndProof , Slot , SubnetId ,
61+ Attestation , AttestationRef , BeaconCommittee , BeaconStateError :: NoCommitteeFound , ChainSpec ,
62+ CommitteeIndex , Epoch , EthSpec , ForkName , Hash256 , IndexedAttestation , SelectionProof ,
63+ SignedAggregateAndProof , Slot , SubnetId ,
6664} ;
6765
6866pub use batch:: { batch_verify_aggregated_attestations, batch_verify_unaggregated_attestations} ;
@@ -572,37 +570,59 @@ impl<'a, T: BeaconChainTypes> IndexedAggregatedAttestation<'a, T> {
572570
573571 // Committees must be sorted by ascending index order 0..committees_per_slot
574572 let get_indexed_attestation_with_committee =
575- |( committee, _) : ( BeaconCommittee , CommitteesPerSlot ) | {
576- // Note: this clones the signature which is known to be a relatively slow operation.
577- //
578- // Future optimizations should remove this clone.
579- let selection_proof =
580- SelectionProof :: from ( signed_aggregate. message ( ) . selection_proof ( ) . clone ( ) ) ;
581-
582- let committee = committees
583- . get ( index as usize )
584- . ok_or ( Error :: NoCommitteeForSlotAndIndex { slot, index } ) ?;
585-
586- if !SelectionProof :: from ( selection_proof)
587- . is_aggregator ( committee. committee . len ( ) , & chain. spec )
588- . map_err ( |e| Error :: BeaconChainError ( e. into ( ) ) ) ?
589- {
590- return Err ( Error :: InvalidSelectionProof { aggregator_index } ) ;
591- }
592-
593- // Ensure the aggregator is a member of the committee for which it is aggregating.
594- if !committee. committee . contains ( & ( aggregator_index as usize ) ) {
595- return Err ( Error :: AggregatorNotInCommittee { aggregator_index } ) ;
573+ |( committees, _) : ( Vec < BeaconCommittee > , CommitteesPerSlot ) | {
574+ match attestation {
575+ AttestationRef :: Base ( att) => {
576+ let committee = committees
577+ . iter ( )
578+ . filter ( |& committee| committee. index == att. data . index )
579+ . at_most_one ( )
580+ . map_err ( |_| Error :: NoCommitteeForSlotAndIndex {
581+ slot : att. data . slot ,
582+ index : att. data . index ,
583+ } ) ?;
584+
585+ if let Some ( committee) = committee {
586+ // Note: this clones the signature which is known to be a relatively slow operation.
587+ //
588+ // Future optimizations should remove this clone.
589+ let selection_proof = SelectionProof :: from (
590+ signed_aggregate. message ( ) . selection_proof ( ) . clone ( ) ,
591+ ) ;
592+
593+ if !selection_proof
594+ . is_aggregator ( committee. committee . len ( ) , & chain. spec )
595+ . map_err ( |e| Error :: BeaconChainError ( e. into ( ) ) ) ?
596+ {
597+ return Err ( Error :: InvalidSelectionProof { aggregator_index } ) ;
598+ }
599+
600+ // Ensure the aggregator is a member of the committee for which it is aggregating.
601+ if !committee. committee . contains ( & ( aggregator_index as usize ) ) {
602+ return Err ( Error :: AggregatorNotInCommittee { aggregator_index } ) ;
603+ }
604+ attesting_indices_base:: get_indexed_attestation (
605+ committee. committee ,
606+ att,
607+ )
608+ . map_err ( |e| BeaconChainError :: from ( e) . into ( ) )
609+ } else {
610+ Err ( Error :: NoCommitteeForSlotAndIndex {
611+ slot : att. data . slot ,
612+ index : att. data . index ,
613+ } )
614+ }
615+ }
616+ AttestationRef :: Electra ( att) => {
617+ attesting_indices_electra:: get_indexed_attestation ( & committees, att)
618+ . map_err ( |e| BeaconChainError :: from ( e) . into ( ) )
619+ }
596620 }
597-
598- get_indexed_attestation ( committee. committee , attestation)
599- . map_err ( |e| BeaconChainError :: from ( e) . into ( ) )
600621 } ;
601622
602- let attestation = signed_aggregate. message ( ) . aggregate ( ) ;
603623 let indexed_attestation = match map_attestation_committees (
604624 chain,
605- attestation,
625+ & attestation,
606626 get_indexed_attestation_with_committee,
607627 ) {
608628 Ok ( indexed_attestation) => indexed_attestation,
@@ -1310,13 +1330,49 @@ pub fn obtain_indexed_attestation_and_committees_per_slot<T: BeaconChainTypes>(
13101330 chain : & BeaconChain < T > ,
13111331 attestation : AttestationRef < T :: EthSpec > ,
13121332) -> Result < ( IndexedAttestation < T :: EthSpec > , CommitteesPerSlot ) , Error > {
1313- map_attestation_committee ( chain, attestation, |( committee, committees_per_slot) | {
1314- get_indexed_attestation ( committee. committee , attestation)
1315- . map ( |attestation| ( attestation, committees_per_slot) )
1316- . map_err ( Error :: Invalid )
1333+ map_attestation_committees ( chain, & attestation, |( committees, committees_per_slot) | {
1334+ match attestation {
1335+ AttestationRef :: Base ( att) => {
1336+ let committee = committees
1337+ . iter ( )
1338+ . filter ( |& committee| committee. index == att. data . index )
1339+ . at_most_one ( )
1340+ . map_err ( |_| Error :: NoCommitteeForSlotAndIndex {
1341+ slot : att. data . slot ,
1342+ index : att. data . index ,
1343+ } ) ?;
1344+
1345+ if let Some ( committee) = committee {
1346+ attesting_indices_base:: get_indexed_attestation ( committee. committee , att)
1347+ . map ( |attestation| ( attestation, committees_per_slot) )
1348+ . map_err ( Error :: Invalid )
1349+ } else {
1350+ Err ( Error :: NoCommitteeForSlotAndIndex {
1351+ slot : att. data . slot ,
1352+ index : att. data . index ,
1353+ } )
1354+ }
1355+ }
1356+ AttestationRef :: Electra ( att) => {
1357+ attesting_indices_electra:: get_indexed_attestation ( & committees, att)
1358+ . map ( |attestation| ( attestation, committees_per_slot) )
1359+ . map_err ( |e| {
1360+ if e == BlockOperationError :: BeaconStateError ( NoCommitteeFound ) {
1361+ Error :: NoCommitteeForSlotAndIndex {
1362+ slot : att. data . slot ,
1363+ index : att. committee_index ( ) ,
1364+ }
1365+ } else {
1366+ Error :: Invalid ( e)
1367+ }
1368+ } )
1369+ }
1370+ }
13171371 } )
13181372}
13191373
1374+ // TODO(electra) update comments below to reflect logic changes
1375+ // i.e. this now runs the map_fn on a list of committees for the slot of the provided attestation
13201376/// Runs the `map_fn` with the committee and committee count per slot for the given `attestation`.
13211377///
13221378/// This function exists in this odd "map" pattern because efficiently obtaining the committees for
@@ -1326,11 +1382,9 @@ pub fn obtain_indexed_attestation_and_committees_per_slot<T: BeaconChainTypes>(
13261382///
13271383/// If the committees for an `attestation`'s slot aren't found in the `shuffling_cache`, we will read a state
13281384/// from disk and then update the `shuffling_cache`.
1329- ///
1330- /// Committees are sorted by ascending index order 0..committees_per_slot
13311385fn map_attestation_committees < T , F , R > (
13321386 chain : & BeaconChain < T > ,
1333- attestation : AttestationRef < T :: EthSpec > ,
1387+ attestation : & AttestationRef < T :: EthSpec > ,
13341388 map_fn : F ,
13351389) -> Result < R , Error >
13361390where
@@ -1361,12 +1415,12 @@ where
13611415 let committees_per_slot = committee_cache. committees_per_slot ( ) ;
13621416
13631417 Ok ( committee_cache
1364- . get_beacon_committee ( attestation. data ( ) . slot , attestation . data ( ) . index )
1365- . map ( |committee | map_fn ( ( committee , committees_per_slot) ) )
1366- . unwrap_or_else ( || {
1418+ . get_beacon_committees_at_slot ( attestation. data ( ) . slot )
1419+ . map ( |committees | map_fn ( ( committees , committees_per_slot) ) )
1420+ . unwrap_or_else ( |_ | {
13671421 Err ( Error :: NoCommitteeForSlotAndIndex {
13681422 slot : attestation. data ( ) . slot ,
1369- index : attestation. data ( ) . index ,
1423+ index : attestation. committee_index ( ) ,
13701424 } )
13711425 } ) )
13721426 } )
0 commit comments