Skip to content

Commit

Permalink
Add EIP-7594 boilerplate code.
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmygchen committed May 7, 2024
1 parent a857546 commit cef8853
Show file tree
Hide file tree
Showing 74 changed files with 1,415 additions and 221 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ PROFILE ?= release

# List of all hard forks. This list is used to set env variables for several tests so that
# they run for different forks.
FORKS=phase0 altair bellatrix capella deneb electra
FORKS=phase0 altair bellatrix capella deneb electra eip7594

# Extra flags for Cargo
CARGO_INSTALL_EXTRA_FLAGS?=
Expand Down
3 changes: 2 additions & 1 deletion beacon_node/beacon_chain/src/attestation_rewards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
| BeaconState::Bellatrix(_)
| BeaconState::Capella(_)
| BeaconState::Deneb(_)
| BeaconState::Electra(_) => self.compute_attestation_rewards_altair(state, validators),
| BeaconState::Electra(_)
| BeaconState::Eip7594(_) => self.compute_attestation_rewards_altair(state, validators),
}
}

Expand Down
2 changes: 1 addition & 1 deletion beacon_node/beacon_chain/src/attestation_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1067,7 +1067,7 @@ pub fn verify_propagation_slot_range<S: SlotClock, E: EthSpec>(
one_epoch_prior
}
// EIP-7045
ForkName::Deneb | ForkName::Electra => one_epoch_prior
ForkName::Deneb | ForkName::Electra | ForkName::Eip7594 => one_epoch_prior
.epoch(E::slots_per_epoch())
.start_slot(E::slots_per_epoch()),
};
Expand Down
5 changes: 3 additions & 2 deletions beacon_node/beacon_chain/src/beacon_block_streamer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ use types::{
SignedBlindedBeaconBlock, Slot,
};
use types::{
ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadElectra,
ExecutionPayloadHeader,
ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadEip7594,
ExecutionPayloadElectra, ExecutionPayloadHeader,
};

#[derive(PartialEq)]
Expand Down Expand Up @@ -99,6 +99,7 @@ fn reconstruct_default_header_block<E: EthSpec>(
ForkName::Capella => ExecutionPayloadCapella::default().into(),
ForkName::Deneb => ExecutionPayloadDeneb::default().into(),
ForkName::Electra => ExecutionPayloadElectra::default().into(),
ForkName::Eip7594 => ExecutionPayloadEip7594::default().into(),
ForkName::Base | ForkName::Altair => {
return Err(Error::PayloadReconstruction(format!(
"Block with fork variant {} has execution payload",
Expand Down
48 changes: 44 additions & 4 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5005,7 +5005,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
BeaconState::Bellatrix(_)
| BeaconState::Capella(_)
| BeaconState::Deneb(_)
| BeaconState::Electra(_) => {
| BeaconState::Electra(_)
| BeaconState::Eip7594(_) => {
let prepare_payload_handle = get_execution_payload(
self.clone(),
&state,
Expand Down Expand Up @@ -5399,6 +5400,44 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
execution_payload_value,
)
}
BeaconState::Eip7594(_) => {
let (payload, kzg_commitments, maybe_blobs_and_proofs, execution_payload_value) =
block_contents
.ok_or(BlockProductionError::MissingExecutionPayload)?
.deconstruct();

(
BeaconBlock::Eip7594(BeaconBlockEip7594 {
slot,
proposer_index,
parent_root,
state_root: Hash256::zero(),
body: BeaconBlockBodyEip7594 {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings: proposer_slashings.into(),
attester_slashings: attester_slashings.into(),
attestations: attestations.into(),
deposits: deposits.into(),
voluntary_exits: voluntary_exits.into(),
sync_aggregate: sync_aggregate
.ok_or(BlockProductionError::MissingSyncAggregate)?,
execution_payload: payload
.try_into()
.map_err(|_| BlockProductionError::InvalidPayloadFork)?,
bls_to_execution_changes: bls_to_execution_changes.into(),
blob_kzg_commitments: kzg_commitments.ok_or(
BlockProductionError::MissingKzgCommitment(
"Kzg commitments missing from block contents".to_string(),
),
)?,
},
}),
maybe_blobs_and_proofs,
execution_payload_value,
)
}
};

let block = SignedBeaconBlock::from_block(
Expand Down Expand Up @@ -5721,7 +5760,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let prepare_slot_fork = self.spec.fork_name_at_slot::<T::EthSpec>(prepare_slot);
let withdrawals = match prepare_slot_fork {
ForkName::Base | ForkName::Altair | ForkName::Bellatrix => None,
ForkName::Capella | ForkName::Deneb | ForkName::Electra => {
ForkName::Capella | ForkName::Deneb | ForkName::Electra | ForkName::Eip7594 => {
let chain = self.clone();
self.spawn_blocking_handle(
move || {
Expand All @@ -5736,7 +5775,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {

let parent_beacon_block_root = match prepare_slot_fork {
ForkName::Base | ForkName::Altair | ForkName::Bellatrix | ForkName::Capella => None,
ForkName::Deneb | ForkName::Electra => {
ForkName::Deneb | ForkName::Electra | ForkName::Eip7594 => {
Some(pre_payload_attributes.parent_beacon_block_root)
}
};
Expand Down Expand Up @@ -6781,7 +6820,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
| ForkName::Bellatrix
| ForkName::Capella
| ForkName::Deneb
| ForkName::Electra => {
| ForkName::Electra
| ForkName::Eip7594 => {
LightClientBootstrap::from_beacon_state(&mut state, &block, &self.spec)
.map(|bootstrap| Some((bootstrap, fork_name)))
.map_err(Error::LightClientError)
Expand Down
11 changes: 7 additions & 4 deletions beacon_node/beacon_chain/src/execution_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,15 +412,18 @@ pub fn get_execution_payload<T: BeaconChainTypes>(
let latest_execution_payload_header_block_hash =
state.latest_execution_payload_header()?.block_hash();
let withdrawals = match state {
&BeaconState::Capella(_) | &BeaconState::Deneb(_) | &BeaconState::Electra(_) => {
Some(get_expected_withdrawals(state, spec)?.into())
}
&BeaconState::Capella(_)
| &BeaconState::Deneb(_)
| &BeaconState::Electra(_)
| &BeaconState::Eip7594(_) => Some(get_expected_withdrawals(state, spec)?.into()),
&BeaconState::Bellatrix(_) => None,
// These shouldn't happen but they're here to make the pattern irrefutable
&BeaconState::Base(_) | &BeaconState::Altair(_) => None,
};
let parent_beacon_block_root = match state {
BeaconState::Deneb(_) | BeaconState::Electra(_) => Some(parent_block_root),
BeaconState::Deneb(_) | BeaconState::Electra(_) | BeaconState::Eip7594(_) => {
Some(parent_block_root)
}
BeaconState::Bellatrix(_) | BeaconState::Capella(_) => None,
// These shouldn't happen but they're here to make the pattern irrefutable
BeaconState::Base(_) | BeaconState::Altair(_) => None,
Expand Down
12 changes: 6 additions & 6 deletions beacon_node/beacon_chain/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -882,9 +882,9 @@ where
| SignedBeaconBlock::Altair(_)
| SignedBeaconBlock::Bellatrix(_)
| SignedBeaconBlock::Capella(_) => (signed_block, None),
SignedBeaconBlock::Deneb(_) | SignedBeaconBlock::Electra(_) => {
(signed_block, block_response.blob_items)
}
SignedBeaconBlock::Deneb(_)
| SignedBeaconBlock::Electra(_)
| SignedBeaconBlock::Eip7594(_) => (signed_block, block_response.blob_items),
};

(block_contents, block_response.state)
Expand Down Expand Up @@ -946,9 +946,9 @@ where
| SignedBeaconBlock::Altair(_)
| SignedBeaconBlock::Bellatrix(_)
| SignedBeaconBlock::Capella(_) => (signed_block, None),
SignedBeaconBlock::Deneb(_) | SignedBeaconBlock::Electra(_) => {
(signed_block, block_response.blob_items)
}
SignedBeaconBlock::Deneb(_)
| SignedBeaconBlock::Electra(_)
| SignedBeaconBlock::Eip7594(_) => (signed_block, block_response.blob_items),
};
(block_contents, pre_state)
}
Expand Down
68 changes: 62 additions & 6 deletions beacon_node/execution_layer/src/engine_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub use types::{
};
use types::{
ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
ExecutionPayloadElectra, KzgProofs,
ExecutionPayloadEip7594, ExecutionPayloadElectra, KzgProofs,
};
use types::{Graffiti, GRAFFITI_BYTES_LEN};

Expand All @@ -37,7 +37,7 @@ mod new_payload_request;

pub use new_payload_request::{
NewPayloadRequest, NewPayloadRequestBellatrix, NewPayloadRequestCapella,
NewPayloadRequestDeneb, NewPayloadRequestElectra,
NewPayloadRequestDeneb, NewPayloadRequestEip7594, NewPayloadRequestElectra,
};

pub const LATEST_TAG: &str = "latest";
Expand Down Expand Up @@ -155,7 +155,7 @@ pub struct ExecutionBlock {

/// Representation of an execution block with enough detail to reconstruct a payload.
#[superstruct(
variants(Bellatrix, Capella, Deneb, Electra),
variants(Bellatrix, Capella, Deneb, Electra, Eip7594),
variant_attributes(
derive(Clone, Debug, PartialEq, Serialize, Deserialize,),
serde(bound = "E: EthSpec", rename_all = "camelCase"),
Expand Down Expand Up @@ -189,12 +189,12 @@ pub struct ExecutionBlockWithTransactions<E: EthSpec> {
#[serde(rename = "hash")]
pub block_hash: ExecutionBlockHash,
pub transactions: Vec<Transaction>,
#[superstruct(only(Capella, Deneb, Electra))]
#[superstruct(only(Capella, Deneb, Electra, Eip7594))]
pub withdrawals: Vec<JsonWithdrawal>,
#[superstruct(only(Deneb, Electra))]
#[superstruct(only(Deneb, Electra, Eip7594))]
#[serde(with = "serde_utils::u64_hex_be")]
pub blob_gas_used: u64,
#[superstruct(only(Deneb, Electra))]
#[superstruct(only(Deneb, Electra, Eip7594))]
#[serde(with = "serde_utils::u64_hex_be")]
pub excess_blob_gas: u64,
}
Expand Down Expand Up @@ -306,6 +306,34 @@ impl<E: EthSpec> TryFrom<ExecutionPayload<E>> for ExecutionBlockWithTransactions
excess_blob_gas: block.excess_blob_gas,
})
}
ExecutionPayload::Eip7594(block) => {
Self::Eip7594(ExecutionBlockWithTransactionsEip7594 {
parent_hash: block.parent_hash,
fee_recipient: block.fee_recipient,
state_root: block.state_root,
receipts_root: block.receipts_root,
logs_bloom: block.logs_bloom,
prev_randao: block.prev_randao,
block_number: block.block_number,
gas_limit: block.gas_limit,
gas_used: block.gas_used,
timestamp: block.timestamp,
extra_data: block.extra_data,
base_fee_per_gas: block.base_fee_per_gas,
block_hash: block.block_hash,
transactions: block
.transactions
.iter()
.map(|tx| Transaction::decode(&Rlp::new(tx)))
.collect::<Result<Vec<_>, _>>()?,
withdrawals: Vec::from(block.withdrawals)
.into_iter()
.map(|withdrawal| withdrawal.into())
.collect(),
blob_gas_used: block.blob_gas_used,
excess_blob_gas: block.excess_blob_gas,
})
}
};
Ok(json_payload)
}
Expand Down Expand Up @@ -643,6 +671,34 @@ impl<E: EthSpec> ExecutionPayloadBodyV1<E> {
))
}
}
ExecutionPayloadHeader::Eip7594(header) => {
if let Some(withdrawals) = self.withdrawals {
Ok(ExecutionPayload::Eip7594(ExecutionPayloadEip7594 {
parent_hash: header.parent_hash,
fee_recipient: header.fee_recipient,
state_root: header.state_root,
receipts_root: header.receipts_root,
logs_bloom: header.logs_bloom,
prev_randao: header.prev_randao,
block_number: header.block_number,
gas_limit: header.gas_limit,
gas_used: header.gas_used,
timestamp: header.timestamp,
extra_data: header.extra_data,
base_fee_per_gas: header.base_fee_per_gas,
block_hash: header.block_hash,
transactions: self.transactions,
withdrawals,
blob_gas_used: header.blob_gas_used,
excess_blob_gas: header.excess_blob_gas,
}))
} else {
Err(format!(
"block {} is post-capella but payload body doesn't have withdrawals",
header.block_hash
))
}
}
}
}
}
Expand Down
60 changes: 56 additions & 4 deletions beacon_node/execution_layer/src/engine_api/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,14 @@ impl HttpJsonRpc {
)
.await?,
),
ForkName::Eip7594 => ExecutionBlockWithTransactions::Eip7594(
self.rpc_request(
ETH_GET_BLOCK_BY_HASH,
params,
ETH_GET_BLOCK_BY_HASH_TIMEOUT * self.execution_timeout_multiplier,
)
.await?,
),
ForkName::Base | ForkName::Altair => {
return Err(Error::UnsupportedForkVariant(format!(
"called get_block_by_hash_with_txns with fork {:?}",
Expand Down Expand Up @@ -833,6 +841,27 @@ impl HttpJsonRpc {
Ok(response.into())
}

pub async fn new_payload_v3_eip7594<E: EthSpec>(
&self,
new_payload_request_eip7594: NewPayloadRequestEip7594<'_, E>,
) -> Result<PayloadStatusV1, Error> {
let params = json!([
JsonExecutionPayload::V3(new_payload_request_eip7594.execution_payload.clone().into()),
new_payload_request_eip7594.versioned_hashes,
new_payload_request_eip7594.parent_beacon_block_root,
]);

let response: JsonPayloadStatusV1 = self
.rpc_request(
ENGINE_NEW_PAYLOAD_V3,
params,
ENGINE_NEW_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;

Ok(response.into())
}

pub async fn new_payload_v3_electra<E: EthSpec>(
&self,
new_payload_request_electra: NewPayloadRequestElectra<'_, E>,
Expand Down Expand Up @@ -905,9 +934,14 @@ impl HttpJsonRpc {
.await?;
Ok(JsonGetPayloadResponse::V2(response).into())
}
ForkName::Base | ForkName::Altair | ForkName::Deneb | ForkName::Electra => Err(
Error::UnsupportedForkVariant(format!("called get_payload_v2 with {}", fork_name)),
),
ForkName::Base
| ForkName::Altair
| ForkName::Deneb
| ForkName::Electra
| ForkName::Eip7594 => Err(Error::UnsupportedForkVariant(format!(
"called get_payload_v2 with {}",
fork_name
))),
}
}

Expand Down Expand Up @@ -939,6 +973,16 @@ impl HttpJsonRpc {
.await?;
Ok(JsonGetPayloadResponse::V4(response).into())
}
ForkName::Eip7594 => {
let response: JsonGetPayloadResponseV3<E> = self
.rpc_request(
ENGINE_GET_PAYLOAD_V3,
params,
ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
Ok(JsonGetPayloadResponse::V3(response).into())
}
ForkName::Base | ForkName::Altair | ForkName::Bellatrix | ForkName::Capella => Err(
Error::UnsupportedForkVariant(format!("called get_payload_v3 with {}", fork_name)),
),
Expand Down Expand Up @@ -1206,6 +1250,14 @@ impl HttpJsonRpc {
Err(Error::RequiredMethodUnsupported("engine_newPayloadV3"))
}
}
NewPayloadRequest::Eip7594(new_payload_request_eip7594) => {
if engine_capabilities.new_payload_v3 {
self.new_payload_v3_eip7594(new_payload_request_eip7594)
.await
} else {
Err(Error::RequiredMethodUnsupported("engine_newPayloadV3"))
}
}
}
}

Expand All @@ -1227,7 +1279,7 @@ impl HttpJsonRpc {
Err(Error::RequiredMethodUnsupported("engine_getPayload"))
}
}
ForkName::Deneb | ForkName::Electra => {
ForkName::Deneb | ForkName::Electra | ForkName::Eip7594 => {
if engine_capabilities.get_payload_v3 {
self.get_payload_v3(fork_name, payload_id).await
} else {
Expand Down
Loading

0 comments on commit cef8853

Please sign in to comment.