add focil epoch activation

This commit is contained in:
Eitan Seri-Levi
2025-02-01 23:54:50 +03:00
parent d3368f59a3
commit f31c0b69e3
5 changed files with 123 additions and 11 deletions

View File

@@ -136,6 +136,7 @@ pub struct BeaconProcessorQueueLengths {
lc_optimistic_update_queue: usize, lc_optimistic_update_queue: usize,
lc_finality_update_queue: usize, lc_finality_update_queue: usize,
lc_update_range_queue: usize, lc_update_range_queue: usize,
gossip_inclusion_list_queue: usize,
api_request_p0_queue: usize, api_request_p0_queue: usize,
api_request_p1_queue: usize, api_request_p1_queue: usize,
} }
@@ -204,6 +205,8 @@ impl BeaconProcessorQueueLengths {
lc_optimistic_update_queue: 512, lc_optimistic_update_queue: 512,
lc_finality_update_queue: 512, lc_finality_update_queue: 512,
lc_update_range_queue: 512, lc_update_range_queue: 512,
// TODO(focil) pick proper values
gossip_inclusion_list_queue: 64,
api_request_p0_queue: 1024, api_request_p0_queue: 1024,
api_request_p1_queue: 1024, api_request_p1_queue: 1024,
}) })
@@ -625,6 +628,7 @@ pub enum Work<E: EthSpec> {
LightClientOptimisticUpdateRequest(BlockingFn), LightClientOptimisticUpdateRequest(BlockingFn),
LightClientFinalityUpdateRequest(BlockingFn), LightClientFinalityUpdateRequest(BlockingFn),
LightClientUpdatesByRangeRequest(BlockingFn), LightClientUpdatesByRangeRequest(BlockingFn),
GossipInclusionList(BlockingFn),
ApiRequestP0(BlockingOrAsync), ApiRequestP0(BlockingOrAsync),
ApiRequestP1(BlockingOrAsync), ApiRequestP1(BlockingOrAsync),
} }
@@ -677,6 +681,7 @@ pub enum WorkType {
LightClientOptimisticUpdateRequest, LightClientOptimisticUpdateRequest,
LightClientFinalityUpdateRequest, LightClientFinalityUpdateRequest,
LightClientUpdatesByRangeRequest, LightClientUpdatesByRangeRequest,
GossipInclusionList,
ApiRequestP0, ApiRequestP0,
ApiRequestP1, ApiRequestP1,
} }
@@ -734,6 +739,7 @@ impl<E: EthSpec> Work<E> {
Work::UnknownLightClientOptimisticUpdate { .. } => { Work::UnknownLightClientOptimisticUpdate { .. } => {
WorkType::UnknownLightClientOptimisticUpdate WorkType::UnknownLightClientOptimisticUpdate
} }
Work::GossipInclusionList { .. } => WorkType::GossipInclusionList,
Work::ApiRequestP0 { .. } => WorkType::ApiRequestP0, Work::ApiRequestP0 { .. } => WorkType::ApiRequestP0,
Work::ApiRequestP1 { .. } => WorkType::ApiRequestP1, Work::ApiRequestP1 { .. } => WorkType::ApiRequestP1,
} }
@@ -909,6 +915,8 @@ impl<E: EthSpec> BeaconProcessor<E> {
let mut lc_finality_update_queue = FifoQueue::new(queue_lengths.lc_finality_update_queue); let mut lc_finality_update_queue = FifoQueue::new(queue_lengths.lc_finality_update_queue);
let mut lc_update_range_queue = FifoQueue::new(queue_lengths.lc_update_range_queue); let mut lc_update_range_queue = FifoQueue::new(queue_lengths.lc_update_range_queue);
let mut gossip_inclusion_list_queue =
FifoQueue::new(queue_lengths.gossip_inclusion_list_queue);
let mut api_request_p0_queue = FifoQueue::new(queue_lengths.api_request_p0_queue); let mut api_request_p0_queue = FifoQueue::new(queue_lengths.api_request_p0_queue);
let mut api_request_p1_queue = FifoQueue::new(queue_lengths.api_request_p1_queue); let mut api_request_p1_queue = FifoQueue::new(queue_lengths.api_request_p1_queue);
@@ -1180,6 +1188,9 @@ impl<E: EthSpec> BeaconProcessor<E> {
None None
} }
} }
// TODO(focil) figure out priority and maybe introduce batching
} else if let Some(item) = gossip_inclusion_list_queue.pop() {
Some(item)
// Check sync committee messages after attestations as their rewards are lesser // Check sync committee messages after attestations as their rewards are lesser
// and they don't influence fork choice. // and they don't influence fork choice.
} else if let Some(item) = sync_contribution_queue.pop() { } else if let Some(item) = sync_contribution_queue.pop() {
@@ -1412,6 +1423,9 @@ impl<E: EthSpec> BeaconProcessor<E> {
Work::UnknownBlockSamplingRequest { .. } => { Work::UnknownBlockSamplingRequest { .. } => {
unknown_block_sampling_request_queue.push(work, work_id, &self.log) unknown_block_sampling_request_queue.push(work, work_id, &self.log)
} }
Work::GossipInclusionList { .. } => {
gossip_inclusion_list_queue.push(work, work_id, &self.log)
}
Work::ApiRequestP0 { .. } => { Work::ApiRequestP0 { .. } => {
api_request_p0_queue.push(work, work_id, &self.log) api_request_p0_queue.push(work, work_id, &self.log)
} }
@@ -1479,6 +1493,7 @@ impl<E: EthSpec> BeaconProcessor<E> {
WorkType::LightClientFinalityUpdateRequest => { WorkType::LightClientFinalityUpdateRequest => {
lc_finality_update_queue.len() lc_finality_update_queue.len()
} }
WorkType::GossipInclusionList => gossip_inclusion_list_queue.len(),
WorkType::LightClientUpdatesByRangeRequest => lc_update_range_queue.len(), WorkType::LightClientUpdatesByRangeRequest => lc_update_range_queue.len(),
WorkType::ApiRequestP0 => api_request_p0_queue.len(), WorkType::ApiRequestP0 => api_request_p0_queue.len(),
WorkType::ApiRequestP1 => api_request_p1_queue.len(), WorkType::ApiRequestP1 => api_request_p1_queue.len(),
@@ -1633,9 +1648,8 @@ impl<E: EthSpec> BeaconProcessor<E> {
| Work::LightClientBootstrapRequest(process_fn) | Work::LightClientBootstrapRequest(process_fn)
| Work::LightClientOptimisticUpdateRequest(process_fn) | Work::LightClientOptimisticUpdateRequest(process_fn)
| Work::LightClientFinalityUpdateRequest(process_fn) | Work::LightClientFinalityUpdateRequest(process_fn)
| Work::LightClientUpdatesByRangeRequest(process_fn) => { | Work::LightClientUpdatesByRangeRequest(process_fn)
task_spawner.spawn_blocking(process_fn) | Work::GossipInclusionList(process_fn) => task_spawner.spawn_blocking(process_fn),
}
}; };
} }
} }

View File

@@ -9,12 +9,13 @@ use std::sync::Arc;
use types::{ use types::{
Attestation, AttestationBase, AttestationElectra, AttesterSlashing, AttesterSlashingBase, Attestation, AttestationBase, AttestationElectra, AttesterSlashing, AttesterSlashingBase,
AttesterSlashingElectra, BlobSidecar, DataColumnSidecar, DataColumnSubnetId, EthSpec, AttesterSlashingElectra, BlobSidecar, DataColumnSidecar, DataColumnSubnetId, EthSpec,
ForkContext, ForkName, InclusionList, LightClientFinalityUpdate, LightClientOptimisticUpdate, ForkContext, ForkName, LightClientFinalityUpdate, LightClientOptimisticUpdate,
ProposerSlashing, SignedAggregateAndProof, SignedAggregateAndProofBase, ProposerSlashing, SignedAggregateAndProof, SignedAggregateAndProofBase,
SignedAggregateAndProofElectra, SignedBeaconBlock, SignedBeaconBlockAltair, SignedAggregateAndProofElectra, SignedBeaconBlock, SignedBeaconBlockAltair,
SignedBeaconBlockBase, SignedBeaconBlockBellatrix, SignedBeaconBlockCapella, SignedBeaconBlockBase, SignedBeaconBlockBellatrix, SignedBeaconBlockCapella,
SignedBeaconBlockDeneb, SignedBeaconBlockElectra, SignedBlsToExecutionChange, SignedBeaconBlockDeneb, SignedBeaconBlockElectra, SignedBlsToExecutionChange,
SignedContributionAndProof, SignedVoluntaryExit, SubnetId, SyncCommitteeMessage, SyncSubnetId, SignedContributionAndProof, SignedInclusionList, SignedVoluntaryExit, SubnetId,
SyncCommitteeMessage, SyncSubnetId,
}; };
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@@ -46,7 +47,7 @@ pub enum PubsubMessage<E: EthSpec> {
/// Gossipsub message providing notification of a light client optimistic update. /// Gossipsub message providing notification of a light client optimistic update.
LightClientOptimisticUpdate(Box<LightClientOptimisticUpdate<E>>), LightClientOptimisticUpdate(Box<LightClientOptimisticUpdate<E>>),
/// Gossipsub message providing notification of an inclusion list. /// Gossipsub message providing notification of an inclusion list.
InclusionList(Box<InclusionList<E>>), InclusionList(Box<SignedInclusionList<E>>),
} }
// Implements the `DataTransform` trait of gossipsub to employ snappy compression // Implements the `DataTransform` trait of gossipsub to employ snappy compression
@@ -394,9 +395,27 @@ impl<E: EthSpec> PubsubMessage<E> {
))) )))
} }
GossipKind::InclusionList => { GossipKind::InclusionList => {
let il = match fork_context.from_context_bytes(gossip_topic.fork_digest) {
InclusionList::from_ssz_bytes(data).map_err(|e| format!("{:?}", e))?; Some(fork) if fork.electra_enabled() => {
Ok(PubsubMessage::InclusionList(Box::new(il))) let il = SignedInclusionList::from_ssz_bytes(data)
.map_err(|e| format!("{:?}", e))?;
let focil_enabled = fork_context.spec.is_focil_enabled_for_epoch(
il.message.slot.epoch(E::slots_per_epoch()),
);
if focil_enabled {
Ok(PubsubMessage::InclusionList(Box::new(il)))
} else {
Err(format!(
"inclusion_List topic invalid for given fork digest {:?}",
gossip_topic.fork_digest
))
}
}
Some(_) | None => Err(format!(
"inclusion_List topic invalid for given fork digest {:?}",
gossip_topic.fork_digest
)),
}
} }
} }
} }

View File

@@ -298,6 +298,30 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
}) })
} }
/// Create a new `Work` event for some inclusion list.
pub fn send_gossip_inclusion_list(
self: &Arc<Self>,
message_id: MessageId,
peer_id: PeerId,
signed_inclusion_list: SignedInclusionList<T::EthSpec>,
seen_timestamp: Duration,
) -> Result<(), Error<T::EthSpec>> {
let processor = self.clone();
let process_fn = move || {
processor.process_gossip_inclusion_list(
message_id,
peer_id,
signed_inclusion_list,
seen_timestamp,
)
};
self.try_send(BeaconWorkEvent {
drop_during_sync: true,
work: Work::GossipInclusionList(Box::new(process_fn)),
})
}
/// Create a new `Work` event for some sync committee contribution. /// Create a new `Work` event for some sync committee contribution.
pub fn send_gossip_sync_contribution( pub fn send_gossip_sync_contribution(
self: &Arc<Self>, self: &Arc<Self>,

View File

@@ -541,8 +541,20 @@ impl<T: BeaconChainTypes> Router<T> {
bls_to_execution_change, bls_to_execution_change,
), ),
), ),
PubsubMessage::InclusionList(_il) => { PubsubMessage::InclusionList(inclusion_list) => {
// TODO(focil) trace!(
self.log,
"Received inclusion list";
"peer_id" => %peer_id
);
self.handle_beacon_processor_send_result(
self.network_beacon_processor.send_gossip_inclusion_list(
message_id,
peer_id,
*inclusion_list,
timestamp_now(),
),
)
} }
} }
} }

View File

@@ -208,6 +208,11 @@ pub struct ChainSpec {
pub number_of_columns: usize, pub number_of_columns: usize,
pub samples_per_slot: u64, pub samples_per_slot: u64,
/*
* FOCIL params
*/
pub eip7805_fork_epoch: Option<Epoch>,
/* /*
* Networking * Networking
*/ */
@@ -439,6 +444,20 @@ impl ChainSpec {
}) })
} }
/// Returns true if the given epoch is greater than or equal to the `EIP7805_FORK_EPOCH`.
pub fn is_focil_enabled_for_epoch(&self, block_epoch: Epoch) -> bool {
self.eip7805_fork_epoch.map_or(false, |eip7805_fork_epoch| {
block_epoch >= eip7805_fork_epoch
})
}
/// Returns true if `EIP7805_FORK_EPOCH` is set and is not set to `FAR_FUTURE_EPOCH`.
pub fn is_focil_scheduled(&self) -> bool {
self.eip7805_fork_epoch.map_or(false, |eip7805_fork_epoch| {
eip7805_fork_epoch != self.far_future_epoch
})
}
/// Returns a full `Fork` struct for a given epoch. /// Returns a full `Fork` struct for a given epoch.
pub fn fork_at_epoch(&self, epoch: Epoch) -> Fork { pub fn fork_at_epoch(&self, epoch: Epoch) -> Fork {
let current_fork_name = self.fork_name_at_epoch(epoch); let current_fork_name = self.fork_name_at_epoch(epoch);
@@ -827,6 +846,11 @@ impl ChainSpec {
number_of_columns: 128, number_of_columns: 128,
samples_per_slot: 8, samples_per_slot: 8,
/*
* FOCIL params
*/
eip7805_fork_epoch: None,
/* /*
* Network specific * Network specific
*/ */
@@ -935,6 +959,8 @@ impl ChainSpec {
.expect("calculation does not overflow"), .expect("calculation does not overflow"),
// PeerDAS // PeerDAS
eip7594_fork_epoch: None, eip7594_fork_epoch: None,
// FOCIL
eip7805_fork_epoch: None,
// Other // Other
network_id: 2, // lighthouse testnet network id network_id: 2, // lighthouse testnet network id
deposit_chain_id: 5, deposit_chain_id: 5,
@@ -1151,6 +1177,12 @@ impl ChainSpec {
data_column_sidecar_subnet_count: 128, data_column_sidecar_subnet_count: 128,
number_of_columns: 128, number_of_columns: 128,
samples_per_slot: 8, samples_per_slot: 8,
/*
* FOCIL params
*/
eip7805_fork_epoch: None,
/* /*
* Network specific * Network specific
*/ */
@@ -1282,6 +1314,11 @@ pub struct Config {
#[serde(deserialize_with = "deserialize_fork_epoch")] #[serde(deserialize_with = "deserialize_fork_epoch")]
pub eip7594_fork_epoch: Option<MaybeQuoted<Epoch>>, pub eip7594_fork_epoch: Option<MaybeQuoted<Epoch>>,
#[serde(default)]
#[serde(serialize_with = "serialize_fork_epoch")]
#[serde(deserialize_with = "deserialize_fork_epoch")]
pub eip7805_fork_epoch: Option<MaybeQuoted<Epoch>>,
#[serde(with = "serde_utils::quoted_u64")] #[serde(with = "serde_utils::quoted_u64")]
seconds_per_slot: u64, seconds_per_slot: u64,
#[serde(with = "serde_utils::quoted_u64")] #[serde(with = "serde_utils::quoted_u64")]
@@ -1681,6 +1718,10 @@ impl Config {
.eip7594_fork_epoch .eip7594_fork_epoch
.map(|epoch| MaybeQuoted { value: epoch }), .map(|epoch| MaybeQuoted { value: epoch }),
eip7805_fork_epoch: spec
.eip7805_fork_epoch
.map(|epoch| MaybeQuoted { value: epoch }),
seconds_per_slot: spec.seconds_per_slot, seconds_per_slot: spec.seconds_per_slot,
seconds_per_eth1_block: spec.seconds_per_eth1_block, seconds_per_eth1_block: spec.seconds_per_eth1_block,
min_validator_withdrawability_delay: spec.min_validator_withdrawability_delay, min_validator_withdrawability_delay: spec.min_validator_withdrawability_delay,
@@ -1761,6 +1802,7 @@ impl Config {
electra_fork_epoch, electra_fork_epoch,
electra_fork_version, electra_fork_version,
eip7594_fork_epoch, eip7594_fork_epoch,
eip7805_fork_epoch,
seconds_per_slot, seconds_per_slot,
seconds_per_eth1_block, seconds_per_eth1_block,
min_validator_withdrawability_delay, min_validator_withdrawability_delay,
@@ -1824,6 +1866,7 @@ impl Config {
electra_fork_epoch: electra_fork_epoch.map(|q| q.value), electra_fork_epoch: electra_fork_epoch.map(|q| q.value),
electra_fork_version, electra_fork_version,
eip7594_fork_epoch: eip7594_fork_epoch.map(|q| q.value), eip7594_fork_epoch: eip7594_fork_epoch.map(|q| q.value),
eip7805_fork_epoch: eip7805_fork_epoch.map(|q| q.value),
seconds_per_slot, seconds_per_slot,
seconds_per_eth1_block, seconds_per_eth1_block,
min_validator_withdrawability_delay, min_validator_withdrawability_delay,