mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-16 12:28:24 +00:00
Whole Bunch of Changes Sorry
This commit is contained in:
@@ -59,6 +59,15 @@ pub trait ForkChoiceStore<E: EthSpec>: Sized {
|
||||
/// Returns the `proposer_boost_root`.
|
||||
fn proposer_boost_root(&self) -> Hash256;
|
||||
|
||||
/// Returns the `payload_withhold_boost_root`.
|
||||
fn payload_withhold_boost_root(&self) -> Hash256;
|
||||
|
||||
/// Returns the `payload_withhold_boost_full`.
|
||||
fn payload_withhold_boost_full(&self) -> bool;
|
||||
|
||||
/// Returns the `payload_reveal_boost_root`.
|
||||
fn payload_reveal_boost_root(&self) -> Hash256;
|
||||
|
||||
/// Sets `finalized_checkpoint`.
|
||||
fn set_finalized_checkpoint(&mut self, checkpoint: Checkpoint);
|
||||
|
||||
@@ -74,6 +83,15 @@ pub trait ForkChoiceStore<E: EthSpec>: Sized {
|
||||
/// Sets the proposer boost root.
|
||||
fn set_proposer_boost_root(&mut self, proposer_boost_root: Hash256);
|
||||
|
||||
/// Sets the payload withhold boost root.
|
||||
fn set_payload_withhold_boost_root(&mut self, payload_withhold_boost_root: Hash256);
|
||||
|
||||
/// Sets the payload withhold boost full.
|
||||
fn set_payload_withhold_boost_full(&mut self, payload_withhold_boost_full: bool);
|
||||
|
||||
/// Sets the payload reveal boost root.
|
||||
fn set_payload_reveal_boost_root(&mut self, payload_reveal_boost_root: Hash256);
|
||||
|
||||
/// Gets the equivocating indices.
|
||||
fn equivocating_indices(&self) -> &BTreeSet<u64>;
|
||||
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
use super::signature_sets::{execution_envelope_signature_set, get_pubkey_from_state};
|
||||
use crate::per_block_processing::compute_timestamp_at_slot;
|
||||
use crate::per_block_processing::errors::{BlockProcessingError, ExecutionEnvelopeError};
|
||||
use crate::VerifySignatures;
|
||||
use tree_hash::TreeHash;
|
||||
use types::{BeaconState, ChainSpec, EthSpec, Hash256, SignedExecutionEnvelope};
|
||||
|
||||
pub fn process_execution_envelope<E: EthSpec>(
|
||||
state: &mut BeaconState<E>,
|
||||
signed_envelope: SignedExecutionEnvelope<E>,
|
||||
spec: &ChainSpec,
|
||||
verify_signatures: VerifySignatures,
|
||||
) -> Result<(), BlockProcessingError> {
|
||||
if verify_signatures.is_true() {
|
||||
block_verify!(
|
||||
execution_envelope_signature_set(
|
||||
state,
|
||||
|i| get_pubkey_from_state(state, i),
|
||||
&signed_envelope,
|
||||
spec
|
||||
)?
|
||||
.verify(),
|
||||
ExecutionEnvelopeError::BadSignature.into()
|
||||
)
|
||||
}
|
||||
|
||||
let envelope = signed_envelope.message();
|
||||
let payload = &envelope.payload;
|
||||
let previous_state_root = state.canonical_root()?;
|
||||
if state.latest_block_header().state_root == Hash256::default() {
|
||||
*state.latest_block_header_mut().state_root = *previous_state_root;
|
||||
}
|
||||
|
||||
// Verify consistency with the beacon block
|
||||
block_verify!(
|
||||
envelope.tree_hash_root() == state.latest_block_header().tree_hash_root(),
|
||||
ExecutionEnvelopeError::LatestBlockHeaderMismatch {
|
||||
envelope_root: envelope.tree_hash_root(),
|
||||
block_header_root: state.latest_block_header().tree_hash_root(),
|
||||
}
|
||||
.into()
|
||||
);
|
||||
|
||||
// Verify consistency with the committed bid
|
||||
let committed_bid = state.latest_execution_bid()?;
|
||||
block_verify!(
|
||||
envelope.builder_index == committed_bid.builder_index,
|
||||
ExecutionEnvelopeError::BuilderIndexMismatch {
|
||||
committed_bid: committed_bid.builder_index,
|
||||
envelope: envelope.builder_index,
|
||||
}
|
||||
.into()
|
||||
);
|
||||
block_verify!(
|
||||
committed_bid.blob_kzg_commitments_root == envelope.blob_kzg_commitments.tree_hash_root(),
|
||||
ExecutionEnvelopeError::BlobKzgCommitmentsRootMismatch {
|
||||
committed_bid: committed_bid.blob_kzg_commitments_root,
|
||||
envelope: envelope.blob_kzg_commitments.tree_hash_root(),
|
||||
}
|
||||
.into()
|
||||
);
|
||||
|
||||
if !envelope.payment_withheld {
|
||||
// Verify the withdrawals root
|
||||
block_verify!(
|
||||
payload.withdrawals.tree_hash_root() == state.latest_withdrawals_root()?,
|
||||
ExecutionEnvelopeError::WithdrawalsRootMismatch {
|
||||
state: state.latest_withdrawals_root()?,
|
||||
envelope: payload.withdrawals.tree_hash_root(),
|
||||
}
|
||||
.into()
|
||||
);
|
||||
|
||||
// Verify the gas limit
|
||||
block_verify!(
|
||||
payload.gas_limit == committed_bid.gas_limit,
|
||||
ExecutionEnvelopeError::GasLimitMismatch {
|
||||
committed_bid: committed_bid.gas_limit,
|
||||
envelope: payload.gas_limit,
|
||||
}
|
||||
.into()
|
||||
);
|
||||
|
||||
block_verify!(
|
||||
committed_bid.block_hash == payload.block_hash,
|
||||
ExecutionEnvelopeError::BlockHashMismatch {
|
||||
committed_bid: committed_bid.block_hash,
|
||||
envelope: payload.block_hash,
|
||||
}
|
||||
.into()
|
||||
);
|
||||
|
||||
// Verify consistency of the parent hash with respect to the previous execution payload
|
||||
block_verify!(
|
||||
payload.parent_hash == state.latest_block_hash()?,
|
||||
ExecutionEnvelopeError::ParentHashMismatch {
|
||||
state: state.latest_block_hash()?,
|
||||
envelope: payload.parent_hash,
|
||||
}
|
||||
.into()
|
||||
);
|
||||
|
||||
// Verify prev_randao
|
||||
block_verify!(
|
||||
payload.prev_randao == *state.get_randao_mix(state.current_epoch())?,
|
||||
ExecutionEnvelopeError::PrevRandaoMismatch {
|
||||
state: *state.get_randao_mix(state.current_epoch())?,
|
||||
envelope: payload.prev_randao,
|
||||
}
|
||||
.into()
|
||||
);
|
||||
|
||||
// Verify the timestamp
|
||||
let state_timestamp = compute_timestamp_at_slot(state, state.slot(), spec)?;
|
||||
block_verify!(
|
||||
payload.timestamp == state_timestamp,
|
||||
ExecutionEnvelopeError::TimestampMismatch {
|
||||
state: state_timestamp,
|
||||
envelope: payload.timestamp,
|
||||
}
|
||||
.into()
|
||||
);
|
||||
|
||||
// Verify the commitments are under limit
|
||||
block_verify!(
|
||||
envelope.blob_kzg_commitments.len() <= E::max_blob_commitments_per_block(),
|
||||
ExecutionEnvelopeError::BlobLimitExceeded {
|
||||
max: E::max_blob_commitments_per_block(),
|
||||
envelope: envelope.blob_kzg_commitments.len(),
|
||||
}
|
||||
.into()
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -21,7 +21,6 @@ pub mod block_replayer;
|
||||
pub mod common;
|
||||
pub mod consensus_context;
|
||||
pub mod epoch_cache;
|
||||
pub mod execution_processing;
|
||||
pub mod genesis;
|
||||
pub mod per_block_processing;
|
||||
pub mod per_epoch_processing;
|
||||
@@ -33,7 +32,6 @@ pub mod verify_operation;
|
||||
pub use all_caches::AllCaches;
|
||||
pub use block_replayer::{BlockReplayError, BlockReplayer};
|
||||
pub use consensus_context::{ConsensusContext, ContextError};
|
||||
pub use execution_processing::process_execution_envelope;
|
||||
pub use genesis::{
|
||||
eth2_genesis_time, initialize_beacon_state_from_eth1, is_valid_genesis_state,
|
||||
process_activations,
|
||||
|
||||
@@ -63,7 +63,6 @@ pub enum BlockProcessingError {
|
||||
ExecutionBidInvalid {
|
||||
reason: ExecutionBidInvalid,
|
||||
},
|
||||
ExecutionEnvelopeError(ExecutionEnvelopeError),
|
||||
BeaconStateError(BeaconStateError),
|
||||
SignatureSetError(SignatureSetError),
|
||||
SszTypesError(ssz_types::Error),
|
||||
@@ -160,12 +159,6 @@ impl From<ExecutionBidInvalid> for BlockProcessingError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ExecutionEnvelopeError> for BlockProcessingError {
|
||||
fn from(e: ExecutionEnvelopeError) -> Self {
|
||||
BlockProcessingError::ExecutionEnvelopeError(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BlockOperationError<HeaderInvalid>> for BlockProcessingError {
|
||||
fn from(e: BlockOperationError<HeaderInvalid>) -> BlockProcessingError {
|
||||
match e {
|
||||
@@ -548,59 +541,3 @@ pub enum ExecutionBidInvalid {
|
||||
bid_parent_root: Hash256,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum ExecutionEnvelopeError {
|
||||
/// The signature is invalid.
|
||||
BadSignature,
|
||||
/// Envelope doesn't match latest beacon block header
|
||||
LatestBlockHeaderMismatch {
|
||||
envelope_root: Hash256,
|
||||
block_header_root: Hash256,
|
||||
},
|
||||
/// The builder index doesn't match the committed bid
|
||||
BuilderIndexMismatch {
|
||||
committed_bid: u64,
|
||||
envelope: u64,
|
||||
},
|
||||
/// The blob KZG commitments root doesn't match the committed bid
|
||||
BlobKzgCommitmentsRootMismatch {
|
||||
committed_bid: Hash256,
|
||||
envelope: Hash256,
|
||||
},
|
||||
/// The withdrawals root doesn't match the state's latest withdrawals root
|
||||
WithdrawalsRootMismatch {
|
||||
state: Hash256,
|
||||
envelope: Hash256,
|
||||
},
|
||||
// The gas limit doesn't match the committed bid
|
||||
GasLimitMismatch {
|
||||
committed_bid: u64,
|
||||
envelope: u64,
|
||||
},
|
||||
// The block hash doesn't match the committed bid
|
||||
BlockHashMismatch {
|
||||
committed_bid: ExecutionBlockHash,
|
||||
envelope: ExecutionBlockHash,
|
||||
},
|
||||
// The parent hash doesn't match the previous execution payload
|
||||
ParentHashMismatch {
|
||||
state: ExecutionBlockHash,
|
||||
envelope: ExecutionBlockHash,
|
||||
},
|
||||
// The previous randao didn't match the payload
|
||||
PrevRandaoMismatch {
|
||||
state: Hash256,
|
||||
envelope: Hash256,
|
||||
},
|
||||
// The timestamp didn't match the payload
|
||||
TimestampMismatch {
|
||||
state: u64,
|
||||
envelope: u64,
|
||||
},
|
||||
// Blob committments exceeded the maximum
|
||||
BlobLimitExceeded {
|
||||
max: usize,
|
||||
envelope: usize,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -406,8 +406,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(signed_envelope.message().builder_index() as usize).ok_or(
|
||||
Error::ValidatorUnknown(signed_envelope.message().builder_index()),
|
||||
)?;
|
||||
|
||||
Ok(SignatureSet::single_pubkey(
|
||||
|
||||
@@ -8,8 +8,9 @@ use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
// in all likelihood, this will be superstructed so might as well start early eh?
|
||||
#[superstruct(
|
||||
variants(EIP7732),
|
||||
variants(EIP7732, NextFork),
|
||||
variant_attributes(
|
||||
derive(
|
||||
Debug,
|
||||
@@ -27,6 +28,10 @@ use tree_hash_derive::TreeHash;
|
||||
serde(bound = "E: EthSpec", deny_unknown_fields),
|
||||
arbitrary(bound = "E: EthSpec")
|
||||
),
|
||||
ref_attributes(
|
||||
derive(Debug, PartialEq, TreeHash),
|
||||
tree_hash(enum_behaviour = "transparent")
|
||||
),
|
||||
cast_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant"),
|
||||
partial_getter_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant")
|
||||
)]
|
||||
@@ -41,12 +46,32 @@ use tree_hash_derive::TreeHash;
|
||||
pub struct ExecutionEnvelope<E: EthSpec> {
|
||||
#[superstruct(only(EIP7732), partial_getter(rename = "payload_eip7732"))]
|
||||
pub payload: ExecutionPayloadEIP7732<E>,
|
||||
#[superstruct(only(NextFork), partial_getter(rename = "payload_next_fork"))]
|
||||
pub payload: ExecutionPayloadEIP7732<E>,
|
||||
pub execution_requests: ExecutionRequests<E>,
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
#[superstruct(getter(copy))]
|
||||
pub builder_index: u64,
|
||||
#[superstruct(getter(copy))]
|
||||
pub beacon_block_root: Hash256,
|
||||
pub blob_kzg_commitments: KzgCommitments<E>,
|
||||
pub payment_withheld: bool,
|
||||
#[superstruct(getter(copy))]
|
||||
pub payload_withheld: bool,
|
||||
#[superstruct(getter(copy))]
|
||||
pub state_root: Hash256,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> SignedRoot for ExecutionEnvelopeEIP7732<E> {}
|
||||
impl<'a, E: EthSpec> SignedRoot for ExecutionEnvelopeRef<'a, E> {}
|
||||
|
||||
impl<'a, E: EthSpec> ExecutionEnvelopeRef<'a, E> {
|
||||
pub fn payload(&self) -> ExecutionPayloadRef<'a, E> {
|
||||
match self {
|
||||
ExecutionEnvelopeRef::EIP7732(envelope) => {
|
||||
ExecutionPayloadRef::EIP7732(&envelope.payload)
|
||||
}
|
||||
ExecutionEnvelopeRef::NextFork(envelope) => {
|
||||
ExecutionPayloadRef::EIP7732(&envelope.payload)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +172,9 @@ pub use crate::eth_spec::EthSpecId;
|
||||
pub use crate::execution_bid::ExecutionBid;
|
||||
pub use crate::execution_block_hash::ExecutionBlockHash;
|
||||
pub use crate::execution_block_header::{EncodableExecutionBlockHeader, ExecutionBlockHeader};
|
||||
pub use crate::execution_envelope::{ExecutionEnvelope, ExecutionEnvelopeEIP7732};
|
||||
pub use crate::execution_envelope::{
|
||||
ExecutionEnvelope, ExecutionEnvelopeEIP7732, ExecutionEnvelopeRef,
|
||||
};
|
||||
pub use crate::execution_payload::{
|
||||
ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
|
||||
ExecutionPayloadEIP7732, ExecutionPayloadElectra, ExecutionPayloadRef, Transaction,
|
||||
|
||||
@@ -7,8 +7,9 @@ use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
// in all likelihood, this will be superstructed so might as well start early eh?
|
||||
#[superstruct(
|
||||
variants(EIP7732),
|
||||
variants(EIP7732, NextFork),
|
||||
variant_attributes(
|
||||
derive(
|
||||
Debug,
|
||||
@@ -40,5 +41,51 @@ use tree_hash_derive::TreeHash;
|
||||
pub struct SignedExecutionEnvelope<E: EthSpec> {
|
||||
#[superstruct(only(EIP7732), partial_getter(rename = "message_eip7732"))]
|
||||
pub message: ExecutionEnvelopeEIP7732<E>,
|
||||
#[superstruct(only(NextFork), partial_getter(rename = "message_next_fork"))]
|
||||
pub message: crate::execution_envelope::ExecutionEnvelopeNextFork<E>,
|
||||
pub signature: Signature,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> SignedExecutionEnvelope<E> {
|
||||
pub fn message(&self) -> ExecutionEnvelopeRef<E> {
|
||||
match self {
|
||||
SignedExecutionEnvelope::EIP7732(ref signed) => {
|
||||
ExecutionEnvelopeRef::EIP7732(&signed.message)
|
||||
}
|
||||
SignedExecutionEnvelope::NextFork(ref signed) => {
|
||||
ExecutionEnvelopeRef::NextFork(&signed.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Verify `self.signature`.
|
||||
///
|
||||
/// The `parent_state` is the post-state of the beacon block with
|
||||
/// block_root = self.message.beacon_block_root
|
||||
pub fn verify_signature(
|
||||
&self,
|
||||
parent_state: &BeaconState<E>,
|
||||
genesis_validators_root: Hash256,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<bool, BeaconStateError> {
|
||||
let domain = spec.get_domain(
|
||||
parent_state.current_epoch(),
|
||||
Domain::BeaconBuilder,
|
||||
&parent_state.fork(),
|
||||
genesis_validators_root,
|
||||
);
|
||||
let pubkey = parent_state
|
||||
.validators()
|
||||
.get(self.message().builder_index() as usize)
|
||||
.and_then(|v| {
|
||||
let pk: Option<PublicKey> = v.pubkey.decompress().ok();
|
||||
pk
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
BeaconStateError::UnknownValidator(self.message().builder_index() as usize)
|
||||
})?;
|
||||
let message = self.message().signing_root(domain);
|
||||
|
||||
Ok(self.signature().verify(&pubkey, message))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user