Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
348 changes: 333 additions & 15 deletions common/eth2/src/lib.rs

Large diffs are not rendered by default.

69 changes: 69 additions & 0 deletions common/eth2/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1724,6 +1724,41 @@ pub struct ProduceBlockV3Metadata {
pub consensus_block_value: Uint256,
}

/// Metadata about a `ExecutionPayloadEnvelope` response which is returned in the headers.
#[derive(Debug, Deserialize, Serialize)]
pub struct ExecutionPayloadEnvelopeMetadata {
// The consensus version is serialized & deserialized by `ForkVersionedResponse`.
#[serde(
skip_serializing,
skip_deserializing,
default = "dummy_consensus_version"
)]
pub consensus_version: ForkName,
}

/// Response from the `/eth/v4/validator/blocks/{slot}` endpoint.
///
/// V4 is specific to post-Gloas forks and always returns a BeaconBlock directly.
/// No blinded/unblinded concept exists in Gloas.
pub type ProduceBlockV4Response<E> = BeaconBlock<E>;

pub type JsonProduceBlockV4Response<E> =
ForkVersionedResponse<ProduceBlockV4Response<E>, ProduceBlockV4Metadata>;

/// Metadata about a `ProduceBlockV4Response` which is returned in the body & headers.
#[derive(Debug, Deserialize, Serialize)]
pub struct ProduceBlockV4Metadata {
// The consensus version is serialized & deserialized by `ForkVersionedResponse`.
#[serde(
skip_serializing,
skip_deserializing,
default = "dummy_consensus_version"
)]
pub consensus_version: ForkName,
#[serde(with = "serde_utils::u256_dec")]
pub consensus_block_value: Uint256,
}

impl<E: EthSpec> FullBlockContents<E> {
pub fn new(block: BeaconBlock<E>, blob_data: Option<(KzgProofs<E>, BlobsList<E>)>) -> Self {
match blob_data {
Expand Down Expand Up @@ -1880,6 +1915,40 @@ impl TryFrom<&HeaderMap> for ProduceBlockV3Metadata {
}
}

impl TryFrom<&HeaderMap> for ExecutionPayloadEnvelopeMetadata {
type Error = String;

fn try_from(headers: &HeaderMap) -> Result<Self, Self::Error> {
let consensus_version = parse_required_header(headers, CONSENSUS_VERSION_HEADER, |s| {
s.parse::<ForkName>()
.map_err(|e| format!("invalid {CONSENSUS_VERSION_HEADER}: {e:?}"))
})?;

Ok(ExecutionPayloadEnvelopeMetadata { consensus_version })
}
}

impl TryFrom<&HeaderMap> for ProduceBlockV4Metadata {
type Error = String;

fn try_from(headers: &HeaderMap) -> Result<Self, Self::Error> {
let consensus_version = parse_required_header(headers, CONSENSUS_VERSION_HEADER, |s| {
s.parse::<ForkName>()
.map_err(|e| format!("invalid {CONSENSUS_VERSION_HEADER}: {e:?}"))
})?;
let consensus_block_value =
parse_required_header(headers, CONSENSUS_BLOCK_VALUE_HEADER, |s| {
Uint256::from_str_radix(s, 10)
.map_err(|e| format!("invalid {CONSENSUS_BLOCK_VALUE_HEADER}: {e:?}"))
})?;

Ok(ProduceBlockV4Metadata {
consensus_version,
consensus_block_value,
})
}
}

/// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBlockContents`].
#[derive(Clone, Debug, PartialEq, Encode, Serialize)]
#[serde(untagged)]
Expand Down
1 change: 0 additions & 1 deletion consensus/types/src/execution_payload_envelope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ pub struct ExecutionPayloadEnvelope<E: EthSpec> {

impl<E: EthSpec> SignedRoot for ExecutionPayloadEnvelope<E> {}


#[cfg(test)]
mod tests {
use super::*;
Expand Down
1 change: 1 addition & 0 deletions validator_client/beacon_node_fallback/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,7 @@ mod tests {
spec.clone(),
);

// TODO(EIP-7732): discuss whether we should replace this with a new `mock_post_beacon__blocks_v2_ssz` for post-gloas blocks since no blinded blocks anymore.
mock_beacon_node_1.mock_post_beacon_blinded_blocks_v2_ssz(Duration::from_secs(0));
mock_beacon_node_2.mock_post_beacon_blinded_blocks_v2_ssz(Duration::from_secs(0));

Expand Down
51 changes: 45 additions & 6 deletions validator_client/lighthouse_validator_store/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ use task_executor::TaskExecutor;
use tracing::{error, info, warn};
use types::{
AbstractExecPayload, Address, AggregateAndProof, Attestation, BeaconBlock, BlindedPayload,
ChainSpec, ContributionAndProof, Domain, Epoch, EthSpec, Fork, Graffiti, Hash256,
PublicKeyBytes, SelectionProof, Signature, SignedAggregateAndProof, SignedBeaconBlock,
SignedContributionAndProof, SignedRoot, SignedValidatorRegistrationData, SignedVoluntaryExit,
Slot, SyncAggregatorSelectionData, SyncCommitteeContribution, SyncCommitteeMessage,
SyncSelectionProof, SyncSubnetId, ValidatorRegistrationData, VoluntaryExit,
graffiti::GraffitiString,
ChainSpec, ContributionAndProof, Domain, Epoch, EthSpec, ExecutionPayloadEnvelope, Fork,
Graffiti, Hash256, PublicKeyBytes, SelectionProof, Signature, SignedAggregateAndProof,
SignedBeaconBlock, SignedContributionAndProof, SignedExecutionPayloadEnvelope, SignedRoot,
SignedValidatorRegistrationData, SignedVoluntaryExit, Slot, SyncAggregatorSelectionData,
SyncCommitteeContribution, SyncCommitteeMessage, SyncSelectionProof, SyncSubnetId,
ValidatorRegistrationData, VoluntaryExit, graffiti::GraffitiString,
};
use validator_store::{
DoppelgangerStatus, Error as ValidatorStoreError, ProposalData, SignedBlock, UnsignedBlock,
Expand Down Expand Up @@ -745,6 +745,45 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore for LighthouseValidatorS
}
}

async fn sign_block_gloas(
&self,
validator_pubkey: PublicKeyBytes,
block: &BeaconBlock<E>,
current_slot: Slot,
) -> Result<Arc<SignedBeaconBlock<E>>, Error> {
let beacon_block = block.clone();
self.sign_abstract_block(validator_pubkey, beacon_block, current_slot)
.await
.map(|signed_block| Arc::new(signed_block))
}

async fn sign_execution_payload_envelope(
&self,
validator_pubkey: PublicKeyBytes,
envelope: &ExecutionPayloadEnvelope<E>,
current_slot: Slot,
) -> Result<SignedExecutionPayloadEnvelope<E>, Error> {
let signing_epoch = current_slot.epoch(E::slots_per_epoch());
let signing_context = self.signing_context(Domain::BeaconBuilder, signing_epoch);

let signing_method = self.doppelganger_checked_signing_method(validator_pubkey)?;

let signature = signing_method
.get_signature::<E, BlindedPayload<E>>(
SignableMessage::ExecutionPayloadEnvelope(envelope),
signing_context,
&self.spec,
&self.task_executor,
)
.await
.map_err(Error::SpecificError)?;

Ok(SignedExecutionPayloadEnvelope {
message: envelope.clone(),
signature,
})
}

async fn sign_attestation(
&self,
validator_pubkey: PublicKeyBytes,
Expand Down
5 changes: 5 additions & 0 deletions validator_client/signing_method/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub enum SignableMessage<'a, E: EthSpec, Payload: AbstractExecPayload<E> = FullP
SignedContributionAndProof(&'a ContributionAndProof<E>),
ValidatorRegistration(&'a ValidatorRegistrationData),
VoluntaryExit(&'a VoluntaryExit),
ExecutionPayloadEnvelope(&'a ExecutionPayloadEnvelope<E>),
}

impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignableMessage<'_, E, Payload> {
Expand All @@ -68,6 +69,7 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignableMessage<'_, E, Payload
SignableMessage::SignedContributionAndProof(c) => c.signing_root(domain),
SignableMessage::ValidatorRegistration(v) => v.signing_root(domain),
SignableMessage::VoluntaryExit(exit) => exit.signing_root(domain),
SignableMessage::ExecutionPayloadEnvelope(envelope) => envelope.signing_root(domain),
}
}
}
Expand Down Expand Up @@ -228,6 +230,9 @@ impl SigningMethod {
Web3SignerObject::ValidatorRegistration(v)
}
SignableMessage::VoluntaryExit(e) => Web3SignerObject::VoluntaryExit(e),
SignableMessage::ExecutionPayloadEnvelope(envelope) => {
Web3SignerObject::ExecutionPayloadEnvelope(envelope)
}
};

// Determine the Web3Signer message type.
Expand Down
3 changes: 3 additions & 0 deletions validator_client/signing_method/src/web3signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub enum MessageType {
SyncCommitteeSelectionProof,
SyncCommitteeContributionAndProof,
ValidatorRegistration,
ExecutionPayloadEnvelope,
}

#[derive(Debug, PartialEq, Copy, Clone, Serialize)]
Expand Down Expand Up @@ -74,6 +75,7 @@ pub enum Web3SignerObject<'a, E: EthSpec, Payload: AbstractExecPayload<E>> {
SyncAggregatorSelectionData(&'a SyncAggregatorSelectionData),
ContributionAndProof(&'a ContributionAndProof<E>),
ValidatorRegistration(&'a ValidatorRegistrationData),
ExecutionPayloadEnvelope(&'a ExecutionPayloadEnvelope<E>),
}

impl<'a, E: EthSpec, Payload: AbstractExecPayload<E>> Web3SignerObject<'a, E, Payload> {
Expand Down Expand Up @@ -139,6 +141,7 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload<E>> Web3SignerObject<'a, E, Pa
MessageType::SyncCommitteeContributionAndProof
}
Web3SignerObject::ValidatorRegistration(_) => MessageType::ValidatorRegistration,
Web3SignerObject::ExecutionPayloadEnvelope(_) => MessageType::ExecutionPayloadEnvelope,
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions validator_client/validator_metrics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ pub const BEACON_BLOCK: &str = "beacon_block";
pub const BEACON_BLOCK_HTTP_GET: &str = "beacon_block_http_get";
pub const BEACON_BLOCK_HTTP_POST: &str = "beacon_block_http_post";
pub const BLINDED_BEACON_BLOCK_HTTP_POST: &str = "blinded_beacon_block_http_post";
pub const EXECUTION_PAYLOAD_ENVELOPE_HTTP_GET: &str = "execution_payload_envelope_http_get";
pub const EXECUTION_PAYLOAD_ENVELOPE_HTTP_POST: &str = "execution_payload_envelope_http_post";
pub const EXECUTION_PAYLOAD_ENVELOPE_SIGN: &str = "execution_payload_envelope_sign";
pub const EXECUTION_PAYLOAD_ENVELOPE: &str = "execution_payload_envelope";
pub const ATTESTATIONS: &str = "attestations";
pub const ATTESTATIONS_HTTP_GET: &str = "attestations_http_get";
pub const ATTESTATIONS_HTTP_POST: &str = "attestations_http_post";
Expand Down Expand Up @@ -237,6 +241,12 @@ pub static BLOCK_SIGNING_TIMES: LazyLock<Result<Histogram>> = LazyLock::new(|| {
"Duration to obtain a signature for a block",
)
});
pub static ENVELOPE_SIGNING_TIMES: LazyLock<Result<Histogram>> = LazyLock::new(|| {
try_create_histogram(
"vc_envelope_signing_times_seconds",
"Duration to obtain a signature for an execution payload envelope",
)
});

pub static ATTESTATION_DUTY: LazyLock<Result<IntGaugeVec>> = LazyLock::new(|| {
try_create_int_gauge_vec(
Expand Down
Loading