Gloas gossip boilerplate (#8700)

All the required boilerplate for gloas gossip. We'll include the gossip message processing logic in a separate PR


  


Co-Authored-By: Eitan Seri- Levi <eserilev@gmail.com>

Co-Authored-By: Jimmy Chen <jchen.tc@gmail.com>
This commit is contained in:
Eitan Seri-Levi
2026-01-27 23:12:48 -08:00
committed by GitHub
parent f7b5c7ee3f
commit b202e98dd9
11 changed files with 532 additions and 12 deletions

View File

@@ -40,6 +40,14 @@ pub struct GossipCache {
sync_committee_message: Option<Duration>,
/// Timeout for signed BLS to execution changes.
bls_to_execution_change: Option<Duration>,
/// Timeout for signed execution payload envelope.
execution_payload: Option<Duration>,
/// Timeout for execution payload bid.
execution_payload_bid: Option<Duration>,
/// Timeout for payload attestation message.
payload_attestation: Option<Duration>,
/// Timeout for proposer preferences.
proposer_preferences: Option<Duration>,
/// Timeout for light client finality updates.
light_client_finality_update: Option<Duration>,
/// Timeout for light client optimistic updates.
@@ -71,6 +79,14 @@ pub struct GossipCacheBuilder {
sync_committee_message: Option<Duration>,
/// Timeout for signed BLS to execution changes.
bls_to_execution_change: Option<Duration>,
/// Timeout for signed execution payload envelope.
execution_payload: Option<Duration>,
/// Timeout for execution payload bid.
execution_payload_bid: Option<Duration>,
/// Timeout for payload attestation message.
payload_attestation: Option<Duration>,
/// Timeout for proposer preferences.
proposer_preferences: Option<Duration>,
/// Timeout for light client finality updates.
light_client_finality_update: Option<Duration>,
/// Timeout for light client optimistic updates.
@@ -139,6 +155,30 @@ impl GossipCacheBuilder {
self
}
/// Timeout for signed execution payload envelope.
pub fn execution_payload_timeout(mut self, timeout: Duration) -> Self {
self.execution_payload = Some(timeout);
self
}
/// Timeout for execution payload bid.
pub fn execution_payload_bid_timeout(mut self, timeout: Duration) -> Self {
self.execution_payload_bid = Some(timeout);
self
}
/// Timeout for payload attestation message.
pub fn payload_attestation_timeout(mut self, timeout: Duration) -> Self {
self.payload_attestation = Some(timeout);
self
}
/// Timeout for proposer preferences.
pub fn proposer_preferences_timeout(mut self, timeout: Duration) -> Self {
self.proposer_preferences = Some(timeout);
self
}
/// Timeout for light client finality update messages.
pub fn light_client_finality_update_timeout(mut self, timeout: Duration) -> Self {
self.light_client_finality_update = Some(timeout);
@@ -165,6 +205,10 @@ impl GossipCacheBuilder {
signed_contribution_and_proof,
sync_committee_message,
bls_to_execution_change,
execution_payload,
execution_payload_bid,
payload_attestation,
proposer_preferences,
light_client_finality_update,
light_client_optimistic_update,
} = self;
@@ -182,6 +226,10 @@ impl GossipCacheBuilder {
signed_contribution_and_proof: signed_contribution_and_proof.or(default_timeout),
sync_committee_message: sync_committee_message.or(default_timeout),
bls_to_execution_change: bls_to_execution_change.or(default_timeout),
execution_payload: execution_payload.or(default_timeout),
execution_payload_bid: execution_payload_bid.or(default_timeout),
payload_attestation: payload_attestation.or(default_timeout),
proposer_preferences: proposer_preferences.or(default_timeout),
light_client_finality_update: light_client_finality_update.or(default_timeout),
light_client_optimistic_update: light_client_optimistic_update.or(default_timeout),
}
@@ -209,6 +257,10 @@ impl GossipCache {
GossipKind::SignedContributionAndProof => self.signed_contribution_and_proof,
GossipKind::SyncCommitteeMessage(_) => self.sync_committee_message,
GossipKind::BlsToExecutionChange => self.bls_to_execution_change,
GossipKind::ExecutionPayload => self.execution_payload,
GossipKind::ExecutionPayloadBid => self.execution_payload_bid,
GossipKind::PayloadAttestation => self.payload_attestation,
GossipKind::ProposerPreferences => self.proposer_preferences,
GossipKind::LightClientFinalityUpdate => self.light_client_finality_update,
GossipKind::LightClientOptimisticUpdate => self.light_client_optimistic_update,
};

View File

@@ -272,6 +272,10 @@ pub(crate) fn create_whitelist_filter(
add(AttesterSlashing);
add(SignedContributionAndProof);
add(BlsToExecutionChange);
add(ExecutionPayload);
add(ExecutionPayloadBid);
add(PayloadAttestation);
add(ProposerPreferences);
add(LightClientFinalityUpdate);
add(LightClientOptimisticUpdate);
for id in 0..spec.attestation_subnet_count {

View File

@@ -10,13 +10,14 @@ use std::sync::Arc;
use types::{
AttesterSlashing, AttesterSlashingBase, AttesterSlashingElectra, BlobSidecar,
DataColumnSidecar, DataColumnSubnetId, EthSpec, ForkContext, ForkName,
LightClientFinalityUpdate, LightClientOptimisticUpdate, ProposerSlashing,
SignedAggregateAndProof, SignedAggregateAndProofBase, SignedAggregateAndProofElectra,
SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockBase, SignedBeaconBlockBellatrix,
SignedBeaconBlockCapella, SignedBeaconBlockDeneb, SignedBeaconBlockElectra,
SignedBeaconBlockFulu, SignedBeaconBlockGloas, SignedBlsToExecutionChange,
SignedContributionAndProof, SignedVoluntaryExit, SingleAttestation, SubnetId,
SyncCommitteeMessage, SyncSubnetId,
LightClientFinalityUpdate, LightClientOptimisticUpdate, PayloadAttestationMessage,
ProposerSlashing, SignedAggregateAndProof, SignedAggregateAndProofBase,
SignedAggregateAndProofElectra, SignedBeaconBlock, SignedBeaconBlockAltair,
SignedBeaconBlockBase, SignedBeaconBlockBellatrix, SignedBeaconBlockCapella,
SignedBeaconBlockDeneb, SignedBeaconBlockElectra, SignedBeaconBlockFulu,
SignedBeaconBlockGloas, SignedBlsToExecutionChange, SignedContributionAndProof,
SignedExecutionPayloadBid, SignedExecutionPayloadEnvelope, SignedProposerPreferences,
SignedVoluntaryExit, SingleAttestation, SubnetId, SyncCommitteeMessage, SyncSubnetId,
};
#[derive(Debug, Clone, PartialEq)]
@@ -43,6 +44,14 @@ pub enum PubsubMessage<E: EthSpec> {
SyncCommitteeMessage(Box<(SyncSubnetId, SyncCommitteeMessage)>),
/// Gossipsub message for BLS to execution change messages.
BlsToExecutionChange(Box<SignedBlsToExecutionChange>),
/// Gossipsub message providing notification of a signed execution payload envelope.
ExecutionPayload(Box<SignedExecutionPayloadEnvelope<E>>),
/// Gossipsub message providing notification of a payload attestation message.
PayloadAttestation(Box<PayloadAttestationMessage>),
/// Gossipsub message providing notification of a signed execution payload bid.
ExecutionPayloadBid(Box<SignedExecutionPayloadBid>),
/// Gossipsub message providing notification of signed proposer preferences.
ProposerPreferences(Box<SignedProposerPreferences>),
/// Gossipsub message providing notification of a light client finality update.
LightClientFinalityUpdate(Box<LightClientFinalityUpdate<E>>),
/// Gossipsub message providing notification of a light client optimistic update.
@@ -146,6 +155,10 @@ impl<E: EthSpec> PubsubMessage<E> {
PubsubMessage::SignedContributionAndProof(_) => GossipKind::SignedContributionAndProof,
PubsubMessage::SyncCommitteeMessage(data) => GossipKind::SyncCommitteeMessage(data.0),
PubsubMessage::BlsToExecutionChange(_) => GossipKind::BlsToExecutionChange,
PubsubMessage::ExecutionPayload(_) => GossipKind::ExecutionPayload,
PubsubMessage::PayloadAttestation(_) => GossipKind::PayloadAttestation,
PubsubMessage::ExecutionPayloadBid(_) => GossipKind::ExecutionPayloadBid,
PubsubMessage::ProposerPreferences(_) => GossipKind::ProposerPreferences,
PubsubMessage::LightClientFinalityUpdate(_) => GossipKind::LightClientFinalityUpdate,
PubsubMessage::LightClientOptimisticUpdate(_) => {
GossipKind::LightClientOptimisticUpdate
@@ -350,6 +363,35 @@ impl<E: EthSpec> PubsubMessage<E> {
bls_to_execution_change,
)))
}
GossipKind::ExecutionPayload => {
let execution_payload_envelope =
SignedExecutionPayloadEnvelope::from_ssz_bytes(data)
.map_err(|e| format!("{:?}", e))?;
Ok(PubsubMessage::ExecutionPayload(Box::new(
execution_payload_envelope,
)))
}
GossipKind::ExecutionPayloadBid => {
let execution_payload_bid = SignedExecutionPayloadBid::from_ssz_bytes(data)
.map_err(|e| format!("{:?}", e))?;
Ok(PubsubMessage::ExecutionPayloadBid(Box::new(
execution_payload_bid,
)))
}
GossipKind::PayloadAttestation => {
let payload_attestation = PayloadAttestationMessage::from_ssz_bytes(data)
.map_err(|e| format!("{:?}", e))?;
Ok(PubsubMessage::PayloadAttestation(Box::new(
payload_attestation,
)))
}
GossipKind::ProposerPreferences => {
let proposer_preferences = SignedProposerPreferences::from_ssz_bytes(data)
.map_err(|e| format!("{:?}", e))?;
Ok(PubsubMessage::ProposerPreferences(Box::new(
proposer_preferences,
)))
}
GossipKind::LightClientFinalityUpdate => {
let light_client_finality_update = match fork_context
.get_fork_from_context_bytes(gossip_topic.fork_digest)
@@ -412,6 +454,10 @@ impl<E: EthSpec> PubsubMessage<E> {
PubsubMessage::SignedContributionAndProof(data) => data.as_ssz_bytes(),
PubsubMessage::SyncCommitteeMessage(data) => data.1.as_ssz_bytes(),
PubsubMessage::BlsToExecutionChange(data) => data.as_ssz_bytes(),
PubsubMessage::ExecutionPayload(data) => data.as_ssz_bytes(),
PubsubMessage::PayloadAttestation(data) => data.as_ssz_bytes(),
PubsubMessage::ExecutionPayloadBid(data) => data.as_ssz_bytes(),
PubsubMessage::ProposerPreferences(data) => data.as_ssz_bytes(),
PubsubMessage::LightClientFinalityUpdate(data) => data.as_ssz_bytes(),
PubsubMessage::LightClientOptimisticUpdate(data) => data.as_ssz_bytes(),
}
@@ -467,6 +513,38 @@ impl<E: EthSpec> std::fmt::Display for PubsubMessage<E> {
data.message.validator_index, data.message.to_execution_address
)
}
PubsubMessage::ExecutionPayload(data) => {
write!(
f,
"Signed Execution Payload Envelope: slot: {:?}, beacon block root: {:?}",
data.slot(),
data.beacon_block_root()
)
}
PubsubMessage::PayloadAttestation(data) => {
write!(
f,
"Payload Attestation Message: slot: {:?}, beacon block root: {:?}, payload present: {:?}, blob data available: {:?}",
data.data.slot,
data.data.beacon_block_root,
data.data.payload_present,
data.data.blob_data_available
)
}
PubsubMessage::ExecutionPayloadBid(data) => {
write!(
f,
"Execution payload bid: slot: {:?} value: {:?}",
data.message.slot, data.message.value
)
}
PubsubMessage::ProposerPreferences(data) => {
write!(
f,
"Proposer preferences: slot: {:?}, validator_index: {:?}",
data.message.proposal_slot, data.message.validator_index
)
}
PubsubMessage::LightClientFinalityUpdate(_data) => {
write!(f, "Light CLient Finality Update")
}

View File

@@ -29,6 +29,10 @@ pub const ATTESTER_SLASHING_TOPIC: &str = "attester_slashing";
pub const SIGNED_CONTRIBUTION_AND_PROOF_TOPIC: &str = "sync_committee_contribution_and_proof";
pub const SYNC_COMMITTEE_PREFIX_TOPIC: &str = "sync_committee_";
pub const BLS_TO_EXECUTION_CHANGE_TOPIC: &str = "bls_to_execution_change";
pub const EXECUTION_PAYLOAD: &str = "execution_payload";
pub const EXECUTION_PAYLOAD_BID: &str = "execution_payload_bid";
pub const PAYLOAD_ATTESTATION: &str = "payload_attestation_message";
pub const PROPOSER_PREFERENCES: &str = "proposer_preferences";
pub const LIGHT_CLIENT_FINALITY_UPDATE: &str = "light_client_finality_update";
pub const LIGHT_CLIENT_OPTIMISTIC_UPDATE: &str = "light_client_optimistic_update";
@@ -91,6 +95,13 @@ pub fn core_topics_to_subscribe<E: EthSpec>(
}
}
if fork_name.gloas_enabled() {
topics.push(GossipKind::ExecutionPayload);
topics.push(GossipKind::ExecutionPayloadBid);
topics.push(GossipKind::PayloadAttestation);
topics.push(GossipKind::ProposerPreferences);
}
topics
}
@@ -114,6 +125,10 @@ pub fn is_fork_non_core_topic(topic: &GossipTopic, _fork_name: ForkName) -> bool
| GossipKind::AttesterSlashing
| GossipKind::SignedContributionAndProof
| GossipKind::BlsToExecutionChange
| GossipKind::ExecutionPayload
| GossipKind::ExecutionPayloadBid
| GossipKind::PayloadAttestation
| GossipKind::ProposerPreferences
| GossipKind::LightClientFinalityUpdate
| GossipKind::LightClientOptimisticUpdate => false,
}
@@ -171,6 +186,14 @@ pub enum GossipKind {
SyncCommitteeMessage(SyncSubnetId),
/// Topic for validator messages which change their withdrawal address.
BlsToExecutionChange,
/// Topic for signed execution payload envelopes.
ExecutionPayload,
/// Topic for payload attestation messages.
PayloadAttestation,
/// Topic for signed execution payload bids.
ExecutionPayloadBid,
/// Topic for signed proposer preferences.
ProposerPreferences,
/// Topic for publishing finality updates for light clients.
LightClientFinalityUpdate,
/// Topic for publishing optimistic updates for light clients.
@@ -255,6 +278,10 @@ impl GossipTopic {
PROPOSER_SLASHING_TOPIC => GossipKind::ProposerSlashing,
ATTESTER_SLASHING_TOPIC => GossipKind::AttesterSlashing,
BLS_TO_EXECUTION_CHANGE_TOPIC => GossipKind::BlsToExecutionChange,
EXECUTION_PAYLOAD => GossipKind::ExecutionPayload,
EXECUTION_PAYLOAD_BID => GossipKind::ExecutionPayloadBid,
PAYLOAD_ATTESTATION => GossipKind::PayloadAttestation,
PROPOSER_PREFERENCES => GossipKind::ProposerPreferences,
LIGHT_CLIENT_FINALITY_UPDATE => GossipKind::LightClientFinalityUpdate,
LIGHT_CLIENT_OPTIMISTIC_UPDATE => GossipKind::LightClientOptimisticUpdate,
topic => match subnet_topic_index(topic) {
@@ -320,6 +347,10 @@ impl std::fmt::Display for GossipTopic {
format!("{}{}", DATA_COLUMN_SIDECAR_PREFIX, *column_subnet_id)
}
GossipKind::BlsToExecutionChange => BLS_TO_EXECUTION_CHANGE_TOPIC.into(),
GossipKind::ExecutionPayload => EXECUTION_PAYLOAD.into(),
GossipKind::PayloadAttestation => PAYLOAD_ATTESTATION.into(),
GossipKind::ExecutionPayloadBid => EXECUTION_PAYLOAD_BID.into(),
GossipKind::ProposerPreferences => PROPOSER_PREFERENCES.into(),
GossipKind::LightClientFinalityUpdate => LIGHT_CLIENT_FINALITY_UPDATE.into(),
GossipKind::LightClientOptimisticUpdate => LIGHT_CLIENT_OPTIMISTIC_UPDATE.into(),
};