This commit is contained in:
Eitan Seri-Levi
2026-04-30 16:22:17 +02:00
parent e23e3ac794
commit 313e2d946c
11 changed files with 97 additions and 92 deletions

View File

@@ -33,8 +33,8 @@ use types::{
ExecutionPayloadEnvelope, ExecutionPayloadGloas, ExecutionRequests, FullPayload, Graffiti,
Hash256, PayloadAttestation, ProposerSlashing, RelativeEpoch, SignedBeaconBlock,
SignedBlsToExecutionChange, SignedExecutionPayloadBid, SignedExecutionPayloadBidGloas,
SignedExecutionPayloadBidHeze, SignedExecutionPayloadEnvelope, SignedVoluntaryExit,
Slot, SyncAggregate, Withdrawal, Withdrawals,
SignedExecutionPayloadBidHeze, SignedExecutionPayloadEnvelope, SignedVoluntaryExit, Slot,
SyncAggregate, Withdrawal, Withdrawals,
};
use crate::pending_payload_envelopes::PendingEnvelopeData;
@@ -607,26 +607,24 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.unwrap_or_default();
let heze_bid = match signed_execution_payload_bid {
SignedExecutionPayloadBid::Heze(bid) => bid,
SignedExecutionPayloadBid::Gloas(gloas_bid) => {
SignedExecutionPayloadBidHeze {
message: ExecutionPayloadBidHeze {
parent_block_hash: gloas_bid.message.parent_block_hash,
parent_block_root: gloas_bid.message.parent_block_root,
block_hash: gloas_bid.message.block_hash,
prev_randao: gloas_bid.message.prev_randao,
fee_recipient: gloas_bid.message.fee_recipient,
gas_limit: gloas_bid.message.gas_limit,
builder_index: gloas_bid.message.builder_index,
slot: gloas_bid.message.slot,
value: gloas_bid.message.value,
execution_payment: gloas_bid.message.execution_payment,
blob_kzg_commitments: gloas_bid.message.blob_kzg_commitments,
execution_requests_root: gloas_bid.message.execution_requests_root,
inclusion_list_bits,
},
signature: gloas_bid.signature,
}
}
SignedExecutionPayloadBid::Gloas(gloas_bid) => SignedExecutionPayloadBidHeze {
message: ExecutionPayloadBidHeze {
parent_block_hash: gloas_bid.message.parent_block_hash,
parent_block_root: gloas_bid.message.parent_block_root,
block_hash: gloas_bid.message.block_hash,
prev_randao: gloas_bid.message.prev_randao,
fee_recipient: gloas_bid.message.fee_recipient,
gas_limit: gloas_bid.message.gas_limit,
builder_index: gloas_bid.message.builder_index,
slot: gloas_bid.message.slot,
value: gloas_bid.message.value,
execution_payment: gloas_bid.message.execution_payment,
blob_kzg_commitments: gloas_bid.message.blob_kzg_commitments,
execution_requests_root: gloas_bid.message.execution_requests_root,
inclusion_list_bits,
},
signature: gloas_bid.signature,
},
};
BeaconBlock::Heze(BeaconBlockHeze {
slot,

View File

@@ -57,6 +57,10 @@ impl<T: BeaconChainTypes> GossipVerifiedInclusionList<T> {
return Err(GossipInclusionListError::TooManyTransactions);
}
// TODO(focil): Spec says message.slot must equal current_slot with
// MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance. We currently also accept current_slot - 1
// and add an attestation-deadline check that is not in the spec.
// See: https://github.com/ethereum/consensus-specs/blob/master/specs/heze/p2p-interface.md#inclusion_list
if message_slot != current_slot && message_slot != current_slot - 1 {
return Err(GossipInclusionListError::InvalidSlot {
message_slot,

View File

@@ -251,9 +251,8 @@ mod tests {
use kzg::KzgCommitment;
use ssz_types::VariableList;
use types::{
Address, BeaconState, ChainSpec, EthSpec, ExecutionPayloadBidGloas,
ExecutionPayloadBidRef, MinimalEthSpec, ProposerPreferences, SignedProposerPreferences,
Slot,
Address, BeaconState, ChainSpec, EthSpec, ExecutionPayloadBidGloas, ExecutionPayloadBidRef,
MinimalEthSpec, ProposerPreferences, SignedProposerPreferences, Slot,
};
use super::verify_bid_consistency;

View File

@@ -166,10 +166,12 @@ impl TestContext {
);
let message = bid.signing_root(domain);
let signature = self.keypairs[bid.builder_index as usize].sk.sign(message);
Arc::new(SignedExecutionPayloadBid::Gloas(SignedExecutionPayloadBidGloas {
message: bid,
signature,
}))
Arc::new(SignedExecutionPayloadBid::Gloas(
SignedExecutionPayloadBidGloas {
message: bid,
signature,
},
))
}
fn gossip_ctx(&self) -> GossipVerificationContext<'_, T> {
@@ -423,16 +425,18 @@ fn execution_payment_nonzero() {
let slot = Slot::new(0);
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
let bid = Arc::new(SignedExecutionPayloadBid::Gloas(SignedExecutionPayloadBidGloas {
message: ExecutionPayloadBidGloas {
slot,
gas_limit: 30_000_000,
execution_payment: 42,
parent_block_root: ctx.genesis_block_root,
..ExecutionPayloadBidGloas::default()
let bid = Arc::new(SignedExecutionPayloadBid::Gloas(
SignedExecutionPayloadBidGloas {
message: ExecutionPayloadBidGloas {
slot,
gas_limit: 30_000_000,
execution_payment: 42,
parent_block_root: ctx.genesis_block_root,
..ExecutionPayloadBidGloas::default()
},
signature: Signature::empty(),
},
signature: Signature::empty(),
}));
));
let result = GossipVerifiedPayloadBid::new(bid, &gossip);
assert!(matches!(
result,
@@ -579,19 +583,21 @@ fn invalid_blob_kzg_commitments() {
.map(|_| KzgCommitment::empty_for_testing())
.collect();
let bid = Arc::new(SignedExecutionPayloadBid::Gloas(SignedExecutionPayloadBidGloas {
message: ExecutionPayloadBidGloas {
slot,
builder_index: 0,
fee_recipient: Address::ZERO,
gas_limit: 30_000_000,
value: 0,
parent_block_root: ctx.genesis_block_root,
blob_kzg_commitments: VariableList::new(commitments).unwrap(),
..ExecutionPayloadBidGloas::default()
let bid = Arc::new(SignedExecutionPayloadBid::Gloas(
SignedExecutionPayloadBidGloas {
message: ExecutionPayloadBidGloas {
slot,
builder_index: 0,
fee_recipient: Address::ZERO,
gas_limit: 30_000_000,
value: 0,
parent_block_root: ctx.genesis_block_root,
blob_kzg_commitments: VariableList::new(commitments).unwrap(),
..ExecutionPayloadBidGloas::default()
},
signature: Signature::empty(),
},
signature: Signature::empty(),
}));
));
let result = GossipVerifiedPayloadBid::new(bid, &gossip);
assert!(matches!(
result,

View File

@@ -102,33 +102,33 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.spec
.is_focil_enabled_for_epoch(block_slot.epoch(T::EthSpec::slots_per_epoch()))
{
let payload_block_hash = envelope.envelope.message().payload.block_hash;
let il_slot = block_slot.saturating_sub(1_u64);
let il_txs = chain_ref
.inclusion_list_cache
.read()
.get_inclusion_list_transactions(il_slot, true)
.unwrap_or_default()
.into_iter()
.map(|tx| tx.to_vec())
.collect::<Vec<Vec<u8>>>();
let payload_block_hash = envelope.envelope.message().payload.block_hash;
let il_slot = block_slot.saturating_sub(1_u64);
let il_txs = chain_ref
.inclusion_list_cache
.read()
.get_inclusion_list_transactions(il_slot, true)
.unwrap_or_default()
.into_iter()
.map(|tx| tx.to_vec())
.collect::<Vec<Vec<u8>>>();
if let Some(execution_layer) = chain_ref.execution_layer.as_ref() {
let satisfied = execution_layer
.is_inclusion_list_satisfied(payload_block_hash, il_txs)
.await
.unwrap_or(false);
if let Some(execution_layer) = chain_ref.execution_layer.as_ref() {
let satisfied = execution_layer
.is_inclusion_list_satisfied(payload_block_hash, il_txs)
.await
.unwrap_or(false);
if let Err(e) = chain_ref
.record_payload_inclusion_list_satisfaction(block_root, satisfied)
.await
{
warn!(
error = ?e,
"Failed to record IL satisfaction"
);
}
if let Err(e) = chain_ref
.record_payload_inclusion_list_satisfaction(block_root, satisfied)
.await
{
warn!(
error = ?e,
"Failed to record IL satisfaction"
);
}
}
}
match executed_envelope {

View File

@@ -756,9 +756,7 @@ impl HttpJsonRpc {
pub async fn update_payload_with_inclusion_list<E: EthSpec>(&self) {}
pub async fn get_inclusion_list<E: EthSpec>(
&self,
) -> Result<Option<Vec<String>>, Error> {
pub async fn get_inclusion_list<E: EthSpec>(&self) -> Result<Option<Vec<String>>, Error> {
let params = json!([]);
self.rpc_request(

View File

@@ -2008,11 +2008,7 @@ impl<E: EthSpec> ExecutionLayer<E> {
pub async fn get_inclusion_list(&self) -> Result<Transactions<E>, Error> {
debug!("Requesting inclusion list from EL");
let raw_transactions = self
.engine()
.api
.get_inclusion_list::<E>()
.await?;
let raw_transactions = self.engine().api.get_inclusion_list::<E>().await?;
let mut transactions = vec![];

View File

@@ -16,9 +16,9 @@ use types::{
SignedBeaconBlockCapella, SignedBeaconBlockDeneb, SignedBeaconBlockElectra,
SignedBeaconBlockFulu, SignedBeaconBlockGloas, SignedBeaconBlockHeze,
SignedBlsToExecutionChange, SignedContributionAndProof, SignedExecutionPayloadBid,
SignedExecutionPayloadBidGloas, SignedExecutionPayloadBidHeze,
SignedExecutionPayloadEnvelope, SignedInclusionList, SignedProposerPreferences,
SignedVoluntaryExit, SingleAttestation, SubnetId, SyncCommitteeMessage, SyncSubnetId,
SignedExecutionPayloadBidGloas, SignedExecutionPayloadBidHeze, SignedExecutionPayloadEnvelope,
SignedInclusionList, SignedProposerPreferences, SignedVoluntaryExit, SingleAttestation,
SubnetId, SyncCommitteeMessage, SyncSubnetId,
};
#[derive(Debug, Clone, PartialEq)]
@@ -616,7 +616,8 @@ impl<E: EthSpec> std::fmt::Display for PubsubMessage<E> {
write!(
f,
"Execution payload bid: slot: {:?} value: {:?}",
data.message().slot(), data.message().value()
data.message().slot(),
data.message().value()
)
}
PubsubMessage::ProposerPreferences(data) => {