mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-18 13:28:33 +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
|
||||
if envelope.builder_index != execution_bid.builder_index {
|
||||
if envelope.raw_builder_index() != execution_bid.builder_index {
|
||||
return Err(EnvelopeError::BuilderIndexMismatch {
|
||||
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;
|
||||
|
||||
// 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 pubkey_cache = chain.validator_pubkey_cache.read();
|
||||
let builder_pubkey = pubkey_cache
|
||||
.get(envelope.builder_index as usize)
|
||||
.ok_or_else(|| EnvelopeError::UnknownValidator {
|
||||
builder_index: envelope.builder_index,
|
||||
})?;
|
||||
.get(builder_index as usize)
|
||||
.ok_or_else(|| EnvelopeError::UnknownValidator { builder_index })?;
|
||||
signed_envelope.verify_signature(
|
||||
builder_pubkey,
|
||||
&fork,
|
||||
|
||||
@@ -372,6 +372,8 @@ where
|
||||
E: EthSpec,
|
||||
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(
|
||||
state.current_epoch(),
|
||||
Domain::BeaconBuilder,
|
||||
@@ -379,9 +381,8 @@ where
|
||||
state.genesis_validators_root(),
|
||||
);
|
||||
let message = signed_envelope.message.signing_root(domain);
|
||||
let pubkey = get_pubkey(signed_envelope.message.builder_index as usize).ok_or(
|
||||
Error::ValidatorUnknown(signed_envelope.message.builder_index),
|
||||
)?;
|
||||
let pubkey =
|
||||
get_pubkey(builder_index as usize).ok_or(Error::ValidatorUnknown(builder_index))?;
|
||||
|
||||
Ok(SignatureSet::single_pubkey(
|
||||
&signed_envelope.signature,
|
||||
@@ -400,6 +401,7 @@ where
|
||||
E: EthSpec,
|
||||
F: Fn(usize) -> Option<Cow<'a, PublicKey>>,
|
||||
{
|
||||
// TODO(EIP-7732): needs to handle self building!
|
||||
let domain = spec.get_domain(
|
||||
state.current_epoch(),
|
||||
Domain::BeaconBuilder,
|
||||
|
||||
@@ -25,3 +25,6 @@ pub mod bellatrix {
|
||||
pub mod deneb {
|
||||
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::{
|
||||
EthSpec, ExecutionPayloadGloas, ExecutionRequests, ForkName, Hash256, KzgCommitments,
|
||||
@@ -17,8 +18,10 @@ use tree_hash_derive::TreeHash;
|
||||
pub struct ExecutionPayloadEnvelope<E: EthSpec> {
|
||||
pub payload: ExecutionPayloadGloas<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")]
|
||||
pub builder_index: u64,
|
||||
builder_index: u64,
|
||||
pub beacon_block_root: Hash256,
|
||||
pub slot: Slot,
|
||||
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> 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)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -39,12 +39,14 @@ impl<E: EthSpec> SignedExecutionPayloadEnvelope<E> {
|
||||
///
|
||||
/// The `parent_state` is the post-state of the beacon block with
|
||||
/// 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(
|
||||
&self,
|
||||
parent_state: &BeaconState<E>,
|
||||
spec: &ChainSpec,
|
||||
) -> 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(
|
||||
parent_state.current_epoch(),
|
||||
Domain::BeaconBuilder,
|
||||
@@ -53,23 +55,18 @@ impl<E: EthSpec> SignedExecutionPayloadEnvelope<E> {
|
||||
);
|
||||
let pubkey = parent_state
|
||||
.validators()
|
||||
.get(self.message.builder_index as usize)
|
||||
.get(builder_index)
|
||||
.and_then(|v| {
|
||||
let pk: Option<PublicKey> = v.pubkey.decompress().ok();
|
||||
pk
|
||||
})
|
||||
.ok_or(BeaconStateError::UnknownValidator(
|
||||
self.message.builder_index as usize,
|
||||
))?;
|
||||
.ok_or(BeaconStateError::UnknownValidator(builder_index))?;
|
||||
let message = self.message.signing_root(domain);
|
||||
|
||||
Ok(self.signature.verify(&pubkey, message))
|
||||
}
|
||||
|
||||
/// 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(
|
||||
&self,
|
||||
pubkey: &PublicKey,
|
||||
@@ -77,9 +74,11 @@ impl<E: EthSpec> SignedExecutionPayloadEnvelope<E> {
|
||||
genesis_validators_root: Hash256,
|
||||
spec: &ChainSpec,
|
||||
) -> 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(
|
||||
self.epoch(),
|
||||
Domain::BeaconProposer,
|
||||
Domain::BeaconBuilder,
|
||||
fork,
|
||||
genesis_validators_root,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user