Skip to content

Commit 295830a

Browse files
committed
gloas block production
1 parent f3e822b commit 295830a

File tree

8 files changed

+973
-29
lines changed

8 files changed

+973
-29
lines changed

common/eth2/src/lib.rs

Lines changed: 316 additions & 16 deletions
Large diffs are not rendered by default.

common/eth2/src/types.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,6 +1728,41 @@ pub struct ProduceBlockV3Metadata {
17281728
pub consensus_block_value: Uint256,
17291729
}
17301730

1731+
/// Metadata about a `ExecutionPayloadEnvelope` response which is returned in the headers.
1732+
#[derive(Debug, Deserialize, Serialize)]
1733+
pub struct ExecutionPayloadEnvelopeMetadata {
1734+
// The consensus version is serialized & deserialized by `ForkVersionedResponse`.
1735+
#[serde(
1736+
skip_serializing,
1737+
skip_deserializing,
1738+
default = "dummy_consensus_version"
1739+
)]
1740+
pub consensus_version: ForkName,
1741+
}
1742+
1743+
/// Response from the `/eth/v4/validator/blocks/{slot}` endpoint.
1744+
///
1745+
/// V4 is specific to post-Gloas forks and always returns a BeaconBlock directly.
1746+
/// No blinded/unblinded concept exists in Gloas.
1747+
pub type ProduceBlockV4Response<E> = BeaconBlock<E>;
1748+
1749+
pub type JsonProduceBlockV4Response<E> =
1750+
ForkVersionedResponse<ProduceBlockV4Response<E>, ProduceBlockV4Metadata>;
1751+
1752+
/// Metadata about a `ProduceBlockV4Response` which is returned in the body & headers.
1753+
#[derive(Debug, Deserialize, Serialize)]
1754+
pub struct ProduceBlockV4Metadata {
1755+
// The consensus version is serialized & deserialized by `ForkVersionedResponse`.
1756+
#[serde(
1757+
skip_serializing,
1758+
skip_deserializing,
1759+
default = "dummy_consensus_version"
1760+
)]
1761+
pub consensus_version: ForkName,
1762+
#[serde(with = "serde_utils::u256_dec")]
1763+
pub consensus_block_value: Uint256,
1764+
}
1765+
17311766
impl<E: EthSpec> FullBlockContents<E> {
17321767
pub fn new(block: BeaconBlock<E>, blob_data: Option<(KzgProofs<E>, BlobsList<E>)>) -> Self {
17331768
match blob_data {
@@ -1884,6 +1919,40 @@ impl TryFrom<&HeaderMap> for ProduceBlockV3Metadata {
18841919
}
18851920
}
18861921

1922+
impl TryFrom<&HeaderMap> for ExecutionPayloadEnvelopeMetadata {
1923+
type Error = String;
1924+
1925+
fn try_from(headers: &HeaderMap) -> Result<Self, Self::Error> {
1926+
let consensus_version = parse_required_header(headers, CONSENSUS_VERSION_HEADER, |s| {
1927+
s.parse::<ForkName>()
1928+
.map_err(|e| format!("invalid {CONSENSUS_VERSION_HEADER}: {e:?}"))
1929+
})?;
1930+
1931+
Ok(ExecutionPayloadEnvelopeMetadata { consensus_version })
1932+
}
1933+
}
1934+
1935+
impl TryFrom<&HeaderMap> for ProduceBlockV4Metadata {
1936+
type Error = String;
1937+
1938+
fn try_from(headers: &HeaderMap) -> Result<Self, Self::Error> {
1939+
let consensus_version = parse_required_header(headers, CONSENSUS_VERSION_HEADER, |s| {
1940+
s.parse::<ForkName>()
1941+
.map_err(|e| format!("invalid {CONSENSUS_VERSION_HEADER}: {e:?}"))
1942+
})?;
1943+
let consensus_block_value =
1944+
parse_required_header(headers, CONSENSUS_BLOCK_VALUE_HEADER, |s| {
1945+
Uint256::from_str_radix(s, 10)
1946+
.map_err(|e| format!("invalid {CONSENSUS_BLOCK_VALUE_HEADER}: {e:?}"))
1947+
})?;
1948+
1949+
Ok(ProduceBlockV4Metadata {
1950+
consensus_version,
1951+
consensus_block_value,
1952+
})
1953+
}
1954+
}
1955+
18871956
/// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBlockContents`].
18881957
#[derive(Clone, Debug, PartialEq, Encode, Serialize)]
18891958
#[serde(untagged)]

validator_client/lighthouse_validator_store/src/lib.rs

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ use task_executor::TaskExecutor;
1818
use tracing::{error, info, warn};
1919
use types::{
2020
AbstractExecPayload, Address, AggregateAndProof, Attestation, BeaconBlock, BlindedPayload,
21-
ChainSpec, ContributionAndProof, Domain, Epoch, EthSpec, Fork, Graffiti, Hash256,
22-
PublicKeyBytes, SelectionProof, Signature, SignedAggregateAndProof, SignedBeaconBlock,
23-
SignedContributionAndProof, SignedRoot, SignedValidatorRegistrationData, SignedVoluntaryExit,
24-
Slot, SyncAggregatorSelectionData, SyncCommitteeContribution, SyncCommitteeMessage,
25-
SyncSelectionProof, SyncSubnetId, ValidatorRegistrationData, VoluntaryExit,
26-
graffiti::GraffitiString,
21+
ChainSpec, ContributionAndProof, Domain, Epoch, EthSpec, ExecutionPayloadEnvelope, Fork,
22+
Graffiti, Hash256, PublicKeyBytes, SelectionProof, Signature, SignedAggregateAndProof,
23+
SignedBeaconBlock, SignedContributionAndProof, SignedExecutionPayloadEnvelope, SignedRoot,
24+
SignedValidatorRegistrationData, SignedVoluntaryExit, Slot, SyncAggregatorSelectionData,
25+
SyncCommitteeContribution, SyncCommitteeMessage, SyncSelectionProof, SyncSubnetId,
26+
ValidatorRegistrationData, VoluntaryExit, graffiti::GraffitiString,
2727
};
2828
use validator_store::{
2929
DoppelgangerStatus, Error as ValidatorStoreError, ProposalData, SignedBlock, UnsignedBlock,
@@ -745,6 +745,45 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore for LighthouseValidatorS
745745
}
746746
}
747747

748+
async fn sign_block_gloas(
749+
&self,
750+
validator_pubkey: PublicKeyBytes,
751+
block: &BeaconBlock<E>,
752+
current_slot: Slot,
753+
) -> Result<Arc<SignedBeaconBlock<E>>, Error> {
754+
let beacon_block = block.clone();
755+
self.sign_abstract_block(validator_pubkey, beacon_block, current_slot)
756+
.await
757+
.map(|signed_block| Arc::new(signed_block))
758+
}
759+
760+
async fn sign_execution_payload_envelope(
761+
&self,
762+
validator_pubkey: PublicKeyBytes,
763+
envelope: &ExecutionPayloadEnvelope<E>,
764+
current_slot: Slot,
765+
) -> Result<SignedExecutionPayloadEnvelope<E>, Error> {
766+
let signing_epoch = current_slot.epoch(E::slots_per_epoch());
767+
let signing_context = self.signing_context(Domain::BeaconBuilder, signing_epoch);
768+
769+
let signing_method = self.doppelganger_checked_signing_method(validator_pubkey)?;
770+
771+
let signature = signing_method
772+
.get_signature::<E, BlindedPayload<E>>(
773+
SignableMessage::ExecutionPayloadEnvelope(envelope),
774+
signing_context,
775+
&self.spec,
776+
&self.task_executor,
777+
)
778+
.await
779+
.map_err(Error::SpecificError)?;
780+
781+
let signed_envelope =
782+
SignedExecutionPayloadEnvelope::from_envelope(envelope.clone(), signature);
783+
784+
Ok(signed_envelope)
785+
}
786+
748787
async fn sign_attestation(
749788
&self,
750789
validator_pubkey: PublicKeyBytes,

validator_client/signing_method/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ pub enum SignableMessage<'a, E: EthSpec, Payload: AbstractExecPayload<E> = FullP
4747
SignedContributionAndProof(&'a ContributionAndProof<E>),
4848
ValidatorRegistration(&'a ValidatorRegistrationData),
4949
VoluntaryExit(&'a VoluntaryExit),
50+
ExecutionPayloadEnvelope(&'a ExecutionPayloadEnvelope<E>),
5051
}
5152

5253
impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignableMessage<'_, E, Payload> {
@@ -68,6 +69,7 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignableMessage<'_, E, Payload
6869
SignableMessage::SignedContributionAndProof(c) => c.signing_root(domain),
6970
SignableMessage::ValidatorRegistration(v) => v.signing_root(domain),
7071
SignableMessage::VoluntaryExit(exit) => exit.signing_root(domain),
72+
SignableMessage::ExecutionPayloadEnvelope(envelope) => envelope.signing_root(domain),
7173
}
7274
}
7375
}
@@ -228,6 +230,9 @@ impl SigningMethod {
228230
Web3SignerObject::ValidatorRegistration(v)
229231
}
230232
SignableMessage::VoluntaryExit(e) => Web3SignerObject::VoluntaryExit(e),
233+
SignableMessage::ExecutionPayloadEnvelope(envelope) => {
234+
Web3SignerObject::ExecutionPayloadEnvelope(envelope)
235+
}
231236
};
232237

233238
// Determine the Web3Signer message type.

validator_client/signing_method/src/web3signer.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub enum MessageType {
1818
SyncCommitteeSelectionProof,
1919
SyncCommitteeContributionAndProof,
2020
ValidatorRegistration,
21+
ExecutionPayloadEnvelope,
2122
}
2223

2324
#[derive(Debug, PartialEq, Copy, Clone, Serialize)]
@@ -74,6 +75,7 @@ pub enum Web3SignerObject<'a, E: EthSpec, Payload: AbstractExecPayload<E>> {
7475
SyncAggregatorSelectionData(&'a SyncAggregatorSelectionData),
7576
ContributionAndProof(&'a ContributionAndProof<E>),
7677
ValidatorRegistration(&'a ValidatorRegistrationData),
78+
ExecutionPayloadEnvelope(&'a ExecutionPayloadEnvelope<E>),
7779
}
7880

7981
impl<'a, E: EthSpec, Payload: AbstractExecPayload<E>> Web3SignerObject<'a, E, Payload> {
@@ -139,6 +141,7 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload<E>> Web3SignerObject<'a, E, Pa
139141
MessageType::SyncCommitteeContributionAndProof
140142
}
141143
Web3SignerObject::ValidatorRegistration(_) => MessageType::ValidatorRegistration,
144+
Web3SignerObject::ExecutionPayloadEnvelope(_) => MessageType::ExecutionPayloadEnvelope,
142145
}
143146
}
144147
}

validator_client/validator_metrics/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ pub const BEACON_BLOCK: &str = "beacon_block";
99
pub const BEACON_BLOCK_HTTP_GET: &str = "beacon_block_http_get";
1010
pub const BEACON_BLOCK_HTTP_POST: &str = "beacon_block_http_post";
1111
pub const BLINDED_BEACON_BLOCK_HTTP_POST: &str = "blinded_beacon_block_http_post";
12+
pub const EXECUTION_PAYLOAD_ENVELOPE_HTTP_GET: &str = "execution_payload_envelope_http_get";
13+
pub const EXECUTION_PAYLOAD_ENVELOPE_HTTP_POST: &str = "execution_payload_envelope_http_post";
14+
pub const EXECUTION_PAYLOAD_ENVELOPE_SIGN: &str = "execution_payload_envelope_sign";
15+
pub const EXECUTION_PAYLOAD_ENVELOPE: &str = "execution_payload_envelope";
1216
pub const ATTESTATIONS: &str = "attestations";
1317
pub const ATTESTATIONS_HTTP_GET: &str = "attestations_http_get";
1418
pub const ATTESTATIONS_HTTP_POST: &str = "attestations_http_post";
@@ -237,6 +241,12 @@ pub static BLOCK_SIGNING_TIMES: LazyLock<Result<Histogram>> = LazyLock::new(|| {
237241
"Duration to obtain a signature for a block",
238242
)
239243
});
244+
pub static ENVELOPE_SIGNING_TIMES: LazyLock<Result<Histogram>> = LazyLock::new(|| {
245+
try_create_histogram(
246+
"vc_envelope_signing_times_seconds",
247+
"Duration to obtain a signature for an execution payload envelope",
248+
)
249+
});
240250

241251
pub static ATTESTATION_DUTY: LazyLock<Result<IntGaugeVec>> = LazyLock::new(|| {
242252
try_create_int_gauge_vec(

0 commit comments

Comments
 (0)