diff --git a/common/eth2/src/types.rs b/common/eth2/src/types.rs index 59374f629d..d258b6a23d 100644 --- a/common/eth2/src/types.rs +++ b/common/eth2/src/types.rs @@ -948,6 +948,13 @@ pub struct PeerCount { pub disconnecting: u64, } +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct BeaconCommitteeSelection { + #[serde(with = "serde_utils::quoted_u64")] + pub validator_index: u64, + pub slot: Slot, + pub selection_proof: Signature, +} // --------- Server Sent Event Types ----------- #[derive(PartialEq, Debug, Serialize, Deserialize, Clone)] diff --git a/validator_client/validator_services/src/duties_service.rs b/validator_client/validator_services/src/duties_service.rs index 187eb4feb5..f9bbd4897d 100644 --- a/validator_client/validator_services/src/duties_service.rs +++ b/validator_client/validator_services/src/duties_service.rs @@ -129,24 +129,39 @@ async fn make_selection_proof( duty: &AttesterData, validator_store: &ValidatorStore, spec: &ChainSpec, + distributed: bool, + beacon_nodes: &Arc>, ) -> Result, Error> { - let selection_proof = validator_store - .produce_selection_proof(duty.pubkey, duty.slot) - .await - .map_err(Error::FailedToProduceSelectionProof)?; + if distributed { + // call the middleware for the endpoint /eth/v1/validator/beacon_committee_subscriptions + beacon_nodes + .first_success(|beacon_node| async move { + beacon_node + .post_validator_beacon_committee_subscriptions() + .await + }) + .await + .map_err(|e| Error::FailedToProduceSelectionProof(e.to_string())) + .map(|_| None) + } else { + let selection_proof = validator_store + .produce_selection_proof(duty.pubkey, duty.slot) + .await + .map_err(Error::FailedToProduceSelectionProof)?; - selection_proof - .is_aggregator(duty.committee_length as usize, spec) - .map_err(Error::InvalidModulo) - .map(|is_aggregator| { - if is_aggregator { - Some(selection_proof) - } else { - // Don't bother storing the selection proof if the validator isn't an - // aggregator, we won't need it. - None - } - }) + selection_proof + .is_aggregator(duty.committee_length as usize, spec) + .map_err(Error::InvalidModulo) + .map(|is_aggregator| { + if is_aggregator { + Some(selection_proof) + } else { + // Don't bother storing the selection proof if the validator isn't an + // aggregator, we won't need it. + None + } + }) + } } impl DutyAndProof { @@ -1101,6 +1116,8 @@ async fn fill_in_selection_proofs( &duty, &duties_service.validator_store, &duties_service.spec, + duties_service.distributed, + &duties_service.beacon_nodes, ) .await?; Ok((duty, opt_selection_proof))