mirror of
https://github.com/sigp/lighthouse.git
synced 2026-06-10 09:37:38 +00:00
Merge remote-tracking branch 'origin/gloas-filter-conflicting-voluntairy-exits' into glamsterdam-devnet-0
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@@ -138,6 +138,16 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
graffiti_settings: GraffitiSettings,
|
graffiti_settings: GraffitiSettings,
|
||||||
verification: ProduceBlockVerification,
|
verification: ProduceBlockVerification,
|
||||||
) -> Result<BlockProductionResult<T::EthSpec>, BlockProductionError> {
|
) -> Result<BlockProductionResult<T::EthSpec>, BlockProductionError> {
|
||||||
|
// Extract the parent's execution requests from the envelope (if parent was full).
|
||||||
|
let parent_execution_requests = if parent_payload_status == PayloadStatus::Full {
|
||||||
|
parent_envelope
|
||||||
|
.as_ref()
|
||||||
|
.map(|env| env.message.execution_requests.clone())
|
||||||
|
.ok_or(BlockProductionError::MissingParentExecutionPayload)?
|
||||||
|
} else {
|
||||||
|
ExecutionRequests::default()
|
||||||
|
};
|
||||||
|
|
||||||
// Part 1/3 (blocking)
|
// Part 1/3 (blocking)
|
||||||
//
|
//
|
||||||
// Perform the state advance and block-packing functions.
|
// Perform the state advance and block-packing functions.
|
||||||
@@ -146,6 +156,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
.graffiti_calculator
|
.graffiti_calculator
|
||||||
.get_graffiti(graffiti_settings)
|
.get_graffiti(graffiti_settings)
|
||||||
.await;
|
.await;
|
||||||
|
let parent_execution_requests_ref = parent_execution_requests.clone();
|
||||||
let (partial_beacon_block, state) = self
|
let (partial_beacon_block, state) = self
|
||||||
.task_executor
|
.task_executor
|
||||||
.spawn_blocking_handle(
|
.spawn_blocking_handle(
|
||||||
@@ -156,6 +167,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
produce_at_slot,
|
produce_at_slot,
|
||||||
randao_reveal,
|
randao_reveal,
|
||||||
graffiti,
|
graffiti,
|
||||||
|
&parent_execution_requests_ref,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
"produce_partial_beacon_block_gloas",
|
"produce_partial_beacon_block_gloas",
|
||||||
@@ -164,16 +176,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
.await
|
.await
|
||||||
.map_err(BlockProductionError::TokioJoin)??;
|
.map_err(BlockProductionError::TokioJoin)??;
|
||||||
|
|
||||||
// Extract the parent's execution requests from the envelope (if parent was full).
|
|
||||||
let parent_execution_requests = if parent_payload_status == PayloadStatus::Full {
|
|
||||||
parent_envelope
|
|
||||||
.as_ref()
|
|
||||||
.map(|env| env.message.execution_requests.clone())
|
|
||||||
.ok_or(BlockProductionError::MissingParentExecutionPayload)?
|
|
||||||
} else {
|
|
||||||
ExecutionRequests::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Part 2/3 (async)
|
// Part 2/3 (async)
|
||||||
//
|
//
|
||||||
// Produce the execution payload bid.
|
// Produce the execution payload bid.
|
||||||
@@ -224,6 +226,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
produce_at_slot: Slot,
|
produce_at_slot: Slot,
|
||||||
randao_reveal: Signature,
|
randao_reveal: Signature,
|
||||||
graffiti: Graffiti,
|
graffiti: Graffiti,
|
||||||
|
parent_execution_requests: &ExecutionRequests<T::EthSpec>,
|
||||||
) -> Result<(PartialBeaconBlock<T::EthSpec>, BeaconState<T::EthSpec>), BlockProductionError>
|
) -> Result<(PartialBeaconBlock<T::EthSpec>, BeaconState<T::EthSpec>), BlockProductionError>
|
||||||
{
|
{
|
||||||
// It is invalid to try to produce a block using a state from a future slot.
|
// It is invalid to try to produce a block using a state from a future slot.
|
||||||
@@ -258,6 +261,31 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
let (mut proposer_slashings, mut attester_slashings, mut voluntary_exits) =
|
let (mut proposer_slashings, mut attester_slashings, mut voluntary_exits) =
|
||||||
self.op_pool.get_slashings_and_exits(&state, &self.spec);
|
self.op_pool.get_slashings_and_exits(&state, &self.spec);
|
||||||
|
|
||||||
|
// Filter out voluntary exits that conflict with parent execution requests.
|
||||||
|
let mut exited_pubkeys = HashSet::with_capacity(
|
||||||
|
parent_execution_requests.withdrawals.len()
|
||||||
|
+ parent_execution_requests.consolidations.len(),
|
||||||
|
);
|
||||||
|
for req in &parent_execution_requests.withdrawals {
|
||||||
|
if req.amount == self.spec.full_exit_request_amount {
|
||||||
|
exited_pubkeys.insert(req.validator_pubkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for req in &parent_execution_requests.consolidations {
|
||||||
|
if req.source_pubkey != req.target_pubkey {
|
||||||
|
exited_pubkeys.insert(req.source_pubkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !exited_pubkeys.is_empty() {
|
||||||
|
voluntary_exits.retain(|exit| {
|
||||||
|
state
|
||||||
|
.validators()
|
||||||
|
.get(exit.message.validator_index as usize)
|
||||||
|
.map(|v| !exited_pubkeys.contains(&v.pubkey))
|
||||||
|
.unwrap_or(false)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
drop(slashings_and_exits_span);
|
drop(slashings_and_exits_span);
|
||||||
|
|
||||||
let eth1_data = state.eth1_data().clone();
|
let eth1_data = state.eth1_data().clone();
|
||||||
|
|||||||
@@ -360,7 +360,7 @@ pub fn spawn_notifier<T: BeaconChainTypes>(
|
|||||||
let block_info = if current_slot > head_slot {
|
let block_info = if current_slot > head_slot {
|
||||||
" … empty".to_string()
|
" … empty".to_string()
|
||||||
} else {
|
} else {
|
||||||
head_root.to_string()
|
head_root.short().to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
let block_hash = match beacon_chain.canonical_head.head_execution_status() {
|
let block_hash = match beacon_chain.canonical_head.head_execution_status() {
|
||||||
@@ -393,7 +393,7 @@ pub fn spawn_notifier<T: BeaconChainTypes>(
|
|||||||
info!(
|
info!(
|
||||||
peers = peer_count_pretty(connected_peer_count),
|
peers = peer_count_pretty(connected_peer_count),
|
||||||
exec_hash = block_hash,
|
exec_hash = block_hash,
|
||||||
finalized_root = %finalized_checkpoint.root,
|
finalized_root = %finalized_checkpoint.root.short(),
|
||||||
finalized_epoch = %finalized_checkpoint.epoch,
|
finalized_epoch = %finalized_checkpoint.epoch,
|
||||||
epoch = %current_epoch,
|
epoch = %current_epoch,
|
||||||
block = block_info,
|
block = block_info,
|
||||||
@@ -404,7 +404,7 @@ pub fn spawn_notifier<T: BeaconChainTypes>(
|
|||||||
metrics::set_gauge(&metrics::IS_SYNCED, 0);
|
metrics::set_gauge(&metrics::IS_SYNCED, 0);
|
||||||
info!(
|
info!(
|
||||||
peers = peer_count_pretty(connected_peer_count),
|
peers = peer_count_pretty(connected_peer_count),
|
||||||
finalized_root = %finalized_checkpoint.root,
|
finalized_root = %finalized_checkpoint.root.short(),
|
||||||
finalized_epoch = %finalized_checkpoint.epoch,
|
finalized_epoch = %finalized_checkpoint.epoch,
|
||||||
%head_slot,
|
%head_slot,
|
||||||
%current_slot,
|
%current_slot,
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ use rand::RngCore;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use ssz::{Decode, DecodeError, Encode};
|
use ssz::{Decode, DecodeError, Encode};
|
||||||
|
|
||||||
use crate::{core::Hash256, test_utils::TestRandom};
|
use crate::{
|
||||||
|
core::{Hash256, Hash256Ext},
|
||||||
|
test_utils::TestRandom,
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||||
#[derive(Default, Clone, Copy, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
#[derive(Default, Clone, Copy, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
||||||
@@ -20,13 +23,7 @@ impl fmt::Debug for ExecutionBlockHash {
|
|||||||
|
|
||||||
impl fmt::Display for ExecutionBlockHash {
|
impl fmt::Display for ExecutionBlockHash {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let hash = format!("{}", self.0);
|
self.0.short().fmt(f)
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"{}…{}",
|
|
||||||
&hash[..6],
|
|
||||||
&hash[hash.len().saturating_sub(4)..]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,3 +49,29 @@ pub type Hash64 = alloy_primitives::B64;
|
|||||||
pub type Address = alloy_primitives::Address;
|
pub type Address = alloy_primitives::Address;
|
||||||
pub type VersionedHash = Hash256;
|
pub type VersionedHash = Hash256;
|
||||||
pub type MerkleProof = Vec<Hash256>;
|
pub type MerkleProof = Vec<Hash256>;
|
||||||
|
|
||||||
|
/// Extension trait for `Hash256` to allow us to implement additional methods on it.
|
||||||
|
pub trait Hash256Ext {
|
||||||
|
fn short(&self) -> ShortenedHash<'_>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hash256Ext for Hash256 {
|
||||||
|
fn short(&self) -> ShortenedHash<'_> {
|
||||||
|
ShortenedHash(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ShortenedHash<'a>(&'a Hash256);
|
||||||
|
|
||||||
|
impl<'a> std::fmt::Display for ShortenedHash<'a> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
let hash: &[u8; 32] = self.0.as_ref();
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
// Format as hex, padded to 2 digits per byte.
|
||||||
|
// This outputs a consistent "0x1234...abcd" format.
|
||||||
|
"0x{:02x}{:02x}…{:02x}{:02x}",
|
||||||
|
hash[0], hash[1], hash[30], hash[31]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user