Add payload attestation validator duty (#9178)

Co-Authored-By: Eitan Seri-Levi <eserilev@ucsc.edu>

Co-Authored-By: Jimmy Chen <jchen.tc@gmail.com>
This commit is contained in:
Eitan Seri-Levi
2026-04-27 17:13:35 +02:00
committed by GitHub
parent 6ab48a76f0
commit 028b5a42a9
11 changed files with 618 additions and 16 deletions

View File

@@ -21,11 +21,12 @@ use tracing::{Instrument, debug, error, info, info_span, instrument, warn};
use types::{
AbstractExecPayload, Address, AggregateAndProof, Attestation, BeaconBlock, BlindedPayload,
ChainSpec, ContributionAndProof, Domain, Epoch, EthSpec, ExecutionPayloadEnvelope, Fork,
FullPayload, Graffiti, Hash256, SelectionProof, SignedAggregateAndProof, SignedBeaconBlock,
SignedContributionAndProof, SignedExecutionPayloadEnvelope, SignedRoot,
SignedValidatorRegistrationData, SignedVoluntaryExit, Slot, SyncAggregatorSelectionData,
SyncCommitteeContribution, SyncCommitteeMessage, SyncSelectionProof, SyncSubnetId,
ValidatorRegistrationData, VoluntaryExit, graffiti::GraffitiString,
FullPayload, Graffiti, Hash256, PayloadAttestationData, PayloadAttestationMessage,
SelectionProof, SignedAggregateAndProof, SignedBeaconBlock, SignedContributionAndProof,
SignedExecutionPayloadEnvelope, SignedRoot, SignedValidatorRegistrationData,
SignedVoluntaryExit, Slot, SyncAggregatorSelectionData, SyncCommitteeContribution,
SyncCommitteeMessage, SyncSelectionProof, SyncSubnetId, ValidatorRegistrationData,
VoluntaryExit, graffiti::GraffitiString,
};
use validator_store::{
AggregateToSign, AttestationToSign, ContributionToSign, DoppelgangerStatus,
@@ -1423,6 +1424,37 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore for LighthouseValidatorS
})
}
async fn sign_payload_attestation(
&self,
validator_pubkey: PublicKeyBytes,
data: PayloadAttestationData,
) -> Result<PayloadAttestationMessage, Error> {
let signing_context =
self.signing_context(Domain::PTCAttester, data.slot.epoch(E::slots_per_epoch()));
let validator_index = self
.validator_index(&validator_pubkey)
.ok_or(ValidatorStoreError::UnknownPubkey(validator_pubkey))?;
let signing_method = self.doppelganger_bypassed_signing_method(validator_pubkey)?;
let signature = signing_method
.get_signature::<E, FullPayload<E>>(
SignableMessage::PayloadAttestationData(&data),
signing_context,
&self.spec,
&self.task_executor,
)
.await
.map_err(Error::SpecificError)?;
Ok(PayloadAttestationMessage {
validator_index,
data,
signature,
})
}
/// Sign an `ExecutionPayloadEnvelope` for Gloas (local building).
/// The proposer acts as the builder and signs with the BeaconBuilder domain.
async fn sign_execution_payload_envelope(