mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-07 00:42:42 +00:00
Handle self-building and use builder domain for envelopes
This commit is contained in:
@@ -263,10 +263,10 @@ impl<T: BeaconChainTypes> GossipVerifiedEnvelope<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// builder index matches committed bid
|
// builder index matches committed bid
|
||||||
if envelope.builder_index != execution_bid.builder_index {
|
if envelope.raw_builder_index() != execution_bid.builder_index {
|
||||||
return Err(EnvelopeError::BuilderIndexMismatch {
|
return Err(EnvelopeError::BuilderIndexMismatch {
|
||||||
committed_bid: execution_bid.builder_index,
|
committed_bid: execution_bid.builder_index,
|
||||||
envelope: envelope.builder_index,
|
envelope: envelope.raw_builder_index(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,13 +308,15 @@ impl<T: BeaconChainTypes> GossipVerifiedEnvelope<T> {
|
|||||||
)?;
|
)?;
|
||||||
let fork = proposer.fork;
|
let fork = proposer.fork;
|
||||||
|
|
||||||
|
// True builder index accounting for self-building.
|
||||||
|
let proposer_index = parent_block.message().proposer_index();
|
||||||
|
let builder_index = envelope.builder_index(proposer_index);
|
||||||
|
|
||||||
let signature_is_valid = {
|
let signature_is_valid = {
|
||||||
let pubkey_cache = chain.validator_pubkey_cache.read();
|
let pubkey_cache = chain.validator_pubkey_cache.read();
|
||||||
let builder_pubkey = pubkey_cache
|
let builder_pubkey = pubkey_cache
|
||||||
.get(envelope.builder_index as usize)
|
.get(builder_index as usize)
|
||||||
.ok_or_else(|| EnvelopeError::UnknownValidator {
|
.ok_or_else(|| EnvelopeError::UnknownValidator { builder_index })?;
|
||||||
builder_index: envelope.builder_index,
|
|
||||||
})?;
|
|
||||||
signed_envelope.verify_signature(
|
signed_envelope.verify_signature(
|
||||||
builder_pubkey,
|
builder_pubkey,
|
||||||
&fork,
|
&fork,
|
||||||
|
|||||||
@@ -372,6 +372,8 @@ where
|
|||||||
E: EthSpec,
|
E: EthSpec,
|
||||||
F: Fn(usize) -> Option<Cow<'a, PublicKey>>,
|
F: Fn(usize) -> Option<Cow<'a, PublicKey>>,
|
||||||
{
|
{
|
||||||
|
let proposer_index = state.latest_block_header().proposer_index;
|
||||||
|
let builder_index = signed_envelope.message.builder_index(proposer_index);
|
||||||
let domain = spec.get_domain(
|
let domain = spec.get_domain(
|
||||||
state.current_epoch(),
|
state.current_epoch(),
|
||||||
Domain::BeaconBuilder,
|
Domain::BeaconBuilder,
|
||||||
@@ -379,9 +381,8 @@ where
|
|||||||
state.genesis_validators_root(),
|
state.genesis_validators_root(),
|
||||||
);
|
);
|
||||||
let message = signed_envelope.message.signing_root(domain);
|
let message = signed_envelope.message.signing_root(domain);
|
||||||
let pubkey = get_pubkey(signed_envelope.message.builder_index as usize).ok_or(
|
let pubkey =
|
||||||
Error::ValidatorUnknown(signed_envelope.message.builder_index),
|
get_pubkey(builder_index as usize).ok_or(Error::ValidatorUnknown(builder_index))?;
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(SignatureSet::single_pubkey(
|
Ok(SignatureSet::single_pubkey(
|
||||||
&signed_envelope.signature,
|
&signed_envelope.signature,
|
||||||
@@ -400,6 +401,7 @@ where
|
|||||||
E: EthSpec,
|
E: EthSpec,
|
||||||
F: Fn(usize) -> Option<Cow<'a, PublicKey>>,
|
F: Fn(usize) -> Option<Cow<'a, PublicKey>>,
|
||||||
{
|
{
|
||||||
|
// TODO(EIP-7732): needs to handle self building!
|
||||||
let domain = spec.get_domain(
|
let domain = spec.get_domain(
|
||||||
state.current_epoch(),
|
state.current_epoch(),
|
||||||
Domain::BeaconBuilder,
|
Domain::BeaconBuilder,
|
||||||
|
|||||||
@@ -25,3 +25,6 @@ pub mod bellatrix {
|
|||||||
pub mod deneb {
|
pub mod deneb {
|
||||||
pub use kzg::VERSIONED_HASH_VERSION_KZG;
|
pub use kzg::VERSIONED_HASH_VERSION_KZG;
|
||||||
}
|
}
|
||||||
|
pub mod gloas {
|
||||||
|
pub const BUILDER_INDEX_SELF_BUILD: u64 = u64::MAX;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::consts::gloas::BUILDER_INDEX_SELF_BUILD;
|
||||||
use crate::test_utils::TestRandom;
|
use crate::test_utils::TestRandom;
|
||||||
use crate::{
|
use crate::{
|
||||||
EthSpec, ExecutionPayloadGloas, ExecutionRequests, ForkName, Hash256, KzgCommitments,
|
EthSpec, ExecutionPayloadGloas, ExecutionRequests, ForkName, Hash256, KzgCommitments,
|
||||||
@@ -17,8 +18,10 @@ use tree_hash_derive::TreeHash;
|
|||||||
pub struct ExecutionPayloadEnvelope<E: EthSpec> {
|
pub struct ExecutionPayloadEnvelope<E: EthSpec> {
|
||||||
pub payload: ExecutionPayloadGloas<E>,
|
pub payload: ExecutionPayloadGloas<E>,
|
||||||
pub execution_requests: ExecutionRequests<E>,
|
pub execution_requests: ExecutionRequests<E>,
|
||||||
|
// The builder index is private so that callers are forced to handle the case where it equals
|
||||||
|
// BUILDER_INDEX_SELF_BUILD.
|
||||||
#[serde(with = "serde_utils::quoted_u64")]
|
#[serde(with = "serde_utils::quoted_u64")]
|
||||||
pub builder_index: u64,
|
builder_index: u64,
|
||||||
pub beacon_block_root: Hash256,
|
pub beacon_block_root: Hash256,
|
||||||
pub slot: Slot,
|
pub slot: Slot,
|
||||||
pub blob_kzg_commitments: KzgCommitments<E>,
|
pub blob_kzg_commitments: KzgCommitments<E>,
|
||||||
@@ -27,6 +30,28 @@ pub struct ExecutionPayloadEnvelope<E: EthSpec> {
|
|||||||
|
|
||||||
impl<E: EthSpec> SignedRoot for ExecutionPayloadEnvelope<E> {}
|
impl<E: EthSpec> SignedRoot for ExecutionPayloadEnvelope<E> {}
|
||||||
|
|
||||||
|
impl<E: EthSpec> ExecutionPayloadEnvelope<E> {
|
||||||
|
/// Fetch the validator index of the builder of this execution payload.
|
||||||
|
///
|
||||||
|
/// This falls back to the provided `proposer_index` if the builder index indicates
|
||||||
|
/// self-building.
|
||||||
|
pub fn builder_index(&self, proposer_index: u64) -> u64 {
|
||||||
|
if self.builder_index == BUILDER_INDEX_SELF_BUILD {
|
||||||
|
proposer_index
|
||||||
|
} else {
|
||||||
|
self.builder_index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fetch the raw builder index, which may be `BUILDER_INDEX_SELF_BUILD` to indicate
|
||||||
|
/// self-building.
|
||||||
|
///
|
||||||
|
/// This method should be used sparingly.
|
||||||
|
pub fn raw_builder_index(&self) -> u64 {
|
||||||
|
self.builder_index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -39,12 +39,14 @@ impl<E: EthSpec> SignedExecutionPayloadEnvelope<E> {
|
|||||||
///
|
///
|
||||||
/// The `parent_state` is the post-state of the beacon block with
|
/// The `parent_state` is the post-state of the beacon block with
|
||||||
/// block_root = self.message.beacon_block_root
|
/// block_root = self.message.beacon_block_root
|
||||||
/// TODO(EIP-7732): maybe delete this function later
|
/// TODO(EIP-7732): maybe delete this function later (it is inefficient)
|
||||||
pub fn verify_signature_with_state(
|
pub fn verify_signature_with_state(
|
||||||
&self,
|
&self,
|
||||||
parent_state: &BeaconState<E>,
|
parent_state: &BeaconState<E>,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Result<bool, BeaconStateError> {
|
) -> Result<bool, BeaconStateError> {
|
||||||
|
let proposer_index = parent_state.latest_block_header().proposer_index;
|
||||||
|
let builder_index = self.message.builder_index(proposer_index) as usize;
|
||||||
let domain = spec.get_domain(
|
let domain = spec.get_domain(
|
||||||
parent_state.current_epoch(),
|
parent_state.current_epoch(),
|
||||||
Domain::BeaconBuilder,
|
Domain::BeaconBuilder,
|
||||||
@@ -53,23 +55,18 @@ impl<E: EthSpec> SignedExecutionPayloadEnvelope<E> {
|
|||||||
);
|
);
|
||||||
let pubkey = parent_state
|
let pubkey = parent_state
|
||||||
.validators()
|
.validators()
|
||||||
.get(self.message.builder_index as usize)
|
.get(builder_index)
|
||||||
.and_then(|v| {
|
.and_then(|v| {
|
||||||
let pk: Option<PublicKey> = v.pubkey.decompress().ok();
|
let pk: Option<PublicKey> = v.pubkey.decompress().ok();
|
||||||
pk
|
pk
|
||||||
})
|
})
|
||||||
.ok_or(BeaconStateError::UnknownValidator(
|
.ok_or(BeaconStateError::UnknownValidator(builder_index))?;
|
||||||
self.message.builder_index as usize,
|
|
||||||
))?;
|
|
||||||
let message = self.message.signing_root(domain);
|
let message = self.message.signing_root(domain);
|
||||||
|
|
||||||
Ok(self.signature.verify(&pubkey, message))
|
Ok(self.signature.verify(&pubkey, message))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verify `self.signature`.
|
/// Verify `self.signature`.
|
||||||
///
|
|
||||||
/// If the root of `block.message` is already known it can be passed in via `object_root_opt`.
|
|
||||||
/// Otherwise, it will be computed locally.
|
|
||||||
pub fn verify_signature(
|
pub fn verify_signature(
|
||||||
&self,
|
&self,
|
||||||
pubkey: &PublicKey,
|
pubkey: &PublicKey,
|
||||||
@@ -77,9 +74,11 @@ impl<E: EthSpec> SignedExecutionPayloadEnvelope<E> {
|
|||||||
genesis_validators_root: Hash256,
|
genesis_validators_root: Hash256,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
// Signed envelopes using the new BeaconBuilder domain per the spec:
|
||||||
|
// https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/gloas/beacon-chain.md#new-verify_execution_payload_envelope_signature
|
||||||
let domain = spec.get_domain(
|
let domain = spec.get_domain(
|
||||||
self.epoch(),
|
self.epoch(),
|
||||||
Domain::BeaconProposer,
|
Domain::BeaconBuilder,
|
||||||
fork,
|
fork,
|
||||||
genesis_validators_root,
|
genesis_validators_root,
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user