From 51a07b09c1b380561b41a52404f4e21f4bc75f8f Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Thu, 16 Mar 2023 12:04:04 +0100 Subject: [PATCH 01/52] add `deposit_receipts` --- beacon_node/execution_layer/src/engine_api.rs | 9 +++- .../src/engine_api/json_structures.rs | 54 ++++++++++++++++++- beacon_node/execution_layer/src/lib.rs | 11 ++++ .../test_utils/execution_block_generator.rs | 1 + consensus/types/src/eip6110.rs | 37 +++++++++++++ consensus/types/src/eth_spec.rs | 6 ++- consensus/types/src/execution_payload.rs | 5 ++ consensus/types/src/lib.rs | 6 ++- 8 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 consensus/types/src/eip6110.rs diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index 009183d7ab9..590b1ffe5ec 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -10,7 +10,7 @@ use eth2::types::{SsePayloadAttributes, SsePayloadAttributesV1, SsePayloadAttrib pub use ethers_core::types::Transaction; use ethers_core::utils::rlp::{self, Decodable, Rlp}; use http::deposit_methods::RpcError; -pub use json_structures::{JsonWithdrawal, TransitionConfigurationV1}; +pub use json_structures::{JsonDepositReceipt, JsonWithdrawal, TransitionConfigurationV1}; use reqwest::StatusCode; use serde::{Deserialize, Serialize}; use std::convert::TryFrom; @@ -51,6 +51,7 @@ pub enum Error { PayloadConversionLogicFlaw, SszError(ssz_types::Error), DeserializeWithdrawals(ssz_types::Error), + DeserializeDepositReceipts(ssz_types::Error), BuilderApi(builder_client::Error), IncorrectStateVariant, RequiredMethodUnsupported(&'static str), @@ -189,6 +190,8 @@ pub struct ExecutionBlockWithTransactions { pub transactions: Vec, #[superstruct(only(Capella, Eip4844))] pub withdrawals: Vec, + #[superstruct(only(Eip4844))] + pub deposit_receipts: Vec, } impl TryFrom> for ExecutionBlockWithTransactions { @@ -267,6 +270,10 @@ impl TryFrom> for ExecutionBlockWithTransactions .into_iter() .map(|withdrawal| withdrawal.into()) .collect(), + deposit_receipts: Vec::from(block.deposit_receipts) + .into_iter() + .map(|receipt| receipt.into()) + .collect(), }) } }; diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index e84e8dd8175..bd5bd8e41a3 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -1,10 +1,12 @@ use super::*; +use eth2::types::PublicKey; +use eth2::types::Signature; use serde::{Deserialize, Serialize}; use strum::EnumString; use superstruct::superstruct; use types::blobs_sidecar::KzgCommitments; use types::{ - Blobs, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadCapella, + Blobs, DepositReceipt, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadCapella, ExecutionPayloadEip4844, ExecutionPayloadMerge, FixedVector, Transactions, Unsigned, VariableList, Withdrawal, }; @@ -101,6 +103,8 @@ pub struct JsonExecutionPayload { pub transactions: Transactions, #[superstruct(only(V2, V3))] pub withdrawals: VariableList, + #[superstruct(only(V3))] + pub deposit_receipts: VariableList, } impl From> for JsonExecutionPayloadV1 { @@ -173,6 +177,12 @@ impl From> for JsonExecutionPayloadV3 .map(Into::into) .collect::>() .into(), + deposit_receipts: payload + .deposit_receipts + .into_iter() + .map(Into::into) + .collect::>() + .into(), } } } @@ -257,6 +267,12 @@ impl From> for ExecutionPayloadEip4844 .map(Into::into) .collect::>() .into(), + deposit_receipts: payload + .deposit_receipts + .into_iter() + .map(Into::into) + .collect::>() + .into(), } } } @@ -352,6 +368,42 @@ impl From for Withdrawal { } } +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct JsonDepositReceipt { + pub pubkey: PublicKey, + pub withdrawal_credentials: Hash256, + #[serde(with = "eth2_serde_utils::u64_hex_be")] + pub amount: u64, + pub signature: Signature, + #[serde(with = "eth2_serde_utils::u64_hex_be")] + pub index: u64, +} + +impl From for JsonDepositReceipt { + fn from(deposit_receipt: DepositReceipt) -> Self { + Self { + pubkey: deposit_receipt.pubkey, + withdrawal_credentials: deposit_receipt.withdrawal_credentials, + amount: deposit_receipt.amount, + signature: deposit_receipt.signature, + index: deposit_receipt.index, + } + } +} + +impl From for DepositReceipt { + fn from(json_deposit_receipt: JsonDepositReceipt) -> Self { + Self { + pubkey: json_deposit_receipt.pubkey, + withdrawal_credentials: json_deposit_receipt.withdrawal_credentials, + amount: json_deposit_receipt.amount, + signature: json_deposit_receipt.signature, + index: json_deposit_receipt.index, + } + } +} + #[superstruct( variants(V1, V2), variant_attributes( diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 2160c06e4dc..06192c9098c 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -1784,6 +1784,16 @@ impl ExecutionLayer { .collect(), ) .map_err(ApiError::DeserializeWithdrawals)?; + + let deposit_receipts = VariableList::new( + eip4844_block + .deposit_receipts + .into_iter() + .map(Into::into) + .collect(), + ) + .map_err(ApiError::DeserializeDepositReceipts)?; + ExecutionPayload::Eip4844(ExecutionPayloadEip4844 { parent_hash: eip4844_block.parent_hash, fee_recipient: eip4844_block.fee_recipient, @@ -1801,6 +1811,7 @@ impl ExecutionLayer { block_hash: eip4844_block.block_hash, transactions: convert_transactions(eip4844_block.transactions)?, withdrawals, + deposit_receipts, }) } }; diff --git a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs index fe3c6f274b8..a6db7eee594 100644 --- a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs +++ b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs @@ -554,6 +554,7 @@ impl ExecutionBlockGenerator { block_hash: ExecutionBlockHash::zero(), transactions: vec![].into(), withdrawals: pa.withdrawals.clone().into(), + deposit_receipts: vec![].into(), // TODO: Check if deposit receipts should be part of PayloadAttributesV2 }) } _ => unreachable!(), diff --git a/consensus/types/src/eip6110.rs b/consensus/types/src/eip6110.rs new file mode 100644 index 00000000000..2050f0834a6 --- /dev/null +++ b/consensus/types/src/eip6110.rs @@ -0,0 +1,37 @@ +use crate::test_utils::TestRandom; +use crate::*; +use serde_derive::{Deserialize, Serialize}; +use ssz_derive::{Decode, Encode}; +use test_random_derive::TestRandom; +use tree_hash_derive::TreeHash; + +#[derive( + arbitrary::Arbitrary, + Debug, + PartialEq, + // Eq, + Hash, + Clone, + Serialize, + Deserialize, + Encode, + Decode, + TreeHash, + TestRandom, +)] +pub struct DepositReceipt { + pub pubkey: PublicKey, + pub withdrawal_credentials: Hash256, + #[serde(with = "eth2_serde_utils::quoted_u64")] + pub amount: u64, + pub signature: Signature, + #[serde(with = "eth2_serde_utils::quoted_u64")] + pub index: u64, +} + +#[cfg(test)] +mod tests { + use super::*; + + ssz_and_tree_hash_tests!(DepositReceipt); +} diff --git a/consensus/types/src/eth_spec.rs b/consensus/types/src/eth_spec.rs index 7a78dd5800c..66316a699d0 100644 --- a/consensus/types/src/eth_spec.rs +++ b/consensus/types/src/eth_spec.rs @@ -108,6 +108,7 @@ pub trait EthSpec: type MaxBlobsPerBlock: Unsigned + Clone + Sync + Send + Debug + PartialEq; type FieldElementsPerBlob: Unsigned + Clone + Sync + Send + Debug + PartialEq; type BytesPerFieldElement: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type MaxDepositReceiptsPerPayload: Unsigned + Clone + Sync + Send + Debug + PartialEq; /* * Derived values (set these CAREFULLY) */ @@ -303,6 +304,7 @@ impl EthSpec for MainnetEthSpec { type SlotsPerEth1VotingPeriod = U2048; // 64 epochs * 32 slots per epoch type MaxBlsToExecutionChanges = U16; type MaxWithdrawalsPerPayload = U16; + type MaxDepositReceiptsPerPayload = U8192; fn default_spec() -> ChainSpec { ChainSpec::mainnet() @@ -352,7 +354,8 @@ impl EthSpec for MinimalEthSpec { MaxExtraDataBytes, MaxBlsToExecutionChanges, MaxBlobsPerBlock, - BytesPerFieldElement + BytesPerFieldElement, + MaxDepositReceiptsPerPayload }); fn default_spec() -> ChainSpec { @@ -402,6 +405,7 @@ impl EthSpec for GnosisEthSpec { type FieldElementsPerBlob = U4096; type BytesPerFieldElement = U32; type BytesPerBlob = U131072; + type MaxDepositReceiptsPerPayload = U8192; fn default_spec() -> ChainSpec { ChainSpec::gnosis() diff --git a/consensus/types/src/execution_payload.rs b/consensus/types/src/execution_payload.rs index 7762afe9184..2e02326de4f 100644 --- a/consensus/types/src/execution_payload.rs +++ b/consensus/types/src/execution_payload.rs @@ -14,6 +14,9 @@ pub type Transactions = VariableList< pub type Withdrawals = VariableList::MaxWithdrawalsPerPayload>; +pub type DepositReceipts = + VariableList::MaxDepositReceiptsPerPayload>; + #[superstruct( variants(Merge, Capella, Eip4844), variant_attributes( @@ -87,6 +90,8 @@ pub struct ExecutionPayload { pub transactions: Transactions, #[superstruct(only(Capella, Eip4844))] pub withdrawals: Withdrawals, + #[superstruct(only(Eip4844))] + pub deposit_receipts: DepositReceipts, } impl<'a, T: EthSpec> ExecutionPayloadRef<'a, T> { diff --git a/consensus/types/src/lib.rs b/consensus/types/src/lib.rs index 221dda31bc4..b38a6080b6c 100644 --- a/consensus/types/src/lib.rs +++ b/consensus/types/src/lib.rs @@ -74,6 +74,7 @@ pub mod voluntary_exit; #[macro_use] pub mod slot_epoch_macros; pub mod config_and_preset; +pub mod eip6110; pub mod execution_block_header; pub mod fork_context; pub mod participation_flags; @@ -131,14 +132,15 @@ pub use crate::deposit::{Deposit, DEPOSIT_TREE_DEPTH}; pub use crate::deposit_data::DepositData; pub use crate::deposit_message::DepositMessage; pub use crate::deposit_tree_snapshot::{DepositTreeSnapshot, FinalizedExecutionBlock}; +pub use crate::eip6110::DepositReceipt; pub use crate::enr_fork_id::EnrForkId; pub use crate::eth1_data::Eth1Data; pub use crate::eth_spec::EthSpecId; pub use crate::execution_block_hash::ExecutionBlockHash; pub use crate::execution_block_header::ExecutionBlockHeader; pub use crate::execution_payload::{ - ExecutionPayload, ExecutionPayloadCapella, ExecutionPayloadEip4844, ExecutionPayloadMerge, - ExecutionPayloadRef, Transaction, Transactions, Withdrawals, + DepositReceipts, ExecutionPayload, ExecutionPayloadCapella, ExecutionPayloadEip4844, + ExecutionPayloadMerge, ExecutionPayloadRef, Transaction, Transactions, Withdrawals, }; pub use crate::execution_payload_header::{ ExecutionPayloadHeader, ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderEip4844, From a0157f46b0e288651cf4907ec21209cb588e6658 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Thu, 16 Mar 2023 16:32:03 +0100 Subject: [PATCH 02/52] modify `ExecutionPayloadHeader`& `BeaconState` --- beacon_node/execution_layer/src/lib.rs | 18 +++++++++--------- beacon_node/store/src/partial_beacon_state.rs | 15 +++++++++++---- .../state_processing/src/upgrade/capella.rs | 2 ++ .../state_processing/src/upgrade/eip4844.rs | 1 + consensus/types/src/beacon_state.rs | 3 +++ .../types/src/execution_payload_header.rs | 5 +++++ 6 files changed, 31 insertions(+), 13 deletions(-) diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 06192c9098c..9702e210569 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -43,13 +43,13 @@ use tokio_stream::wrappers::WatchStream; use tree_hash::TreeHash; use types::consts::eip4844::BLOB_TX_TYPE; use types::transaction::{AccessTuple, BlobTransaction, EcdsaSignature, SignedBlobTransaction}; -use types::Withdrawals; use types::{ blobs_sidecar::{Blobs, KzgCommitments}, BlindedPayload, BlockType, ChainSpec, Epoch, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadCapella, ExecutionPayloadEip4844, ExecutionPayloadMerge, ForkName, }; use types::{AbstractExecPayload, BeaconStateError, ExecPayload, VersionedHash}; +use types::{DepositReceipt, Withdrawals}; use types::{ ProposerPreparationData, PublicKeyBytes, Signature, SignedBeaconBlock, Slot, Transaction, Uint256, @@ -1785,14 +1785,14 @@ impl ExecutionLayer { ) .map_err(ApiError::DeserializeWithdrawals)?; - let deposit_receipts = VariableList::new( - eip4844_block - .deposit_receipts - .into_iter() - .map(Into::into) - .collect(), - ) - .map_err(ApiError::DeserializeDepositReceipts)?; + let deposit_receipts = eip4844_block + .deposit_receipts + .into_iter() + .map(Into::into) + .collect::>(); + + let deposit_receipts = VariableList::new(deposit_receipts) + .map_err(ApiError::DeserializeDepositReceipts)?; ExecutionPayload::Eip4844(ExecutionPayloadEip4844 { parent_hash: eip4844_block.parent_hash, diff --git a/beacon_node/store/src/partial_beacon_state.rs b/beacon_node/store/src/partial_beacon_state.rs index 55697bd3160..b642c2752c6 100644 --- a/beacon_node/store/src/partial_beacon_state.rs +++ b/beacon_node/store/src/partial_beacon_state.rs @@ -114,6 +114,9 @@ where #[ssz(skip_serializing, skip_deserializing)] #[superstruct(only(Capella, Eip4844))] pub historical_summaries: Option>, + + #[superstruct(only(Capella, Eip4844))] + pub deposit_receipts_start_index: u64, } /// Implement the conversion function from BeaconState -> PartialBeaconState. @@ -223,7 +226,8 @@ impl PartialBeaconState { inactivity_scores, latest_execution_payload_header, next_withdrawal_index, - next_withdrawal_validator_index + next_withdrawal_validator_index, + deposit_receipts_start_index ], [historical_summaries] ), @@ -240,7 +244,8 @@ impl PartialBeaconState { inactivity_scores, latest_execution_payload_header, next_withdrawal_index, - next_withdrawal_validator_index + next_withdrawal_validator_index, + deposit_receipts_start_index ], [historical_summaries] ), @@ -468,7 +473,8 @@ impl TryInto> for PartialBeaconState { inactivity_scores, latest_execution_payload_header, next_withdrawal_index, - next_withdrawal_validator_index + next_withdrawal_validator_index, + deposit_receipts_start_index ], [historical_summaries] ), @@ -484,7 +490,8 @@ impl TryInto> for PartialBeaconState { inactivity_scores, latest_execution_payload_header, next_withdrawal_index, - next_withdrawal_validator_index + next_withdrawal_validator_index, + deposit_receipts_start_index ], [historical_summaries] ), diff --git a/consensus/state_processing/src/upgrade/capella.rs b/consensus/state_processing/src/upgrade/capella.rs index 3b933fac37a..babea82cc2e 100644 --- a/consensus/state_processing/src/upgrade/capella.rs +++ b/consensus/state_processing/src/upgrade/capella.rs @@ -66,6 +66,8 @@ pub fn upgrade_to_capella( pubkey_cache: mem::take(&mut pre.pubkey_cache), exit_cache: mem::take(&mut pre.exit_cache), tree_hash_cache: mem::take(&mut pre.tree_hash_cache), + // EIP-6110 + deposit_receipts_start_index: 0, }); *pre_state = post; diff --git a/consensus/state_processing/src/upgrade/eip4844.rs b/consensus/state_processing/src/upgrade/eip4844.rs index 4f6ff9d1943..c6e8c15c185 100644 --- a/consensus/state_processing/src/upgrade/eip4844.rs +++ b/consensus/state_processing/src/upgrade/eip4844.rs @@ -67,6 +67,7 @@ pub fn upgrade_to_eip4844( pubkey_cache: mem::take(&mut pre.pubkey_cache), exit_cache: mem::take(&mut pre.exit_cache), tree_hash_cache: mem::take(&mut pre.tree_hash_cache), + deposit_receipts_start_index: pre.deposit_receipts_start_index, }); *pre_state = post; diff --git a/consensus/types/src/beacon_state.rs b/consensus/types/src/beacon_state.rs index c98df48d14e..4f3a68e3b4f 100644 --- a/consensus/types/src/beacon_state.rs +++ b/consensus/types/src/beacon_state.rs @@ -309,6 +309,9 @@ where // Deep history valid from Capella onwards. #[superstruct(only(Capella, Eip4844))] pub historical_summaries: VariableList, + #[superstruct(only(Capella, Eip4844), partial_getter(copy))] + #[serde(with = "eth2_serde_utils::quoted_u64")] + pub deposit_receipts_start_index: u64, // Caching (not in the spec) #[serde(skip_serializing, skip_deserializing)] diff --git a/consensus/types/src/execution_payload_header.rs b/consensus/types/src/execution_payload_header.rs index 4dc79ddc999..fde2fa8880d 100644 --- a/consensus/types/src/execution_payload_header.rs +++ b/consensus/types/src/execution_payload_header.rs @@ -81,6 +81,9 @@ pub struct ExecutionPayloadHeader { #[superstruct(only(Capella, Eip4844))] #[superstruct(getter(copy))] pub withdrawals_root: Hash256, + #[superstruct(only(Eip4844))] + #[superstruct(getter(copy))] + pub deposit_receipts_root: Hash256, } impl ExecutionPayloadHeader { @@ -155,6 +158,7 @@ impl ExecutionPayloadHeaderCapella { block_hash: self.block_hash, transactions_root: self.transactions_root, withdrawals_root: self.withdrawals_root, + deposit_receipts_root: Hash256::zero(), } } } @@ -220,6 +224,7 @@ impl<'a, T: EthSpec> From<&'a ExecutionPayloadEip4844> for ExecutionPayloadHe block_hash: payload.block_hash, transactions_root: payload.transactions.tree_hash_root(), withdrawals_root: payload.withdrawals.tree_hash_root(), + deposit_receipts_root: payload.deposit_receipts.tree_hash_root(), } } } From 57afc5e73a6723ba8b32aa45f2f172a8517e0518 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Fri, 17 Mar 2023 14:23:58 +0100 Subject: [PATCH 03/52] add `process_deposit_receipt`&`process_operations` --- .../src/per_block_processing.rs | 24 +++++++++++++++++++ .../process_operations.rs | 19 +++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index b2d7e000723..1bb7538bea2 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -416,6 +416,30 @@ pub fn process_execution_payload>( Ok(()) } +pub const UNSET_DEPOSIT_RECEIPTS_START_INDEX: u64 = std::u64::MAX; +pub fn process_deposit_receipt( + state: &mut BeaconState, + deposit_receipts: &DepositReceipt, +) -> Result<(), BlockProcessingError> { + /* + // Set deposit receipt start index + let start_index = state.deposit_receipts_start_index().map_err(|_| BlockProcessingError::DepositReceiptError)?; + if start_index == UNSET_DEPOSIT_RECEIPTS_START_INDEX { + *state.deposit_receipts_start_index_mut().map_err(|_| BlockProcessingError::DepositReceiptError)? = deposit_receipt.index; + } + + // Process the deposit (replace this with the actual deposit processing logic) + let pubkey = &deposit_receipt.pubkey; + let withdrawal_credentials = &deposit_receipt.withdrawal_credentials; + let amount = deposit_receipt.amount; + let signature = &deposit_receipt.signature; + */ + + // Add the logic to process the deposit here + + Ok(()) +} + /// These functions will definitely be called before the merge. Their entire purpose is to check if /// the merge has happened or if we're on the transition block. Thus we don't want to propagate /// errors from the `BeaconState` being an earlier variant than `BeaconStateMerge` as we'd have to diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 8a6163f29b9..4ba4cb6beee 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -16,6 +16,12 @@ pub fn process_operations>( ctxt: &mut ConsensusContext, spec: &ChainSpec, ) -> Result<(), BlockProcessingError> { + let unprocessed_deposits_count = state + .eth1_data() + .deposit_count + .saturating_sub(state.eth1_deposit_index()); + let max_deposits = ::MaxDeposits::to_u64(); + process_proposer_slashings( state, block_body.proposer_slashings(), @@ -31,12 +37,21 @@ pub fn process_operations>( spec, )?; process_attestations(state, block_body, verify_signatures, ctxt, spec)?; + assert_eq!( + block_body.deposits().len() as usize, + std::cmp::min(max_deposits as usize, unprocessed_deposits_count as usize), + "Number of deposits in block does not match the minimum of the maximum number of deposits and the number of unprocessed deposits" + ); process_deposits(state, block_body.deposits(), spec)?; process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?; - if let Ok(bls_to_execution_changes) = block_body.bls_to_execution_changes() { - process_bls_to_execution_changes(state, bls_to_execution_changes, verify_signatures, spec)?; + /* + if let Ok(payload) = block_body.execution_payload() { + if is_execution_enabled(state, block_body) { + process_deposit_receipt(state, payload.deposit_receipts())?; + } } + */ Ok(()) } From b20fa959feb025996e6df90bfbd8716675a280a0 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Sun, 19 Mar 2023 15:11:41 +0100 Subject: [PATCH 04/52] update `process_deposit_receipt` --- .../src/per_block_processing.rs | 27 ++++++++++--------- .../src/per_block_processing/errors.rs | 1 + .../process_operations.rs | 2 +- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 1bb7538bea2..080a7f467a2 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -419,23 +419,26 @@ pub fn process_execution_payload>( pub const UNSET_DEPOSIT_RECEIPTS_START_INDEX: u64 = std::u64::MAX; pub fn process_deposit_receipt( state: &mut BeaconState, - deposit_receipts: &DepositReceipt, + deposit_receipt: &DepositReceipt, ) -> Result<(), BlockProcessingError> { - /* // Set deposit receipt start index - let start_index = state.deposit_receipts_start_index().map_err(|_| BlockProcessingError::DepositReceiptError)?; + let start_index = state + .deposit_receipts_start_index() + .map_err(|_| BlockProcessingError::DepositReceiptError)?; if start_index == UNSET_DEPOSIT_RECEIPTS_START_INDEX { - *state.deposit_receipts_start_index_mut().map_err(|_| BlockProcessingError::DepositReceiptError)? = deposit_receipt.index; + *state + .deposit_receipts_start_index_mut() + .map_err(|_| BlockProcessingError::DepositReceiptError)? = deposit_receipt.index; } - - // Process the deposit (replace this with the actual deposit processing logic) - let pubkey = &deposit_receipt.pubkey; - let withdrawal_credentials = &deposit_receipt.withdrawal_credentials; - let amount = deposit_receipt.amount; - let signature = &deposit_receipt.signature; - */ - // Add the logic to process the deposit here + /* TODO: Check how apply_deposit works: Create a DepositData instance (?) from the DepositReceipt fields + let deposit_data = DepositData { + pubkey: deposit_receipt.pubkey.into(), + withdrawal_credentials: deposit_receipt.withdrawal_credentials, + amount: deposit_receipt.amount, + signature: deposit_receipt.signature.into(), + }; + */ Ok(()) } diff --git a/consensus/state_processing/src/per_block_processing/errors.rs b/consensus/state_processing/src/per_block_processing/errors.rs index 5c34afd593e..0370945a16a 100644 --- a/consensus/state_processing/src/per_block_processing/errors.rs +++ b/consensus/state_processing/src/per_block_processing/errors.rs @@ -95,6 +95,7 @@ pub enum BlockProcessingError { length: usize, }, WithdrawalCredentialsInvalid, + DepositReceiptError, } impl From for BlockProcessingError { diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 4ba4cb6beee..c64620b1b9a 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -45,7 +45,7 @@ pub fn process_operations>( process_deposits(state, block_body.deposits(), spec)?; process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?; - /* + /* TODO: Add deposit_receipts to AbstractExecPayload if let Ok(payload) = block_body.execution_payload() { if is_execution_enabled(state, block_body) { process_deposit_receipt(state, payload.deposit_receipts())?; From 541ff94da40f6651b252ffe6506627565eb99093 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Mon, 20 Mar 2023 10:45:51 +0100 Subject: [PATCH 05/52] finish `process_deposit_receipt` --- .../state_processing/src/per_block_processing.rs | 16 ++++++++++++---- .../per_block_processing/process_operations.rs | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 080a7f467a2..adea2df1c59 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -7,6 +7,7 @@ use std::borrow::Cow; use tree_hash::TreeHash; use types::*; +use self::process_operations::process_deposit; pub use self::verify_attester_slashing::{ get_slashable_indices, get_slashable_indices_modular, verify_attester_slashing, }; @@ -420,6 +421,7 @@ pub const UNSET_DEPOSIT_RECEIPTS_START_INDEX: u64 = std::u64::MAX; pub fn process_deposit_receipt( state: &mut BeaconState, deposit_receipt: &DepositReceipt, + spec: &ChainSpec, ) -> Result<(), BlockProcessingError> { // Set deposit receipt start index let start_index = state @@ -431,14 +433,20 @@ pub fn process_deposit_receipt( .map_err(|_| BlockProcessingError::DepositReceiptError)? = deposit_receipt.index; } - /* TODO: Check how apply_deposit works: Create a DepositData instance (?) from the DepositReceipt fields + // Create a Deposit object from the DepositReceipt let deposit_data = DepositData { - pubkey: deposit_receipt.pubkey.into(), + pubkey: deposit_receipt.pubkey.clone().into(), withdrawal_credentials: deposit_receipt.withdrawal_credentials, amount: deposit_receipt.amount, - signature: deposit_receipt.signature.into(), + signature: deposit_receipt.signature.clone().into(), + }; + let deposit = Deposit { + proof: FixedVector::from_elem(Hash256::zero()), // Set an empty proof, since it's not included in DepositReceipt + data: deposit_data, }; - */ + + // Call process_deposit with the created Deposit object + process_deposit(state, &deposit, spec, true)?; Ok(()) } diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index c64620b1b9a..526986a2f9a 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -38,7 +38,7 @@ pub fn process_operations>( )?; process_attestations(state, block_body, verify_signatures, ctxt, spec)?; assert_eq!( - block_body.deposits().len() as usize, + block_body.deposits().len(), std::cmp::min(max_deposits as usize, unprocessed_deposits_count as usize), "Number of deposits in block does not match the minimum of the maximum number of deposits and the number of unprocessed deposits" ); From 37adbf00f0a41684a2747b86a51b771424ad37c5 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Mon, 20 Mar 2023 14:13:59 +0100 Subject: [PATCH 06/52] mod. `process_operations` and `payload.rs` --- .../process_operations.rs | 7 ++-- consensus/types/src/payload.rs | 41 +++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 526986a2f9a..903ee56ec9d 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -45,13 +45,14 @@ pub fn process_operations>( process_deposits(state, block_body.deposits(), spec)?; process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?; - /* TODO: Add deposit_receipts to AbstractExecPayload if let Ok(payload) = block_body.execution_payload() { if is_execution_enabled(state, block_body) { - process_deposit_receipt(state, payload.deposit_receipts())?; + let deposit_receipts = payload.deposit_receipts()?; + for deposit_receipt in deposit_receipts.iter() { + process_deposit_receipt(state, deposit_receipt, spec)?; + } } } - */ Ok(()) } diff --git a/consensus/types/src/payload.rs b/consensus/types/src/payload.rs index 9ec2d9f30a2..22aacc0e331 100644 --- a/consensus/types/src/payload.rs +++ b/consensus/types/src/payload.rs @@ -39,6 +39,7 @@ pub trait ExecPayload: Debug + Clone + PartialEq + Hash + TreeHash + fn transactions(&self) -> Option<&Transactions>; /// fork-specific fields fn withdrawals_root(&self) -> Result; + fn deposit_receipts(&self) -> Result, Error>; /// Is this a default payload with 0x0 roots for transactions and withdrawals? fn is_default_with_zero_roots(&self) -> bool; @@ -267,6 +268,20 @@ impl ExecPayload for FullPayload { // For full payloads the empty/zero distinction does not exist. self.is_default_with_zero_roots() } + + fn deposit_receipts(&self) -> Result, Error> { + match self { + FullPayload::Merge(_) => { + // Return an error for the Merge variant + Err(Error::IncorrectStateVariant) + } + FullPayload::Capella(_) => { + // Return an error for the Capella variant + Err(Error::IncorrectStateVariant) + } + FullPayload::Eip4844(ref inner) => Ok(inner.execution_payload.deposit_receipts.clone()), + } + } } impl FullPayload { @@ -376,6 +391,20 @@ impl<'b, T: EthSpec> ExecPayload for FullPayloadRef<'b, T> { // For full payloads the empty/zero distinction does not exist. self.is_default_with_zero_roots() } + + fn deposit_receipts(&self) -> Result, Error> { + match self { + FullPayloadRef::Merge(_) => { + // Return an error for the Merge variant + Err(Error::IncorrectStateVariant) + } + FullPayloadRef::Capella(_) => { + // Return an error for the Capella variant + Err(Error::IncorrectStateVariant) + } + FullPayloadRef::Eip4844(inner) => Ok(inner.execution_payload.deposit_receipts.clone()), + } + } } impl AbstractExecPayload for FullPayload { @@ -548,6 +577,10 @@ impl ExecPayload for BlindedPayload { fn is_default_with_empty_roots(&self) -> bool { self.to_ref().is_default_with_empty_roots() } + + fn deposit_receipts(&self) -> Result, Error> { + todo!() + } } impl<'b, T: EthSpec> ExecPayload for BlindedPayloadRef<'b, T> { @@ -640,6 +673,10 @@ impl<'b, T: EthSpec> ExecPayload for BlindedPayloadRef<'b, T> { payload.is_default_with_empty_roots() }) } + + fn deposit_receipts(&self) -> Result, Error> { + todo!() + } } macro_rules! impl_exec_payload_common { @@ -710,6 +747,10 @@ macro_rules! impl_exec_payload_common { let g = $g; g(self) } + + fn deposit_receipts(&self) -> Result, Error> { + todo!() + } } impl From<$wrapped_type> for $wrapper_type { From 81b0db6d1395167c8ca84fd351c734920ca8f20b Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Mon, 20 Mar 2023 17:30:18 +0100 Subject: [PATCH 07/52] modify `initialize_beacon_state_from_eth1` --- consensus/state_processing/src/genesis.rs | 102 ++++++---------------- consensus/types/src/chain_spec.rs | 18 ++++ 2 files changed, 47 insertions(+), 73 deletions(-) diff --git a/consensus/state_processing/src/genesis.rs b/consensus/state_processing/src/genesis.rs index 3f9328f4d5c..275b214c8f7 100644 --- a/consensus/state_processing/src/genesis.rs +++ b/consensus/state_processing/src/genesis.rs @@ -2,15 +2,12 @@ use super::per_block_processing::{ errors::BlockProcessingError, process_operations::process_deposit, }; use crate::common::DepositDataTree; -use crate::upgrade::{ - upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_eip4844, -}; +use crate::per_block_processing::UNSET_DEPOSIT_RECEIPTS_START_INDEX; use safe_arith::{ArithError, SafeArith}; use tree_hash::TreeHash; use types::DEPOSIT_TREE_DEPTH; use types::*; -/// Initialize a `BeaconState` from genesis data. pub fn initialize_beacon_state_from_eth1( eth1_block_hash: Hash256, eth1_timestamp: u64, @@ -20,7 +17,6 @@ pub fn initialize_beacon_state_from_eth1( ) -> Result, BlockProcessingError> { let genesis_time = eth2_genesis_time(eth1_timestamp, spec)?; let eth1_data = Eth1Data { - // Temporary deposit root deposit_root: Hash256::zero(), deposit_count: deposits.len() as u64, block_hash: eth1_block_hash, @@ -42,80 +38,40 @@ pub fn initialize_beacon_state_from_eth1( process_activations(&mut state, spec)?; - // To support testnets with Altair enabled from genesis, perform a possible state upgrade here. - // This must happen *after* deposits and activations are processed or the calculation of sync - // committees during the upgrade will fail. It's a bit cheeky to do this instead of having - // separate Altair genesis initialization logic, but it turns out that our - // use of `BeaconBlock::empty` in `BeaconState::new` is sufficient to correctly initialise - // the `latest_block_header` as per: - // https://github.com/ethereum/eth2.0-specs/pull/2323 - if spec - .altair_fork_epoch - .map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch()) - { - upgrade_to_altair(&mut state, spec)?; - - state.fork_mut().previous_version = spec.altair_fork_version; - } - - // Similarly, perform an upgrade to the merge if configured from genesis. - if spec - .bellatrix_fork_epoch - .map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch()) - { - // this will set state.latest_execution_payload_header = ExecutionPayloadHeaderMerge::default() - upgrade_to_bellatrix(&mut state, spec)?; - - // Remove intermediate Altair fork from `state.fork`. - state.fork_mut().previous_version = spec.bellatrix_fork_version; - - // Override latest execution payload header. - // See https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/bellatrix/beacon-chain.md#testing - if let Some(ExecutionPayloadHeader::Merge(ref header)) = execution_payload_header { - *state.latest_execution_payload_header_merge_mut()? = header.clone(); - } - } - - // Upgrade to capella if configured from genesis - if spec - .capella_fork_epoch - .map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch()) - { - upgrade_to_capella(&mut state, spec)?; - - // Remove intermediate Bellatrix fork from `state.fork`. - state.fork_mut().previous_version = spec.capella_fork_version; - - // Override latest execution payload header. - // See https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#testing - if let Some(ExecutionPayloadHeader::Capella(ref header)) = execution_payload_header { - *state.latest_execution_payload_header_capella_mut()? = header.clone(); - } - } - - // Upgrade to eip4844 if configured from genesis - if spec - .eip4844_fork_epoch - .map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch()) - { - upgrade_to_eip4844(&mut state, spec)?; - - // Remove intermediate Capella fork from `state.fork`. - state.fork_mut().previous_version = spec.eip4844_fork_version; - - // Override latest execution payload header. - // See https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/beacon-chain.md#testing - if let Some(ExecutionPayloadHeader::Eip4844(header)) = execution_payload_header { - *state.latest_execution_payload_header_eip4844_mut()? = header; - } - } - // Now that we have our validators, initialize the caches (including the committees) state.build_all_caches(spec)?; // Set genesis validators root for domain separation and chain versioning *state.genesis_validators_root_mut() = state.update_validators_tree_hash_cache()?; + // Set fork version to EIP6110 + state.fork_mut().previous_version = spec.eip6110_fork_version; + state.fork_mut().current_version = spec.eip6110_fork_version; + + // Add deposit_receipts_start_index field with the value UNSET_DEPOSIT_RECEIPTS_START_INDEX + *state.deposit_receipts_start_index_mut()? = UNSET_DEPOSIT_RECEIPTS_START_INDEX; + + // Initialize the execution payload header + if let Some(header) = execution_payload_header { + match state.latest_execution_payload_header_mut()? { + ExecutionPayloadHeaderRefMut::Merge(header_mut) => { + if let ExecutionPayloadHeader::Merge(header) = header { + *header_mut = header; + } + } + ExecutionPayloadHeaderRefMut::Capella(header_mut) => { + if let ExecutionPayloadHeader::Capella(header) = header { + *header_mut = header; + } + } + ExecutionPayloadHeaderRefMut::Eip4844(header_mut) => { + if let ExecutionPayloadHeader::Eip4844(header) = header { + *header_mut = header; + } + } // TODO: Should a Eip6110 or upgrade_to_eip6110() be added? + } + } + Ok(state) } diff --git a/consensus/types/src/chain_spec.rs b/consensus/types/src/chain_spec.rs index 61d46b6cce5..806632a6021 100644 --- a/consensus/types/src/chain_spec.rs +++ b/consensus/types/src/chain_spec.rs @@ -167,6 +167,12 @@ pub struct ChainSpec { pub eip4844_fork_version: [u8; 4], pub eip4844_fork_epoch: Option, + /* + * Eip6110 hard fork params + */ + pub eip6110_fork_version: [u8; 4], + pub eip6110_fork_epoch: Option, + /* * Networking */ @@ -642,6 +648,12 @@ impl ChainSpec { eip4844_fork_version: [0x04, 0x00, 0x00, 0x00], eip4844_fork_epoch: None, + /* + * Eip6110 hard fork params + */ + eip6110_fork_version: [0x05, 0x00, 0x00, 0x00], + eip6110_fork_epoch: None, + /* * Network specific */ @@ -879,6 +891,12 @@ impl ChainSpec { eip4844_fork_version: [0x04, 0x00, 0x00, 0x64], eip4844_fork_epoch: None, + /* + * Eip6110 hard fork params + */ + eip6110_fork_version: [0x05, 0x00, 0x00, 0x64], + eip6110_fork_epoch: None, + /* * Network specific */ From ef699e3545a4f342297c1643af755c5914a7bf95 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Thu, 23 Mar 2023 16:07:05 +0100 Subject: [PATCH 08/52] fix `consensus-spec-tests` --- .../src/engine_api/json_structures.rs | 16 ++++---- consensus/types/src/eip6110.rs | 4 +- consensus/types/src/payload.rs | 37 +++++++++++++------ 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index bd5bd8e41a3..0384aad4886 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -1,6 +1,6 @@ use super::*; -use eth2::types::PublicKey; -use eth2::types::Signature; +use eth2::types::PublicKeyBytes; +use eth2::types::SignatureBytes; use serde::{Deserialize, Serialize}; use strum::EnumString; use superstruct::superstruct; @@ -371,11 +371,11 @@ impl From for Withdrawal { #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct JsonDepositReceipt { - pub pubkey: PublicKey, + pub pubkey: PublicKeyBytes, pub withdrawal_credentials: Hash256, #[serde(with = "eth2_serde_utils::u64_hex_be")] pub amount: u64, - pub signature: Signature, + pub signature: SignatureBytes, #[serde(with = "eth2_serde_utils::u64_hex_be")] pub index: u64, } @@ -383,10 +383,10 @@ pub struct JsonDepositReceipt { impl From for JsonDepositReceipt { fn from(deposit_receipt: DepositReceipt) -> Self { Self { - pubkey: deposit_receipt.pubkey, + pubkey: deposit_receipt.pubkey.decompress().unwrap().into(), // Convert PublicKeyBytes to PublicKey withdrawal_credentials: deposit_receipt.withdrawal_credentials, amount: deposit_receipt.amount, - signature: deposit_receipt.signature, + signature: (deposit_receipt.signature).try_into().unwrap(), // Convert SignatureBytes to Signature index: deposit_receipt.index, } } @@ -395,10 +395,10 @@ impl From for JsonDepositReceipt { impl From for DepositReceipt { fn from(json_deposit_receipt: JsonDepositReceipt) -> Self { Self { - pubkey: json_deposit_receipt.pubkey, + pubkey: json_deposit_receipt.pubkey.into(), withdrawal_credentials: json_deposit_receipt.withdrawal_credentials, amount: json_deposit_receipt.amount, - signature: json_deposit_receipt.signature, + signature: json_deposit_receipt.signature.into(), index: json_deposit_receipt.index, } } diff --git a/consensus/types/src/eip6110.rs b/consensus/types/src/eip6110.rs index 2050f0834a6..9b375b2aa08 100644 --- a/consensus/types/src/eip6110.rs +++ b/consensus/types/src/eip6110.rs @@ -20,11 +20,11 @@ use tree_hash_derive::TreeHash; TestRandom, )] pub struct DepositReceipt { - pub pubkey: PublicKey, + pub pubkey: PublicKeyBytes, pub withdrawal_credentials: Hash256, #[serde(with = "eth2_serde_utils::quoted_u64")] pub amount: u64, - pub signature: Signature, + pub signature: SignatureBytes, #[serde(with = "eth2_serde_utils::quoted_u64")] pub index: u64, } diff --git a/consensus/types/src/payload.rs b/consensus/types/src/payload.rs index 22aacc0e331..4eee05c1754 100644 --- a/consensus/types/src/payload.rs +++ b/consensus/types/src/payload.rs @@ -272,12 +272,12 @@ impl ExecPayload for FullPayload { fn deposit_receipts(&self) -> Result, Error> { match self { FullPayload::Merge(_) => { - // Return an error for the Merge variant - Err(Error::IncorrectStateVariant) + // Return an "empty" or "default" value for the Merge variant + Ok(Vec::new().into()) } FullPayload::Capella(_) => { - // Return an error for the Capella variant - Err(Error::IncorrectStateVariant) + // Return an "empty" or "default" value for the Capella variant + Ok(Vec::new().into()) } FullPayload::Eip4844(ref inner) => Ok(inner.execution_payload.deposit_receipts.clone()), } @@ -395,16 +395,16 @@ impl<'b, T: EthSpec> ExecPayload for FullPayloadRef<'b, T> { fn deposit_receipts(&self) -> Result, Error> { match self { FullPayloadRef::Merge(_) => { - // Return an error for the Merge variant - Err(Error::IncorrectStateVariant) + // Return an "empty" or "default" value for the Merge variant + Ok(Vec::new().into()) } FullPayloadRef::Capella(_) => { - // Return an error for the Capella variant - Err(Error::IncorrectStateVariant) + // Return an "empty" or "default" value for the Capella variant + Ok(Vec::new().into()) } - FullPayloadRef::Eip4844(inner) => Ok(inner.execution_payload.deposit_receipts.clone()), + FullPayloadRef::Eip4844(ref inner) => Ok(inner.execution_payload.deposit_receipts.clone()), } - } + } } impl AbstractExecPayload for FullPayload { @@ -675,8 +675,21 @@ impl<'b, T: EthSpec> ExecPayload for BlindedPayloadRef<'b, T> { } fn deposit_receipts(&self) -> Result, Error> { - todo!() - } + match self { + BlindedPayloadRef::Merge(_) => { + // Return an "empty" or "default" value for the Merge variant + Ok(Vec::new().into()) + } + BlindedPayloadRef::Capella(_) => { + // Return an "empty" or "default" value for the Capella variant + Ok(Vec::new().into()) + } + BlindedPayloadRef::Eip4844(_) => { + // Return an "empty" or "default" value for the Eip4844 variant + Ok(Vec::new().into()) + } + } + } } macro_rules! impl_exec_payload_common { From cf6aefb043fd11a7109b49989f820fb1519daf61 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Thu, 23 Mar 2023 16:18:48 +0100 Subject: [PATCH 09/52] cargo fmt --- consensus/types/src/payload.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/consensus/types/src/payload.rs b/consensus/types/src/payload.rs index 4eee05c1754..bbc6423c057 100644 --- a/consensus/types/src/payload.rs +++ b/consensus/types/src/payload.rs @@ -402,9 +402,11 @@ impl<'b, T: EthSpec> ExecPayload for FullPayloadRef<'b, T> { // Return an "empty" or "default" value for the Capella variant Ok(Vec::new().into()) } - FullPayloadRef::Eip4844(ref inner) => Ok(inner.execution_payload.deposit_receipts.clone()), + FullPayloadRef::Eip4844(ref inner) => { + Ok(inner.execution_payload.deposit_receipts.clone()) + } } - } + } } impl AbstractExecPayload for FullPayload { @@ -689,7 +691,7 @@ impl<'b, T: EthSpec> ExecPayload for BlindedPayloadRef<'b, T> { Ok(Vec::new().into()) } } - } + } } macro_rules! impl_exec_payload_common { From 824d40d80835a2bbdf61f128a08ff4ff35eedb01 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Tue, 28 Mar 2023 17:07:21 +0200 Subject: [PATCH 10/52] Decouple `Eip6110` and `Eip4844` --- Makefile | 2 +- beacon_node/beacon_chain/src/beacon_chain.rs | 39 +++++++- .../beacon_chain/src/blob_verification.rs | 6 +- .../beacon_chain/src/execution_payload.rs | 2 +- beacon_node/beacon_chain/src/test_utils.rs | 5 + beacon_node/execution_layer/src/engine_api.rs | 52 ++++++++-- .../execution_layer/src/engine_api/http.rs | 47 ++++++++- .../src/engine_api/json_structures.rs | 84 ++++++++++++++-- beacon_node/execution_layer/src/lib.rs | 61 +++++++++--- .../test_utils/execution_block_generator.rs | 43 +++++++-- .../src/test_utils/handle_rpc.rs | 95 ++++++++++++++++++- .../src/test_utils/mock_builder.rs | 4 +- .../src/test_utils/mock_execution_layer.rs | 3 + .../execution_layer/src/test_utils/mod.rs | 7 ++ beacon_node/lighthouse_network/src/config.rs | 6 +- .../lighthouse_network/src/rpc/codec/base.rs | 3 + .../src/rpc/codec/ssz_snappy.rs | 20 +++- .../lighthouse_network/src/rpc/protocol.rs | 12 +++ .../lighthouse_network/src/types/pubsub.rs | 8 +- .../lighthouse_network/src/types/topics.rs | 1 + .../lighthouse_network/tests/common.rs | 3 + .../store/src/impls/execution_payload.rs | 3 +- beacon_node/store/src/partial_beacon_state.rs | 64 ++++++++++--- common/eth2/src/types.rs | 8 +- .../eip4844/config.yaml | 4 + .../gnosis/config.yaml | 3 + .../mainnet/config.yaml | 3 + .../sepolia/config.yaml | 4 + consensus/fork_choice/src/fork_choice.rs | 1 + .../src/common/slash_validator.rs | 3 + consensus/state_processing/src/genesis.rs | 7 +- .../src/per_block_processing.rs | 9 +- .../src/per_block_processing/eip6110.rs | 2 + .../per_block_processing/eip6110/eip6110.rs | 1 + .../process_operations.rs | 3 +- .../src/per_epoch_processing.rs | 2 + .../src/per_epoch_processing/eip4844.rs | 75 +++++++++++++++ .../src/per_slot_processing.rs | 5 + consensus/state_processing/src/upgrade.rs | 2 + .../state_processing/src/upgrade/capella.rs | 2 - .../state_processing/src/upgrade/eip4844.rs | 1 - .../state_processing/src/upgrade/eip6110.rs | 72 ++++++++++++++ consensus/types/src/beacon_block.rs | 67 ++++++++++++- consensus/types/src/beacon_block_body.rs | 94 +++++++++++++++++- consensus/types/src/beacon_state.rs | 38 ++++++-- consensus/types/src/chain_spec.rs | 50 ++++++++-- consensus/types/src/eip6110.rs | 14 ++- consensus/types/src/eth_spec.rs | 5 + consensus/types/src/execution_payload.rs | 23 ++++- .../types/src/execution_payload_header.rs | 76 ++++++++++++++- consensus/types/src/fork_context.rs | 7 ++ consensus/types/src/fork_name.rs | 25 ++++- consensus/types/src/lib.rs | 21 ++-- consensus/types/src/payload.rs | 63 +++++++++++- consensus/types/src/signed_beacon_block.rs | 67 ++++++++++++- lcli/src/create_payload_header.rs | 10 +- lcli/src/main.rs | 11 ++- lcli/src/new_testnet.rs | 12 ++- lcli/src/parse_ssz.rs | 3 + scripts/local_testnet/setup.sh | 2 + scripts/local_testnet/vars.env | 1 + scripts/tests/vars.env | 1 + testing/ef_tests/src/cases/common.rs | 1 + .../ef_tests/src/cases/epoch_processing.rs | 22 +++-- testing/ef_tests/src/cases/fork.rs | 2 + testing/ef_tests/src/cases/operations.rs | 3 +- testing/ef_tests/src/cases/transition.rs | 7 ++ testing/ef_tests/src/handler.rs | 4 + testing/ef_tests/src/type_name.rs | 3 + testing/ef_tests/tests/tests.rs | 12 +++ .../src/signing_method/web3signer.rs | 6 ++ 71 files changed, 1293 insertions(+), 134 deletions(-) create mode 100644 consensus/state_processing/src/per_block_processing/eip6110.rs create mode 100644 consensus/state_processing/src/per_block_processing/eip6110/eip6110.rs create mode 100644 consensus/state_processing/src/per_epoch_processing/eip4844.rs create mode 100644 consensus/state_processing/src/upgrade/eip6110.rs diff --git a/Makefile b/Makefile index bf2ad679453..711b783aa69 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,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 merge capella eip4844 +FORKS=phase0 altair merge capella eip4844 eip6110 # Extra flags for Cargo CARGO_INSTALL_EXTRA_FLAGS?= diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index c3a1ed55ecd..0dc7e0dd721 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -4439,7 +4439,10 @@ impl BeaconChain { // allows it to run concurrently with things like attestation packing. let prepare_payload_handle = match &state { BeaconState::Base(_) | BeaconState::Altair(_) => None, - BeaconState::Merge(_) | BeaconState::Capella(_) | BeaconState::Eip4844(_) => { + BeaconState::Merge(_) + | BeaconState::Capella(_) + | BeaconState::Eip4844(_) + | BeaconState::Eip6110(_) => { let prepare_payload_handle = get_execution_payload(self.clone(), &state, proposer_index, builder_params)?; Some(prepare_payload_handle) @@ -4779,6 +4782,38 @@ impl BeaconChain { blobs, ) } + BeaconState::Eip6110(_) => { + let (payload, kzg_commitments, blobs) = block_contents + .ok_or(BlockProductionError::MissingExecutionPayload)? + .deconstruct(); + ( + BeaconBlock::Eip6110(BeaconBlockEip6110 { + slot, + proposer_index, + parent_root, + state_root: Hash256::zero(), + body: BeaconBlockBodyEip6110 { + 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::InvalidPayloadFork)?, + }, + }), + blobs, + ) + } }; let block = SignedBeaconBlock::from_block( @@ -5081,7 +5116,7 @@ impl BeaconChain { } else { let withdrawals = match self.spec.fork_name_at_slot::(prepare_slot) { ForkName::Base | ForkName::Altair | ForkName::Merge => None, - ForkName::Capella | ForkName::Eip4844 => { + ForkName::Capella | ForkName::Eip4844 | ForkName::Eip6110 => { let chain = self.clone(); self.spawn_blocking_handle( move || { diff --git a/beacon_node/beacon_chain/src/blob_verification.rs b/beacon_node/beacon_chain/src/blob_verification.rs index 1d7f9cc3c52..673dfd42780 100644 --- a/beacon_node/beacon_chain/src/blob_verification.rs +++ b/beacon_node/beacon_chain/src/blob_verification.rs @@ -285,7 +285,7 @@ impl AvailableBlock { | SignedBeaconBlock::Merge(_) => { Ok(AvailableBlock(AvailableBlockInner::Block(beacon_block))) } - SignedBeaconBlock::Eip4844(_) => { + SignedBeaconBlock::Eip4844(_) | SignedBeaconBlock::Eip6110(_) => { match da_check_required { DataAvailabilityCheckRequired::Yes => { // Attempt to reconstruct empty blobs here. @@ -320,7 +320,7 @@ impl AvailableBlock { | SignedBeaconBlock::Altair(_) | SignedBeaconBlock::Capella(_) | SignedBeaconBlock::Merge(_) => Err(BlobError::InconsistentFork), - SignedBeaconBlock::Eip4844(_) => { + SignedBeaconBlock::Eip4844(_) | SignedBeaconBlock::Eip6110(_) => { match da_check_required { DataAvailabilityCheckRequired::Yes => Ok(AvailableBlock( AvailableBlockInner::BlockAndBlob(SignedBeaconBlockAndBlobsSidecar { @@ -330,7 +330,7 @@ impl AvailableBlock { )), DataAvailabilityCheckRequired::No => { // Blobs were not verified so we drop them, we'll instead just pass around - // an available `Eip4844` block without blobs. + // an available `Eip4844` or `Eip6110` block without blobs. Ok(AvailableBlock(AvailableBlockInner::Block(beacon_block))) } } diff --git a/beacon_node/beacon_chain/src/execution_payload.rs b/beacon_node/beacon_chain/src/execution_payload.rs index 41baa956ab9..78a0432b11a 100644 --- a/beacon_node/beacon_chain/src/execution_payload.rs +++ b/beacon_node/beacon_chain/src/execution_payload.rs @@ -419,7 +419,7 @@ pub fn get_execution_payload< let latest_execution_payload_header_block_hash = state.latest_execution_payload_header()?.block_hash(); let withdrawals = match state { - &BeaconState::Capella(_) | &BeaconState::Eip4844(_) => { + &BeaconState::Capella(_) | &BeaconState::Eip4844(_) | &BeaconState::Eip6110(_) => { Some(get_expected_withdrawals(state, spec)?.into()) } &BeaconState::Merge(_) => None, diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index a784c674113..949310bdd7a 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -453,6 +453,7 @@ where shanghai_time, eip4844_time, None, + None, Some(JwtKey::from_slice(&DEFAULT_JWT_SECRET).unwrap()), spec, None, @@ -478,11 +479,15 @@ where let eip4844_time = spec.eip4844_fork_epoch.map(|epoch| { HARNESS_GENESIS_TIME + spec.seconds_per_slot * E::slots_per_epoch() * epoch.as_u64() }); + let eip6110_time = spec.eip6110_fork_epoch.map(|epoch| { + HARNESS_GENESIS_TIME + spec.seconds_per_slot * E::slots_per_epoch() * epoch.as_u64() + }); let mock_el = MockExecutionLayer::new( self.runtime.task_executor.clone(), DEFAULT_TERMINAL_BLOCK, shanghai_time, eip4844_time, + eip6110_time, builder_threshold, Some(JwtKey::from_slice(&DEFAULT_JWT_SECRET).unwrap()), spec.clone(), diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index 590b1ffe5ec..0769a86a382 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -21,7 +21,10 @@ pub use types::{ ExecutionPayloadRef, FixedVector, ForkName, Hash256, Transactions, Uint256, VariableList, Withdrawal, Withdrawals, }; -use types::{ExecutionPayloadCapella, ExecutionPayloadEip4844, ExecutionPayloadMerge}; +use types::{ + DepositReceipt, ExecutionPayloadCapella, ExecutionPayloadEip4844, ExecutionPayloadEip6110, + ExecutionPayloadMerge, +}; pub mod auth; pub mod http; @@ -151,7 +154,7 @@ pub struct ExecutionBlock { /// Representation of an execution block with enough detail to reconstruct a payload. #[superstruct( - variants(Merge, Capella, Eip4844), + variants(Merge, Capella, Eip4844, Eip6110), variant_attributes( derive(Clone, Debug, PartialEq, Serialize, Deserialize,), serde(bound = "T: EthSpec", rename_all = "camelCase"), @@ -182,15 +185,15 @@ pub struct ExecutionBlockWithTransactions { #[serde(with = "ssz_types::serde_utils::hex_var_list")] pub extra_data: VariableList, pub base_fee_per_gas: Uint256, - #[superstruct(only(Eip4844))] + #[superstruct(only(Eip4844, Eip6110))] #[serde(with = "eth2_serde_utils::u256_hex_be")] pub excess_data_gas: Uint256, #[serde(rename = "hash")] pub block_hash: ExecutionBlockHash, pub transactions: Vec, - #[superstruct(only(Capella, Eip4844))] + #[superstruct(only(Capella, Eip4844, Eip6110))] pub withdrawals: Vec, - #[superstruct(only(Eip4844))] + #[superstruct(only(Eip6110))] pub deposit_receipts: Vec, } @@ -270,6 +273,33 @@ impl TryFrom> for ExecutionBlockWithTransactions .into_iter() .map(|withdrawal| withdrawal.into()) .collect(), + }) + } + ExecutionPayload::Eip6110(block) => { + Self::Eip6110(ExecutionBlockWithTransactionsEip6110 { + 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, + excess_data_gas: block.excess_data_gas, + block_hash: block.block_hash, + transactions: block + .transactions + .iter() + .map(|tx| Transaction::decode(&Rlp::new(tx))) + .collect::, _>>()?, + withdrawals: Vec::from(block.withdrawals) + .into_iter() + .map(|withdrawal| withdrawal.into()) + .collect(), deposit_receipts: Vec::from(block.deposit_receipts) .into_iter() .map(|receipt| receipt.into()) @@ -297,6 +327,8 @@ pub struct PayloadAttributes { pub suggested_fee_recipient: Address, #[superstruct(only(V2))] pub withdrawals: Vec, + #[superstruct(only(V2))] + pub deposit_receipts: Vec, } impl PayloadAttributes { @@ -312,6 +344,7 @@ impl PayloadAttributes { prev_randao, suggested_fee_recipient, withdrawals, + deposit_receipts: Vec::new(), }), None => PayloadAttributes::V1(PayloadAttributesV1 { timestamp, @@ -339,6 +372,7 @@ impl From for SsePayloadAttributes { prev_randao, suggested_fee_recipient, withdrawals, + deposit_receipts: _, }) => Self::V2(SsePayloadAttributesV2 { timestamp, prev_randao, @@ -370,7 +404,7 @@ pub struct ProposeBlindedBlockResponse { } #[superstruct( - variants(Merge, Capella, Eip4844), + variants(Merge, Capella, Eip4844, Eip6110), variant_attributes(derive(Clone, Debug, PartialEq),), map_into(ExecutionPayload), map_ref_into(ExecutionPayloadRef), @@ -385,6 +419,8 @@ pub struct GetPayloadResponse { pub execution_payload: ExecutionPayloadCapella, #[superstruct(only(Eip4844), partial_getter(rename = "execution_payload_eip4844"))] pub execution_payload: ExecutionPayloadEip4844, + #[superstruct(only(Eip6110), partial_getter(rename = "execution_payload_eip6110"))] + pub execution_payload: ExecutionPayloadEip6110, pub block_value: Uint256, } @@ -419,6 +455,10 @@ impl From> for (ExecutionPayload, Uint256) ExecutionPayload::Eip4844(inner.execution_payload), inner.block_value, ), + GetPayloadResponse::Eip6110(inner) => ( + ExecutionPayload::Eip6110(inner.execution_payload), + inner.block_value, + ), } } } diff --git a/beacon_node/execution_layer/src/engine_api/http.rs b/beacon_node/execution_layer/src/engine_api/http.rs index df7d5d25e8c..505eb11cd61 100644 --- a/beacon_node/execution_layer/src/engine_api/http.rs +++ b/beacon_node/execution_layer/src/engine_api/http.rs @@ -33,11 +33,13 @@ pub const ETH_SYNCING_TIMEOUT: Duration = Duration::from_secs(1); pub const ENGINE_NEW_PAYLOAD_V1: &str = "engine_newPayloadV1"; pub const ENGINE_NEW_PAYLOAD_V2: &str = "engine_newPayloadV2"; pub const ENGINE_NEW_PAYLOAD_V3: &str = "engine_newPayloadV3"; +pub const ENGINE_NEW_PAYLOAD_V4: &str = "engine_newPayloadV4"; pub const ENGINE_NEW_PAYLOAD_TIMEOUT: Duration = Duration::from_secs(8); pub const ENGINE_GET_PAYLOAD_V1: &str = "engine_getPayloadV1"; pub const ENGINE_GET_PAYLOAD_V2: &str = "engine_getPayloadV2"; pub const ENGINE_GET_PAYLOAD_V3: &str = "engine_getPayloadV3"; +pub const ENGINE_GET_PAYLOAD_V4: &str = "engine_getPayloadV4"; pub const ENGINE_GET_PAYLOAD_TIMEOUT: Duration = Duration::from_secs(2); pub const ENGINE_GET_BLOBS_BUNDLE_V1: &str = "engine_getBlobsBundleV1"; @@ -765,6 +767,14 @@ impl HttpJsonRpc { ) .await?, ), + ForkName::Eip6110 => ExecutionBlockWithTransactions::Eip6110( + 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 {:?}", @@ -876,9 +886,30 @@ impl HttpJsonRpc { .await?; Ok(JsonGetPayloadResponse::V2(response).into()) } - ForkName::Base | ForkName::Altair | ForkName::Eip4844 => Err( - Error::UnsupportedForkVariant(format!("called get_payload_v2 with {}", fork_name)), - ), + ForkName::Eip4844 => { + let response: JsonGetPayloadResponseV3 = self + .rpc_request( + ENGINE_GET_PAYLOAD_V2, + params, + ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, + ) + .await?; + Ok(JsonGetPayloadResponse::V3(response).into()) + } + ForkName::Eip6110 => { + let response: JsonGetPayloadResponseV4 = self + .rpc_request( + ENGINE_GET_PAYLOAD_V2, + params, + ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, + ) + .await?; + Ok(JsonGetPayloadResponse::V4(response).into()) + } + ForkName::Base | ForkName::Altair => Err(Error::UnsupportedForkVariant(format!( + "called get_payload_v2 with {}", + fork_name + ))), } } @@ -920,6 +951,16 @@ impl HttpJsonRpc { .await?; Ok(JsonGetPayloadResponse::V3(response).into()) } + ForkName::Eip6110 => { + let response: JsonGetPayloadResponseV4 = self + .rpc_request( + ENGINE_GET_PAYLOAD_V4, + params, + ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, + ) + .await?; + Ok(JsonGetPayloadResponse::V4(response).into()) + } ForkName::Base | ForkName::Altair => Err(Error::UnsupportedForkVariant(format!( "called get_payload_v3 with {}", fork_name diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index 0384aad4886..c028abdd0e1 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -7,7 +7,7 @@ use superstruct::superstruct; use types::blobs_sidecar::KzgCommitments; use types::{ Blobs, DepositReceipt, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadCapella, - ExecutionPayloadEip4844, ExecutionPayloadMerge, FixedVector, Transactions, Unsigned, + ExecutionPayloadEip4844, ExecutionPayloadEip6110, ExecutionPayloadMerge, FixedVector, Transactions, Transaction, Unsigned, VariableList, Withdrawal, }; @@ -65,7 +65,7 @@ pub struct JsonPayloadIdResponse { } #[superstruct( - variants(V1, V2, V3), + variants(V1, V2, V3, V4), variant_attributes( derive(Debug, PartialEq, Default, Serialize, Deserialize,), serde(bound = "T: EthSpec", rename_all = "camelCase"), @@ -95,16 +95,16 @@ pub struct JsonExecutionPayload { pub extra_data: VariableList, #[serde(with = "eth2_serde_utils::u256_hex_be")] pub base_fee_per_gas: Uint256, - #[superstruct(only(V3))] + #[superstruct(only(V3, V4))] #[serde(with = "eth2_serde_utils::u256_hex_be")] pub excess_data_gas: Uint256, pub block_hash: ExecutionBlockHash, #[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")] - pub transactions: Transactions, - #[superstruct(only(V2, V3))] + pub transactions: VariableList, T::MaxTransactionsPerPayload>, + #[superstruct(only(V2, V3, V4))] pub withdrawals: VariableList, - #[superstruct(only(V3))] - pub deposit_receipts: VariableList, + #[superstruct(only(V4))] + pub deposit_receipts: VariableList, } impl From> for JsonExecutionPayloadV1 { @@ -177,6 +177,33 @@ impl From> for JsonExecutionPayloadV3 .map(Into::into) .collect::>() .into(), + } + } +} +impl From> for JsonExecutionPayloadV4 { + fn from(payload: ExecutionPayloadEip6110) -> Self { + JsonExecutionPayloadV4 { + parent_hash: payload.parent_hash, + fee_recipient: payload.fee_recipient, + state_root: payload.state_root, + receipts_root: payload.receipts_root, + logs_bloom: payload.logs_bloom, + prev_randao: payload.prev_randao, + block_number: payload.block_number, + gas_limit: payload.gas_limit, + gas_used: payload.gas_used, + timestamp: payload.timestamp, + extra_data: payload.extra_data, + base_fee_per_gas: payload.base_fee_per_gas, + excess_data_gas: payload.excess_data_gas, + block_hash: payload.block_hash, + transactions: payload.transactions, + withdrawals: payload + .withdrawals + .into_iter() + .map(Into::into) + .collect::>() + .into(), deposit_receipts: payload .deposit_receipts .into_iter() @@ -193,6 +220,7 @@ impl From> for JsonExecutionPayload { ExecutionPayload::Merge(payload) => JsonExecutionPayload::V1(payload.into()), ExecutionPayload::Capella(payload) => JsonExecutionPayload::V2(payload.into()), ExecutionPayload::Eip4844(payload) => JsonExecutionPayload::V3(payload.into()), + ExecutionPayload::Eip6110(payload) => JsonExecutionPayload::V4(payload.into()), } } } @@ -267,6 +295,33 @@ impl From> for ExecutionPayloadEip4844 .map(Into::into) .collect::>() .into(), + } + } +} +impl From> for ExecutionPayloadEip6110 { + fn from(payload: JsonExecutionPayloadV4) -> Self { + ExecutionPayloadEip6110 { + parent_hash: payload.parent_hash, + fee_recipient: payload.fee_recipient, + state_root: payload.state_root, + receipts_root: payload.receipts_root, + logs_bloom: payload.logs_bloom, + prev_randao: payload.prev_randao, + block_number: payload.block_number, + gas_limit: payload.gas_limit, + gas_used: payload.gas_used, + timestamp: payload.timestamp, + extra_data: payload.extra_data, + base_fee_per_gas: payload.base_fee_per_gas, + excess_data_gas: payload.excess_data_gas, + block_hash: payload.block_hash, + transactions: payload.transactions, + withdrawals: payload + .withdrawals + .into_iter() + .map(Into::into) + .collect::>() + .into(), deposit_receipts: payload .deposit_receipts .into_iter() @@ -283,12 +338,13 @@ impl From> for ExecutionPayload { JsonExecutionPayload::V1(payload) => ExecutionPayload::Merge(payload.into()), JsonExecutionPayload::V2(payload) => ExecutionPayload::Capella(payload.into()), JsonExecutionPayload::V3(payload) => ExecutionPayload::Eip4844(payload.into()), + JsonExecutionPayload::V4(payload) => ExecutionPayload::Eip6110(payload.into()), } } } #[superstruct( - variants(V1, V2, V3), + variants(V1, V2, V3, V4), variant_attributes( derive(Debug, PartialEq, Serialize, Deserialize), serde(bound = "T: EthSpec", rename_all = "camelCase") @@ -305,6 +361,8 @@ pub struct JsonGetPayloadResponse { pub execution_payload: JsonExecutionPayloadV2, #[superstruct(only(V3), partial_getter(rename = "execution_payload_v3"))] pub execution_payload: JsonExecutionPayloadV3, + #[superstruct(only(V4), partial_getter(rename = "execution_payload_v4"))] + pub execution_payload: JsonExecutionPayloadV4, #[serde(with = "eth2_serde_utils::u256_hex_be")] pub block_value: Uint256, } @@ -330,6 +388,12 @@ impl From> for GetPayloadResponse { block_value: response.block_value, }) } + JsonGetPayloadResponse::V4(response) => { + GetPayloadResponse::Eip6110(GetPayloadResponseEip6110 { + execution_payload: response.execution_payload.into(), + block_value: response.block_value, + }) + } } } } @@ -422,6 +486,8 @@ pub struct JsonPayloadAttributes { pub suggested_fee_recipient: Address, #[superstruct(only(V2))] pub withdrawals: Vec, + #[superstruct(only(V2))] + pub deposit_receipts: Vec, } impl From for JsonPayloadAttributes { @@ -437,6 +503,7 @@ impl From for JsonPayloadAttributes { prev_randao: pa.prev_randao, suggested_fee_recipient: pa.suggested_fee_recipient, withdrawals: pa.withdrawals.into_iter().map(Into::into).collect(), + deposit_receipts: pa.deposit_receipts.into_iter().map(Into::into).collect(), }), } } @@ -455,6 +522,7 @@ impl From for PayloadAttributes { prev_randao: jpa.prev_randao, suggested_fee_recipient: jpa.suggested_fee_recipient, withdrawals: jpa.withdrawals.into_iter().map(Into::into).collect(), + deposit_receipts: jpa.deposit_receipts.into_iter().map(Into::into).collect(), }), } } diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 9702e210569..4a7ea6ccdb7 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -43,13 +43,14 @@ use tokio_stream::wrappers::WatchStream; use tree_hash::TreeHash; use types::consts::eip4844::BLOB_TX_TYPE; use types::transaction::{AccessTuple, BlobTransaction, EcdsaSignature, SignedBlobTransaction}; +use types::Withdrawals; use types::{ blobs_sidecar::{Blobs, KzgCommitments}, BlindedPayload, BlockType, ChainSpec, Epoch, ExecutionBlockHash, ExecutionPayload, - ExecutionPayloadCapella, ExecutionPayloadEip4844, ExecutionPayloadMerge, ForkName, + ExecutionPayloadCapella, ExecutionPayloadEip4844, ExecutionPayloadEip6110, + ExecutionPayloadMerge, ForkName, }; use types::{AbstractExecPayload, BeaconStateError, ExecPayload, VersionedHash}; -use types::{DepositReceipt, Withdrawals}; use types::{ ProposerPreparationData, PublicKeyBytes, Signature, SignedBeaconBlock, Slot, Transaction, Uint256, @@ -213,6 +214,12 @@ impl> BlockProposalContents BlockProposalContents::PayloadAndBlobs { + payload: Payload::default_at_fork(fork_name)?, + block_value: Uint256::zero(), + blobs: VariableList::default(), + kzg_commitments: VariableList::default(), + }, }) } } @@ -1110,7 +1117,7 @@ impl ExecutionLayer { ForkName::Base | ForkName::Altair | ForkName::Merge | ForkName::Capella => { None } - ForkName::Eip4844 => { + ForkName::Eip4844 | ForkName::Eip6110 => { debug!( self.log(), "Issuing engine_getBlobsBundle"; @@ -1703,6 +1710,7 @@ impl ExecutionLayer { ForkName::Merge => Ok(Some(ExecutionPayloadMerge::default().into())), ForkName::Capella => Ok(Some(ExecutionPayloadCapella::default().into())), ForkName::Eip4844 => Ok(Some(ExecutionPayloadEip4844::default().into())), + ForkName::Eip6110 => Ok(Some(ExecutionPayloadEip6110::default().into())), ForkName::Base | ForkName::Altair => Err(ApiError::UnsupportedForkVariant( format!("called get_payload_by_block_hash_from_engine with {}", fork), )), @@ -1785,15 +1793,6 @@ impl ExecutionLayer { ) .map_err(ApiError::DeserializeWithdrawals)?; - let deposit_receipts = eip4844_block - .deposit_receipts - .into_iter() - .map(Into::into) - .collect::>(); - - let deposit_receipts = VariableList::new(deposit_receipts) - .map_err(ApiError::DeserializeDepositReceipts)?; - ExecutionPayload::Eip4844(ExecutionPayloadEip4844 { parent_hash: eip4844_block.parent_hash, fee_recipient: eip4844_block.fee_recipient, @@ -1811,6 +1810,44 @@ impl ExecutionLayer { block_hash: eip4844_block.block_hash, transactions: convert_transactions(eip4844_block.transactions)?, withdrawals, + }) + } + ExecutionBlockWithTransactions::Eip6110(eip6110_block) => { + let withdrawals = VariableList::new( + eip6110_block + .withdrawals + .into_iter() + .map(Into::into) + .collect(), + ) + .map_err(ApiError::DeserializeWithdrawals)?; + + let deposit_receipts = VariableList::new( + eip6110_block + .deposit_receipts + .into_iter() + .map(Into::into) + .collect(), + ) + .map_err(ApiError::DeserializeDepositReceipts)?; + + ExecutionPayload::Eip6110(ExecutionPayloadEip6110 { + parent_hash: eip6110_block.parent_hash, + fee_recipient: eip6110_block.fee_recipient, + state_root: eip6110_block.state_root, + receipts_root: eip6110_block.receipts_root, + logs_bloom: eip6110_block.logs_bloom, + prev_randao: eip6110_block.prev_randao, + block_number: eip6110_block.block_number, + gas_limit: eip6110_block.gas_limit, + gas_used: eip6110_block.gas_used, + timestamp: eip6110_block.timestamp, + extra_data: eip6110_block.extra_data, + base_fee_per_gas: eip6110_block.base_fee_per_gas, + excess_data_gas: eip6110_block.excess_data_gas, + block_hash: eip6110_block.block_hash, + transactions: convert_transactions(eip6110_block.transactions)?, + withdrawals, deposit_receipts, }) } diff --git a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs index a6db7eee594..768c2d35dc5 100644 --- a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs +++ b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs @@ -14,7 +14,8 @@ use tree_hash::TreeHash; use tree_hash_derive::TreeHash; use types::{ EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadCapella, - ExecutionPayloadEip4844, ExecutionPayloadMerge, ForkName, Hash256, Uint256, + ExecutionPayloadEip4844, ExecutionPayloadEip6110, ExecutionPayloadMerge, ForkName, Hash256, + Uint256, }; const GAS_LIMIT: u64 = 16384; @@ -119,6 +120,7 @@ pub struct ExecutionBlockGenerator { */ pub shanghai_time: Option, // withdrawals pub eip4844_time: Option, // 4844 + pub eip6110_time: Option, // 6110 } impl ExecutionBlockGenerator { @@ -128,6 +130,7 @@ impl ExecutionBlockGenerator { terminal_block_hash: ExecutionBlockHash, shanghai_time: Option, eip4844_time: Option, + eip6110_time: Option, ) -> Self { let mut gen = Self { head_block: <_>::default(), @@ -142,6 +145,7 @@ impl ExecutionBlockGenerator { payload_ids: <_>::default(), shanghai_time, eip4844_time, + eip6110_time, }; gen.insert_pow_block(0).unwrap(); @@ -174,11 +178,14 @@ impl ExecutionBlockGenerator { } pub fn get_fork_at_timestamp(&self, timestamp: u64) -> ForkName { - match self.eip4844_time { - Some(fork_time) if timestamp >= fork_time => ForkName::Eip4844, - _ => match self.shanghai_time { - Some(fork_time) if timestamp >= fork_time => ForkName::Capella, - _ => ForkName::Merge, + match self.eip6110_time { + Some(fork_time) if timestamp >= fork_time => ForkName::Eip6110, + _ => match self.eip4844_time { + Some(fork_time) if timestamp >= fork_time => ForkName::Eip4844, + _ => match self.shanghai_time { + Some(fork_time) if timestamp >= fork_time => ForkName::Capella, + _ => ForkName::Merge, + }, }, } } @@ -554,7 +561,28 @@ impl ExecutionBlockGenerator { block_hash: ExecutionBlockHash::zero(), transactions: vec![].into(), withdrawals: pa.withdrawals.clone().into(), - deposit_receipts: vec![].into(), // TODO: Check if deposit receipts should be part of PayloadAttributesV2 + }) + } + ForkName::Eip6110 => { + ExecutionPayload::Eip6110(ExecutionPayloadEip6110 { + parent_hash: forkchoice_state.head_block_hash, + fee_recipient: pa.suggested_fee_recipient, + receipts_root: Hash256::repeat_byte(42), + state_root: Hash256::repeat_byte(43), + logs_bloom: vec![0; 256].into(), + prev_randao: pa.prev_randao, + block_number: parent.block_number() + 1, + gas_limit: GAS_LIMIT, + gas_used: GAS_USED, + timestamp: pa.timestamp, + extra_data: "block gen was here".as_bytes().to_vec().into(), + base_fee_per_gas: Uint256::one(), + // FIXME(4844): maybe this should be set to something? + excess_data_gas: Uint256::one(), + block_hash: ExecutionBlockHash::zero(), + transactions: vec![].into(), + withdrawals: pa.withdrawals.clone().into(), + deposit_receipts: pa.deposit_receipts.clone().into(), }) } _ => unreachable!(), @@ -651,6 +679,7 @@ mod test { ExecutionBlockHash::zero(), None, None, + None, ); for i in 0..=TERMINAL_BLOCK { diff --git a/beacon_node/execution_layer/src/test_utils/handle_rpc.rs b/beacon_node/execution_layer/src/test_utils/handle_rpc.rs index a1488e2dc9a..3c483bdb8fb 100644 --- a/beacon_node/execution_layer/src/test_utils/handle_rpc.rs +++ b/beacon_node/execution_layer/src/test_utils/handle_rpc.rs @@ -112,6 +112,21 @@ pub async fn handle_rpc( }) }) .map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?, + ENGINE_NEW_PAYLOAD_V4 => get_param::>(params, 0) + .map(|jep| JsonExecutionPayload::V4(jep)) + .or_else(|_| { + get_param::>(params, 0) + .map(|jep| JsonExecutionPayload::V3(jep)) + .or_else(|_| { + get_param::>(params, 0) + .map(|jep| JsonExecutionPayload::V2(jep)) + .or_else(|_| { + get_param::>(params, 0) + .map(|jep| JsonExecutionPayload::V1(jep)) + }) + }) + }) + .map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?, _ => unreachable!(), }; @@ -175,6 +190,44 @@ pub async fn handle_rpc( )); } } + ForkName::Eip6110 => { + if method == ENGINE_NEW_PAYLOAD_V1 + || method == ENGINE_NEW_PAYLOAD_V2 + || method == ENGINE_NEW_PAYLOAD_V3 + { + return Err(( + format!("{} called after eip6110 fork!", method), + GENERIC_ERROR_CODE, + )); + } + if matches!(request, JsonExecutionPayload::V1(_)) { + return Err(( + format!( + "{} called with `ExecutionPayloadV1` after eip6110 fork!", + method + ), + GENERIC_ERROR_CODE, + )); + } + if matches!(request, JsonExecutionPayload::V2(_)) { + return Err(( + format!( + "{} called with `ExecutionPayloadV2` after eip6110 fork!", + method + ), + GENERIC_ERROR_CODE, + )); + } + if matches!(request, JsonExecutionPayload::V3(_)) { + return Err(( + format!( + "{} called with `ExecutionPayloadV3` after eip6110 fork!", + method + ), + GENERIC_ERROR_CODE, + )); + } + } _ => unreachable!(), }; @@ -208,7 +261,10 @@ pub async fn handle_rpc( Ok(serde_json::to_value(JsonPayloadStatusV1::from(response)).unwrap()) } - ENGINE_GET_PAYLOAD_V1 | ENGINE_GET_PAYLOAD_V2 | ENGINE_GET_PAYLOAD_V3 => { + ENGINE_GET_PAYLOAD_V1 + | ENGINE_GET_PAYLOAD_V2 + | ENGINE_GET_PAYLOAD_V3 + | ENGINE_GET_PAYLOAD_V4 => { let request: JsonPayloadIdRequest = get_param(params, 0).map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?; let id = request.into(); @@ -294,6 +350,43 @@ pub async fn handle_rpc( }) .unwrap() } + JsonExecutionPayload::V4(execution_payload) => { + serde_json::to_value(JsonGetPayloadResponseV4 { + execution_payload, + block_value: DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI.into(), + }) + .unwrap() + } + }), + ENGINE_GET_PAYLOAD_V4 => Ok(match JsonExecutionPayload::from(response) { + JsonExecutionPayload::V1(execution_payload) => { + serde_json::to_value(JsonGetPayloadResponseV1 { + execution_payload, + block_value: DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI.into(), + }) + .unwrap() + } + JsonExecutionPayload::V2(execution_payload) => { + serde_json::to_value(JsonGetPayloadResponseV2 { + execution_payload, + block_value: DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI.into(), + }) + .unwrap() + } + JsonExecutionPayload::V3(execution_payload) => { + serde_json::to_value(JsonGetPayloadResponseV3 { + execution_payload, + block_value: DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI.into(), + }) + .unwrap() + } + JsonExecutionPayload::V4(execution_payload) => { + serde_json::to_value(JsonGetPayloadResponseV4 { + execution_payload, + block_value: DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI.into(), + }) + .unwrap() + } }), _ => unreachable!(), } diff --git a/beacon_node/execution_layer/src/test_utils/mock_builder.rs b/beacon_node/execution_layer/src/test_utils/mock_builder.rs index 19972650139..b5a500c3f3e 100644 --- a/beacon_node/execution_layer/src/test_utils/mock_builder.rs +++ b/beacon_node/execution_layer/src/test_utils/mock_builder.rs @@ -405,7 +405,7 @@ impl mev_rs::BlindedBlockProvider for MockBuilder { let payload_attributes = match fork { ForkName::Merge => PayloadAttributes::new(timestamp, *prev_randao, fee_recipient, None), // the withdrawals root is filled in by operations - ForkName::Capella | ForkName::Eip4844 => { + ForkName::Capella | ForkName::Eip4844 | ForkName::Eip6110 => { PayloadAttributes::new(timestamp, *prev_randao, fee_recipient, Some(vec![])) } ForkName::Base | ForkName::Altair => { @@ -452,7 +452,7 @@ impl mev_rs::BlindedBlockProvider for MockBuilder { value: to_ssz_rs(&Uint256::from(DEFAULT_BUILDER_PAYLOAD_VALUE_WEI))?, public_key: self.builder_sk.public_key(), }), - ForkName::Base | ForkName::Altair | ForkName::Eip4844 => { + ForkName::Base | ForkName::Altair | ForkName::Eip4844 | ForkName::Eip6110 => { return Err(BlindedBlockProviderError::Custom(format!( "Unsupported fork: {}", fork diff --git a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs index 1a5d1fd1983..8848607856d 100644 --- a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs +++ b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs @@ -30,6 +30,7 @@ impl MockExecutionLayer { None, None, None, + None, Some(JwtKey::from_slice(&DEFAULT_JWT_SECRET).unwrap()), spec, None, @@ -42,6 +43,7 @@ impl MockExecutionLayer { terminal_block: u64, shanghai_time: Option, eip4844_time: Option, + eip6110_time: Option, builder_threshold: Option, jwt_key: Option, spec: ChainSpec, @@ -58,6 +60,7 @@ impl MockExecutionLayer { spec.terminal_block_hash, shanghai_time, eip4844_time, + eip6110_time, ); let url = SensitiveUrl::parse(&server.url()).unwrap(); diff --git a/beacon_node/execution_layer/src/test_utils/mod.rs b/beacon_node/execution_layer/src/test_utils/mod.rs index 3c0763a8fb9..e1a148caaa5 100644 --- a/beacon_node/execution_layer/src/test_utils/mod.rs +++ b/beacon_node/execution_layer/src/test_utils/mod.rs @@ -63,6 +63,7 @@ pub struct MockExecutionConfig { pub terminal_block_hash: ExecutionBlockHash, pub shanghai_time: Option, pub eip4844_time: Option, + pub eip6110_time: Option, } impl Default for MockExecutionConfig { @@ -75,6 +76,7 @@ impl Default for MockExecutionConfig { server_config: Config::default(), shanghai_time: None, eip4844_time: None, + eip6110_time: None, } } } @@ -96,6 +98,7 @@ impl MockServer { ExecutionBlockHash::zero(), None, // FIXME(capella): should this be the default? None, // FIXME(eip4844): should this be the default? + None, // FIXME(eip6110): should this be the default? ) } @@ -108,6 +111,7 @@ impl MockServer { server_config, shanghai_time, eip4844_time, + eip6110_time, } = config; let last_echo_request = Arc::new(RwLock::new(None)); let preloaded_responses = Arc::new(Mutex::new(vec![])); @@ -117,6 +121,7 @@ impl MockServer { terminal_block_hash, shanghai_time, eip4844_time, + eip6110_time, ); let ctx: Arc> = Arc::new(Context { @@ -176,6 +181,7 @@ impl MockServer { terminal_block_hash: ExecutionBlockHash, shanghai_time: Option, eip4844_time: Option, + eip6110_time: Option, ) -> Self { Self::new_with_config( handle, @@ -187,6 +193,7 @@ impl MockServer { terminal_block_hash, shanghai_time, eip4844_time, + eip6110_time, }, ) } diff --git a/beacon_node/lighthouse_network/src/config.rs b/beacon_node/lighthouse_network/src/config.rs index 79c8b67d75a..3ac41a8143e 100644 --- a/beacon_node/lighthouse_network/src/config.rs +++ b/beacon_node/lighthouse_network/src/config.rs @@ -412,7 +412,11 @@ pub fn gossipsub_config(network_load: u8, fork_context: Arc) -> Gos match fork_context.current_fork() { // according to: https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/p2p-interface.md#the-gossip-domain-gossipsub // the derivation of the message-id remains the same in the merge and for eip 4844. - ForkName::Altair | ForkName::Merge | ForkName::Capella | ForkName::Eip4844 => { + ForkName::Altair + | ForkName::Merge + | ForkName::Capella + | ForkName::Eip4844 + | ForkName::Eip6110 => { let topic_len_bytes = topic_bytes.len().to_le_bytes(); let mut vec = Vec::with_capacity( prefix.len() + topic_len_bytes.len() + topic_bytes.len() + message.data.len(), diff --git a/beacon_node/lighthouse_network/src/rpc/codec/base.rs b/beacon_node/lighthouse_network/src/rpc/codec/base.rs index 164a7c025d9..f442e59b85e 100644 --- a/beacon_node/lighthouse_network/src/rpc/codec/base.rs +++ b/beacon_node/lighthouse_network/src/rpc/codec/base.rs @@ -195,11 +195,13 @@ mod tests { let merge_fork_epoch = Epoch::new(2); let capella_fork_epoch = Epoch::new(3); let eip4844_fork_epoch = Epoch::new(4); + let eip6110_fork_epoch = Epoch::new(5); chain_spec.altair_fork_epoch = Some(altair_fork_epoch); chain_spec.bellatrix_fork_epoch = Some(merge_fork_epoch); chain_spec.capella_fork_epoch = Some(capella_fork_epoch); chain_spec.eip4844_fork_epoch = Some(eip4844_fork_epoch); + chain_spec.eip6110_fork_epoch = Some(eip6110_fork_epoch); let current_slot = match fork_name { ForkName::Base => Slot::new(0), @@ -207,6 +209,7 @@ mod tests { ForkName::Merge => merge_fork_epoch.start_slot(Spec::slots_per_epoch()), ForkName::Capella => capella_fork_epoch.start_slot(Spec::slots_per_epoch()), ForkName::Eip4844 => eip4844_fork_epoch.start_slot(Spec::slots_per_epoch()), + ForkName::Eip6110 => eip6110_fork_epoch.start_slot(Spec::slots_per_epoch()), }; ForkContext::new::(current_slot, Hash256::zero(), &chain_spec) } diff --git a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs index d94e8f52218..e75758f8974 100644 --- a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs +++ b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs @@ -19,7 +19,8 @@ use types::light_client_bootstrap::LightClientBootstrap; use types::{ BlobsSidecar, EthSpec, ForkContext, ForkName, Hash256, SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockAndBlobsSidecar, SignedBeaconBlockBase, - SignedBeaconBlockCapella, SignedBeaconBlockEip4844, SignedBeaconBlockMerge, + SignedBeaconBlockCapella, SignedBeaconBlockEip4844, SignedBeaconBlockEip6110, + SignedBeaconBlockMerge, }; use unsigned_varint::codec::Uvi; @@ -419,6 +420,10 @@ fn context_bytes( return match **ref_box_block { // NOTE: If you are adding another fork type here, be sure to modify the // `fork_context.to_context_bytes()` function to support it as well! + SignedBeaconBlock::Eip6110 { .. } => { + // Eip6110 context being `None` implies that "merge never happened". + fork_context.to_context_bytes(ForkName::Eip6110) + } SignedBeaconBlock::Eip4844 { .. } => { // Eip4844 context being `None` implies that "merge never happened". fork_context.to_context_bytes(ForkName::Eip4844) @@ -668,6 +673,11 @@ fn handle_v2_response( decoded_buffer, )?), )))), + ForkName::Eip6110 => Ok(Some(RPCResponse::BlocksByRange(Arc::new( + SignedBeaconBlock::Eip6110(SignedBeaconBlockEip6110::from_ssz_bytes( + decoded_buffer, + )?), + )))), }, Protocol::BlocksByRoot => match fork_name { ForkName::Altair => Ok(Some(RPCResponse::BlocksByRoot(Arc::new( @@ -693,6 +703,11 @@ fn handle_v2_response( decoded_buffer, )?), )))), + ForkName::Eip6110 => Ok(Some(RPCResponse::BlocksByRoot(Arc::new( + SignedBeaconBlock::Eip6110(SignedBeaconBlockEip6110::from_ssz_bytes( + decoded_buffer, + )?), + )))), }, Protocol::BlobsByRange => { Err(RPCError::InvalidData("blobs by range via v2".to_string())) @@ -754,11 +769,13 @@ mod tests { let merge_fork_epoch = Epoch::new(2); let capella_fork_epoch = Epoch::new(3); let eip4844_fork_epoch = Epoch::new(4); + let eip6110_fork_epoch = Epoch::new(5); chain_spec.altair_fork_epoch = Some(altair_fork_epoch); chain_spec.bellatrix_fork_epoch = Some(merge_fork_epoch); chain_spec.capella_fork_epoch = Some(capella_fork_epoch); chain_spec.eip4844_fork_epoch = Some(eip4844_fork_epoch); + chain_spec.eip6110_fork_epoch = Some(eip6110_fork_epoch); let current_slot = match fork_name { ForkName::Base => Slot::new(0), @@ -766,6 +783,7 @@ mod tests { ForkName::Merge => merge_fork_epoch.start_slot(Spec::slots_per_epoch()), ForkName::Capella => capella_fork_epoch.start_slot(Spec::slots_per_epoch()), ForkName::Eip4844 => eip4844_fork_epoch.start_slot(Spec::slots_per_epoch()), + ForkName::Eip6110 => eip6110_fork_epoch.start_slot(Spec::slots_per_epoch()), }; ForkContext::new::(current_slot, Hash256::zero(), &chain_spec) } diff --git a/beacon_node/lighthouse_network/src/rpc/protocol.rs b/beacon_node/lighthouse_network/src/rpc/protocol.rs index d11240ebf9e..1382f498a6c 100644 --- a/beacon_node/lighthouse_network/src/rpc/protocol.rs +++ b/beacon_node/lighthouse_network/src/rpc/protocol.rs @@ -90,6 +90,12 @@ lazy_static! { + (::ssz_fixed_len() * ::max_blobs_per_block()) + ssz::BYTES_PER_LENGTH_OFFSET; // Length offset for the blob commitments field. + pub static ref SIGNED_BEACON_BLOCK_EIP6110_MAX: usize = *SIGNED_BEACON_BLOCK_CAPELLA_MAX_WITHOUT_PAYLOAD + + types::ExecutionPayload::::max_execution_payload_eip6110_size() // adding max size of execution payload (~16gb) + + ssz::BYTES_PER_LENGTH_OFFSET // Adding the additional offsets for the `ExecutionPayload` + + (::ssz_fixed_len() * ::max_blobs_per_block()) + + ssz::BYTES_PER_LENGTH_OFFSET; // Length offset for the blob commitments field. + pub static ref BLOCKS_BY_ROOT_REQUEST_MIN: usize = VariableList::::from(Vec::::new()) .as_ssz_bytes() @@ -130,6 +136,7 @@ pub(crate) const MAX_RPC_SIZE_POST_MERGE: usize = 10 * 1_048_576; // 10M pub(crate) const MAX_RPC_SIZE_POST_CAPELLA: usize = 10 * 1_048_576; // 10M // FIXME(sean) should this be increased to account for blobs? pub(crate) const MAX_RPC_SIZE_POST_EIP4844: usize = 10 * 1_048_576; // 10M +pub(crate) const MAX_RPC_SIZE_POST_EIP6110: usize = 10 * 1_048_576; // 10M /// The protocol prefix the RPC protocol id. const PROTOCOL_PREFIX: &str = "/eth2/beacon_chain/req"; /// Time allowed for the first byte of a request to arrive before we time out (Time To First Byte). @@ -145,6 +152,7 @@ pub fn max_rpc_size(fork_context: &ForkContext) -> usize { ForkName::Merge => MAX_RPC_SIZE_POST_MERGE, ForkName::Capella => MAX_RPC_SIZE_POST_CAPELLA, ForkName::Eip4844 => MAX_RPC_SIZE_POST_EIP4844, + ForkName::Eip6110 => MAX_RPC_SIZE_POST_EIP6110, } } @@ -173,6 +181,10 @@ pub fn rpc_block_limits_by_fork(current_fork: ForkName) -> RpcLimits { *SIGNED_BEACON_BLOCK_BASE_MIN, // Base block is smaller than altair and merge blocks *SIGNED_BEACON_BLOCK_EIP4844_MAX, // EIP 4844 block is larger than all prior fork blocks ), + ForkName::Eip6110 => RpcLimits::new( + *SIGNED_BEACON_BLOCK_BASE_MIN, // Base block is smaller than altair and merge blocks + *SIGNED_BEACON_BLOCK_EIP6110_MAX, // EIP 6110 block is larger than all prior fork blocks + ), } } diff --git a/beacon_node/lighthouse_network/src/types/pubsub.rs b/beacon_node/lighthouse_network/src/types/pubsub.rs index 7951a072438..4b47a8641ed 100644 --- a/beacon_node/lighthouse_network/src/types/pubsub.rs +++ b/beacon_node/lighthouse_network/src/types/pubsub.rs @@ -190,6 +190,12 @@ impl PubsubMessage { .to_string(), ) } + Some(ForkName::Eip6110) => { + return Err( + "beacon_block topic is not used from eip4844 fork onwards" + .to_string(), + ) + } Some(ForkName::Capella) => SignedBeaconBlock::::Capella( SignedBeaconBlockCapella::from_ssz_bytes(data) .map_err(|e| format!("{:?}", e))?, @@ -205,7 +211,7 @@ impl PubsubMessage { } GossipKind::BeaconBlocksAndBlobsSidecar => { match fork_context.from_context_bytes(gossip_topic.fork_digest) { - Some(ForkName::Eip4844) => { + Some(ForkName::Eip4844) | Some(ForkName::Eip6110) => { let block_and_blobs_sidecar = SignedBeaconBlockAndBlobsSidecar::from_ssz_bytes(data) .map_err(|e| format!("{:?}", e))?; diff --git a/beacon_node/lighthouse_network/src/types/topics.rs b/beacon_node/lighthouse_network/src/types/topics.rs index 20f836b76a1..a78f21af9cd 100644 --- a/beacon_node/lighthouse_network/src/types/topics.rs +++ b/beacon_node/lighthouse_network/src/types/topics.rs @@ -48,6 +48,7 @@ pub fn fork_core_topics(fork_name: &ForkName) -> Vec { ForkName::Merge => vec![], ForkName::Capella => CAPELLA_CORE_TOPICS.to_vec(), ForkName::Eip4844 => vec![], // TODO + ForkName::Eip6110 => vec![], // TODO } } diff --git a/beacon_node/lighthouse_network/tests/common.rs b/beacon_node/lighthouse_network/tests/common.rs index bd153284edb..740b5a151b0 100644 --- a/beacon_node/lighthouse_network/tests/common.rs +++ b/beacon_node/lighthouse_network/tests/common.rs @@ -27,11 +27,13 @@ pub fn fork_context(fork_name: ForkName) -> ForkContext { let merge_fork_epoch = Epoch::new(2); let capella_fork_epoch = Epoch::new(3); let eip4844_fork_epoch = Epoch::new(4); + let eip6110_fork_epoch = Epoch::new(5); chain_spec.altair_fork_epoch = Some(altair_fork_epoch); chain_spec.bellatrix_fork_epoch = Some(merge_fork_epoch); chain_spec.capella_fork_epoch = Some(capella_fork_epoch); chain_spec.eip4844_fork_epoch = Some(eip4844_fork_epoch); + chain_spec.eip6110_fork_epoch = Some(eip6110_fork_epoch); let current_slot = match fork_name { ForkName::Base => Slot::new(0), @@ -39,6 +41,7 @@ pub fn fork_context(fork_name: ForkName) -> ForkContext { ForkName::Merge => merge_fork_epoch.start_slot(E::slots_per_epoch()), ForkName::Capella => capella_fork_epoch.start_slot(E::slots_per_epoch()), ForkName::Eip4844 => eip4844_fork_epoch.start_slot(E::slots_per_epoch()), + ForkName::Eip6110 => eip6110_fork_epoch.start_slot(E::slots_per_epoch()), }; ForkContext::new::(current_slot, Hash256::zero(), &chain_spec) } diff --git a/beacon_node/store/src/impls/execution_payload.rs b/beacon_node/store/src/impls/execution_payload.rs index 01a2dba0b0a..d89fe015617 100644 --- a/beacon_node/store/src/impls/execution_payload.rs +++ b/beacon_node/store/src/impls/execution_payload.rs @@ -2,7 +2,7 @@ use crate::{DBColumn, Error, StoreItem}; use ssz::{Decode, Encode}; use types::{ BlobsSidecar, EthSpec, ExecutionPayload, ExecutionPayloadCapella, ExecutionPayloadEip4844, - ExecutionPayloadMerge, + ExecutionPayloadEip6110, ExecutionPayloadMerge, }; macro_rules! impl_store_item { @@ -25,6 +25,7 @@ macro_rules! impl_store_item { impl_store_item!(ExecutionPayloadMerge); impl_store_item!(ExecutionPayloadCapella); impl_store_item!(ExecutionPayloadEip4844); +impl_store_item!(ExecutionPayloadEip6110); impl_store_item!(BlobsSidecar); /// This fork-agnostic implementation should be only used for writing. diff --git a/beacon_node/store/src/partial_beacon_state.rs b/beacon_node/store/src/partial_beacon_state.rs index b642c2752c6..e84e3409fb7 100644 --- a/beacon_node/store/src/partial_beacon_state.rs +++ b/beacon_node/store/src/partial_beacon_state.rs @@ -15,7 +15,7 @@ use types::*; /// /// Utilises lazy-loading from separate storage for its vector fields. #[superstruct( - variants(Base, Altair, Merge, Capella, Eip4844), + variants(Base, Altair, Merge, Capella, Eip4844, Eip6110), variant_attributes(derive(Debug, PartialEq, Clone, Encode, Decode)) )] #[derive(Debug, PartialEq, Clone, Encode)] @@ -67,9 +67,9 @@ where pub current_epoch_attestations: VariableList, T::MaxPendingAttestations>, // Participation (Altair and later) - #[superstruct(only(Altair, Merge, Capella, Eip4844))] + #[superstruct(only(Altair, Merge, Capella, Eip4844, Eip6110))] pub previous_epoch_participation: VariableList, - #[superstruct(only(Altair, Merge, Capella, Eip4844))] + #[superstruct(only(Altair, Merge, Capella, Eip4844, Eip6110))] pub current_epoch_participation: VariableList, // Finality @@ -79,13 +79,13 @@ where pub finalized_checkpoint: Checkpoint, // Inactivity - #[superstruct(only(Altair, Merge, Capella, Eip4844))] + #[superstruct(only(Altair, Merge, Capella, Eip4844, Eip6110))] pub inactivity_scores: VariableList, // Light-client sync committees - #[superstruct(only(Altair, Merge, Capella, Eip4844))] + #[superstruct(only(Altair, Merge, Capella, Eip4844, Eip6110))] pub current_sync_committee: Arc>, - #[superstruct(only(Altair, Merge, Capella, Eip4844))] + #[superstruct(only(Altair, Merge, Capella, Eip4844, Eip6110))] pub next_sync_committee: Arc>, // Execution @@ -104,18 +104,23 @@ where partial_getter(rename = "latest_execution_payload_header_eip4844") )] pub latest_execution_payload_header: ExecutionPayloadHeaderEip4844, + #[superstruct( + only(Eip6110), + partial_getter(rename = "latest_execution_payload_header_eip6110") + )] + pub latest_execution_payload_header: ExecutionPayloadHeaderEip6110, // Capella - #[superstruct(only(Capella, Eip4844))] + #[superstruct(only(Capella, Eip4844, Eip6110))] pub next_withdrawal_index: u64, - #[superstruct(only(Capella, Eip4844))] + #[superstruct(only(Capella, Eip4844, Eip6110))] pub next_withdrawal_validator_index: u64, #[ssz(skip_serializing, skip_deserializing)] - #[superstruct(only(Capella, Eip4844))] + #[superstruct(only(Capella, Eip4844, Eip6110))] pub historical_summaries: Option>, - #[superstruct(only(Capella, Eip4844))] + #[superstruct(only(Eip6110))] pub deposit_receipts_start_index: u64, } @@ -226,8 +231,7 @@ impl PartialBeaconState { inactivity_scores, latest_execution_payload_header, next_withdrawal_index, - next_withdrawal_validator_index, - deposit_receipts_start_index + next_withdrawal_validator_index ], [historical_summaries] ), @@ -236,6 +240,23 @@ impl PartialBeaconState { outer, Eip4844, PartialBeaconStateEip4844, + [ + previous_epoch_participation, + current_epoch_participation, + current_sync_committee, + next_sync_committee, + inactivity_scores, + latest_execution_payload_header, + next_withdrawal_index, + next_withdrawal_validator_index + ], + [historical_summaries] + ), + BeaconState::Eip6110(s) => impl_from_state_forgetful!( + s, + outer, + Eip6110, + PartialBeaconStateEip6110, [ previous_epoch_participation, current_epoch_participation, @@ -473,8 +494,7 @@ impl TryInto> for PartialBeaconState { inactivity_scores, latest_execution_payload_header, next_withdrawal_index, - next_withdrawal_validator_index, - deposit_receipts_start_index + next_withdrawal_validator_index ], [historical_summaries] ), @@ -482,6 +502,22 @@ impl TryInto> for PartialBeaconState { inner, Eip4844, BeaconStateEip4844, + [ + previous_epoch_participation, + current_epoch_participation, + current_sync_committee, + next_sync_committee, + inactivity_scores, + latest_execution_payload_header, + next_withdrawal_index, + next_withdrawal_validator_index + ], + [historical_summaries] + ), + PartialBeaconState::Eip6110(inner) => impl_try_into_beacon_state!( + inner, + Eip6110, + BeaconStateEip6110, [ previous_epoch_participation, current_epoch_participation, diff --git a/common/eth2/src/types.rs b/common/eth2/src/types.rs index d14746551c3..db07444e48e 100644 --- a/common/eth2/src/types.rs +++ b/common/eth2/src/types.rs @@ -959,9 +959,11 @@ impl ForkVersionDeserialize for SsePayloadAttributes { ForkName::Merge => serde_json::from_value(value) .map(Self::V1) .map_err(serde::de::Error::custom), - ForkName::Capella | ForkName::Eip4844 => serde_json::from_value(value) - .map(Self::V2) - .map_err(serde::de::Error::custom), + ForkName::Capella | ForkName::Eip4844 | ForkName::Eip6110 => { + serde_json::from_value(value) + .map(Self::V2) + .map_err(serde::de::Error::custom) + } ForkName::Base | ForkName::Altair => Err(serde::de::Error::custom(format!( "SsePayloadAttributes deserialization for {fork_name} not implemented" ))), diff --git a/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml b/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml index f7334b6187c..ecd9ad80cc8 100644 --- a/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml @@ -38,6 +38,10 @@ CAPELLA_FORK_EPOCH: 1 EIP4844_FORK_VERSION: 0x50484404 EIP4844_FORK_EPOCH: 5 +# EIP6110 +EIP6110_FORK_VERSION: 0x60484404 +EIP6110_FORK_EPOCH: 10 + # Time parameters # --------------------------------------------------------------- # 12 seconds diff --git a/common/eth2_network_config/built_in_network_configs/gnosis/config.yaml b/common/eth2_network_config/built_in_network_configs/gnosis/config.yaml index 6aa2c9590a5..0386babb800 100644 --- a/common/eth2_network_config/built_in_network_configs/gnosis/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/gnosis/config.yaml @@ -42,6 +42,9 @@ CAPELLA_FORK_EPOCH: 18446744073709551615 # Eip4844 EIP4844_FORK_VERSION: 0x04000064 EIP4844_FORK_EPOCH: 18446744073709551615 +# Eip6110 +EIP6110_FORK_VERSION: 0x05000064 +EIP6110_FORK_EPOCH: 18446744073709551615 # Sharding SHARDING_FORK_VERSION: 0x03000064 SHARDING_FORK_EPOCH: 18446744073709551615 diff --git a/common/eth2_network_config/built_in_network_configs/mainnet/config.yaml b/common/eth2_network_config/built_in_network_configs/mainnet/config.yaml index b5ce752b700..7fddf476f99 100644 --- a/common/eth2_network_config/built_in_network_configs/mainnet/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/mainnet/config.yaml @@ -42,6 +42,9 @@ CAPELLA_FORK_EPOCH: 194048 # April 12, 2023, 10:27:35pm UTC # Eip4844 EIP4844_FORK_VERSION: 0x04000000 EIP4844_FORK_EPOCH: 18446744073709551615 +# Eip6110 +EIP6110_FORK_VERSION: 0x05000000 +EIP6110_FORK_EPOCH: 18446744073709551615 # Sharding SHARDING_FORK_VERSION: 0x03000000 SHARDING_FORK_EPOCH: 18446744073709551615 diff --git a/common/eth2_network_config/built_in_network_configs/sepolia/config.yaml b/common/eth2_network_config/built_in_network_configs/sepolia/config.yaml index 4ba006ec945..95a2eaf0d28 100644 --- a/common/eth2_network_config/built_in_network_configs/sepolia/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/sepolia/config.yaml @@ -36,6 +36,10 @@ CAPELLA_FORK_EPOCH: 56832 EIP4844_FORK_VERSION: 0x03001020 EIP4844_FORK_EPOCH: 18446744073709551615 +# Eip6110 +EIP6110_FORK_VERSION: 0x04001020 +EIP6110_FORK_EPOCH: 18446744073709551615 + # Sharding SHARDING_FORK_VERSION: 0x04001020 SHARDING_FORK_EPOCH: 18446744073709551615 diff --git a/consensus/fork_choice/src/fork_choice.rs b/consensus/fork_choice/src/fork_choice.rs index d717c31aaf8..cf8407934c5 100644 --- a/consensus/fork_choice/src/fork_choice.rs +++ b/consensus/fork_choice/src/fork_choice.rs @@ -754,6 +754,7 @@ where // TODO(eip4844): Ensure that the final specification // does not substantially modify per epoch processing. BeaconBlockRef::Eip4844(_) + | BeaconBlockRef::Eip6110(_) | BeaconBlockRef::Capella(_) | BeaconBlockRef::Merge(_) | BeaconBlockRef::Altair(_) => { diff --git a/consensus/state_processing/src/common/slash_validator.rs b/consensus/state_processing/src/common/slash_validator.rs index 77cd1a32659..c53b9cbaacb 100644 --- a/consensus/state_processing/src/common/slash_validator.rs +++ b/consensus/state_processing/src/common/slash_validator.rs @@ -56,6 +56,9 @@ pub fn slash_validator( | BeaconState::Eip4844(_) => whistleblower_reward .safe_mul(PROPOSER_WEIGHT)? .safe_div(WEIGHT_DENOMINATOR)?, + BeaconState::Eip6110(_) => whistleblower_reward + .safe_mul(PROPOSER_WEIGHT)? + .safe_div(WEIGHT_DENOMINATOR)?, }; // Ensure the whistleblower index is in the validator registry. diff --git a/consensus/state_processing/src/genesis.rs b/consensus/state_processing/src/genesis.rs index 275b214c8f7..10b9577400b 100644 --- a/consensus/state_processing/src/genesis.rs +++ b/consensus/state_processing/src/genesis.rs @@ -68,7 +68,12 @@ pub fn initialize_beacon_state_from_eth1( if let ExecutionPayloadHeader::Eip4844(header) = header { *header_mut = header; } - } // TODO: Should a Eip6110 or upgrade_to_eip6110() be added? + } + ExecutionPayloadHeaderRefMut::Eip6110(header_mut) => { + if let ExecutionPayloadHeader::Eip6110(header) = header { + *header_mut = header; + } + } } } diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index adea2df1c59..49ecaf23c36 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -29,6 +29,7 @@ pub use verify_exit::verify_exit; pub mod altair; pub mod block_signature_verifier; pub mod eip4844; +pub mod eip6110; pub mod errors; mod is_valid_indexed_attestation; pub mod process_operations; @@ -412,6 +413,12 @@ pub fn process_execution_payload>( _ => return Err(BlockProcessingError::IncorrectStateType), } } + ExecutionPayloadHeaderRefMut::Eip6110(header_mut) => { + match payload.to_execution_payload_header() { + ExecutionPayloadHeader::Eip6110(header) => *header_mut = header, + _ => return Err(BlockProcessingError::IncorrectStateType), + } + } } Ok(()) @@ -558,7 +565,7 @@ pub fn process_withdrawals>( ) -> Result<(), BlockProcessingError> { match state { BeaconState::Merge(_) => Ok(()), - BeaconState::Capella(_) | BeaconState::Eip4844(_) => { + BeaconState::Capella(_) | BeaconState::Eip4844(_) | BeaconState::Eip6110(_) => { let expected_withdrawals = get_expected_withdrawals(state, spec)?; let expected_root = expected_withdrawals.tree_hash_root(); let withdrawals_root = payload.withdrawals_root()?; diff --git a/consensus/state_processing/src/per_block_processing/eip6110.rs b/consensus/state_processing/src/per_block_processing/eip6110.rs new file mode 100644 index 00000000000..3358e302a60 --- /dev/null +++ b/consensus/state_processing/src/per_block_processing/eip6110.rs @@ -0,0 +1,2 @@ +#[allow(clippy::module_inception)] +pub mod eip6110; diff --git a/consensus/state_processing/src/per_block_processing/eip6110/eip6110.rs b/consensus/state_processing/src/per_block_processing/eip6110/eip6110.rs new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/consensus/state_processing/src/per_block_processing/eip6110/eip6110.rs @@ -0,0 +1 @@ + diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 903ee56ec9d..bb9fc9bf5ac 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -273,7 +273,8 @@ pub fn process_attestations>( BeaconBlockBodyRef::Altair(_) | BeaconBlockBodyRef::Merge(_) | BeaconBlockBodyRef::Capella(_) - | BeaconBlockBodyRef::Eip4844(_) => { + | BeaconBlockBodyRef::Eip4844(_) + | BeaconBlockBodyRef::Eip6110(_) => { altair::process_attestations( state, block_body.attestations(), diff --git a/consensus/state_processing/src/per_epoch_processing.rs b/consensus/state_processing/src/per_epoch_processing.rs index 996e39c27fb..8653b3541cb 100644 --- a/consensus/state_processing/src/per_epoch_processing.rs +++ b/consensus/state_processing/src/per_epoch_processing.rs @@ -14,6 +14,7 @@ pub mod altair; pub mod base; pub mod capella; pub mod effective_balance_updates; +pub mod eip4844; pub mod epoch_processing_summary; pub mod errors; pub mod historical_roots_update; @@ -41,6 +42,7 @@ pub fn process_epoch( BeaconState::Base(_) => base::process_epoch(state, spec), BeaconState::Altair(_) | BeaconState::Merge(_) => altair::process_epoch(state, spec), BeaconState::Capella(_) | BeaconState::Eip4844(_) => capella::process_epoch(state, spec), + BeaconState::Eip4844(_) | BeaconState::Eip6110(_) => capella::process_epoch(state, spec), } } diff --git a/consensus/state_processing/src/per_epoch_processing/eip4844.rs b/consensus/state_processing/src/per_epoch_processing/eip4844.rs new file mode 100644 index 00000000000..5af3758e5b6 --- /dev/null +++ b/consensus/state_processing/src/per_epoch_processing/eip4844.rs @@ -0,0 +1,75 @@ +use super::altair::inactivity_updates::process_inactivity_updates; +use super::altair::justification_and_finalization::process_justification_and_finalization; +use super::altair::participation_cache::ParticipationCache; +use super::altair::participation_flag_updates::process_participation_flag_updates; +use super::altair::rewards_and_penalties::process_rewards_and_penalties; +use super::altair::sync_committee_updates::process_sync_committee_updates; +use super::capella::process_historical_summaries_update; +use super::{process_registry_updates, process_slashings, EpochProcessingSummary, Error}; +use crate::per_epoch_processing::{ + effective_balance_updates::process_effective_balance_updates, + resets::{process_eth1_data_reset, process_randao_mixes_reset, process_slashings_reset}, +}; +use types::{BeaconState, ChainSpec, EthSpec, RelativeEpoch}; + +pub fn process_epoch( + state: &mut BeaconState, + spec: &ChainSpec, +) -> Result, Error> { + // Ensure the committee caches are built. + state.build_committee_cache(RelativeEpoch::Previous, spec)?; + state.build_committee_cache(RelativeEpoch::Current, spec)?; + state.build_committee_cache(RelativeEpoch::Next, spec)?; + + // Pre-compute participating indices and total balances. + let participation_cache = ParticipationCache::new(state, spec)?; + let sync_committee = state.current_sync_committee()?.clone(); + + // Justification and finalization. + let justification_and_finalization_state = + process_justification_and_finalization(state, &participation_cache)?; + justification_and_finalization_state.apply_changes_to_state(state); + + process_inactivity_updates(state, &participation_cache, spec)?; + + // Rewards and Penalties. + process_rewards_and_penalties(state, &participation_cache, spec)?; + + // Registry Updates. + process_registry_updates(state, spec)?; + + // Slashings. + process_slashings( + state, + participation_cache.current_epoch_total_active_balance(), + spec, + )?; + + // Reset eth1 data votes. + process_eth1_data_reset(state)?; + + // Update effective balances with hysteresis (lag). + process_effective_balance_updates(state, spec)?; + + // Reset slashings + process_slashings_reset(state)?; + + // Set randao mix + process_randao_mixes_reset(state)?; + + // Set historical summaries accumulator + process_historical_summaries_update(state)?; + + // Rotate current/previous epoch participation + process_participation_flag_updates(state)?; + + process_sync_committee_updates(state, spec)?; + + // Rotate the epoch caches to suit the epoch transition. + state.advance_caches(spec)?; + + Ok(EpochProcessingSummary::Altair { + participation_cache, + sync_committee, + }) +} diff --git a/consensus/state_processing/src/per_slot_processing.rs b/consensus/state_processing/src/per_slot_processing.rs index 8d2600bb41e..7229e2a906b 100644 --- a/consensus/state_processing/src/per_slot_processing.rs +++ b/consensus/state_processing/src/per_slot_processing.rs @@ -1,5 +1,6 @@ use crate::upgrade::{ upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_eip4844, + upgrade_to_eip6110, }; use crate::{per_epoch_processing::EpochProcessingSummary, *}; use safe_arith::{ArithError, SafeArith}; @@ -65,6 +66,10 @@ pub fn per_slot_processing( if spec.eip4844_fork_epoch == Some(state.current_epoch()) { upgrade_to_eip4844(state, spec)?; } + // Eip6110 + if spec.eip6110_fork_epoch == Some(state.current_epoch()) { + upgrade_to_eip6110(state, spec)?; + } } Ok(summary) diff --git a/consensus/state_processing/src/upgrade.rs b/consensus/state_processing/src/upgrade.rs index 01b65710564..5e7f4a9e5cf 100644 --- a/consensus/state_processing/src/upgrade.rs +++ b/consensus/state_processing/src/upgrade.rs @@ -1,9 +1,11 @@ pub mod altair; pub mod capella; pub mod eip4844; +pub mod eip6110; pub mod merge; pub use altair::upgrade_to_altair; pub use capella::upgrade_to_capella; pub use eip4844::upgrade_to_eip4844; +pub use eip6110::upgrade_to_eip6110; pub use merge::upgrade_to_bellatrix; diff --git a/consensus/state_processing/src/upgrade/capella.rs b/consensus/state_processing/src/upgrade/capella.rs index babea82cc2e..3b933fac37a 100644 --- a/consensus/state_processing/src/upgrade/capella.rs +++ b/consensus/state_processing/src/upgrade/capella.rs @@ -66,8 +66,6 @@ pub fn upgrade_to_capella( pubkey_cache: mem::take(&mut pre.pubkey_cache), exit_cache: mem::take(&mut pre.exit_cache), tree_hash_cache: mem::take(&mut pre.tree_hash_cache), - // EIP-6110 - deposit_receipts_start_index: 0, }); *pre_state = post; diff --git a/consensus/state_processing/src/upgrade/eip4844.rs b/consensus/state_processing/src/upgrade/eip4844.rs index c6e8c15c185..4f6ff9d1943 100644 --- a/consensus/state_processing/src/upgrade/eip4844.rs +++ b/consensus/state_processing/src/upgrade/eip4844.rs @@ -67,7 +67,6 @@ pub fn upgrade_to_eip4844( pubkey_cache: mem::take(&mut pre.pubkey_cache), exit_cache: mem::take(&mut pre.exit_cache), tree_hash_cache: mem::take(&mut pre.tree_hash_cache), - deposit_receipts_start_index: pre.deposit_receipts_start_index, }); *pre_state = post; diff --git a/consensus/state_processing/src/upgrade/eip6110.rs b/consensus/state_processing/src/upgrade/eip6110.rs new file mode 100644 index 00000000000..0afe5f0e118 --- /dev/null +++ b/consensus/state_processing/src/upgrade/eip6110.rs @@ -0,0 +1,72 @@ +use std::mem; +use types::{BeaconState, BeaconStateEip6110, BeaconStateError as Error, ChainSpec, EthSpec, Fork}; + +/// Transform a `Eip4844` state into an `Eip6110` state. +pub fn upgrade_to_eip6110( + pre_state: &mut BeaconState, + spec: &ChainSpec, +) -> Result<(), Error> { + let epoch = pre_state.current_epoch(); + let pre = pre_state.as_eip4844_mut()?; + + let previous_fork_version = pre.fork.current_version; + + let post = BeaconState::Eip6110(BeaconStateEip6110 { + // Versioning + genesis_time: pre.genesis_time, + genesis_validators_root: pre.genesis_validators_root, + slot: pre.slot, + fork: Fork { + previous_version: previous_fork_version, + current_version: spec.eip6110_fork_version, + epoch, + }, + // History + latest_block_header: pre.latest_block_header.clone(), + block_roots: pre.block_roots.clone(), + state_roots: pre.state_roots.clone(), + historical_roots: mem::take(&mut pre.historical_roots), + // Eth1 + eth1_data: pre.eth1_data.clone(), + eth1_data_votes: mem::take(&mut pre.eth1_data_votes), + eth1_deposit_index: pre.eth1_deposit_index, + // Registry + validators: mem::take(&mut pre.validators), + balances: mem::take(&mut pre.balances), + // Randomness + randao_mixes: pre.randao_mixes.clone(), + // Slashings + slashings: pre.slashings.clone(), + // Participation + previous_epoch_participation: mem::take(&mut pre.previous_epoch_participation), + current_epoch_participation: mem::take(&mut pre.current_epoch_participation), + // Finality + justification_bits: pre.justification_bits.clone(), + previous_justified_checkpoint: pre.previous_justified_checkpoint, + current_justified_checkpoint: pre.current_justified_checkpoint, + finalized_checkpoint: pre.finalized_checkpoint, + // Inactivity + inactivity_scores: mem::take(&mut pre.inactivity_scores), + // Sync committees + current_sync_committee: pre.current_sync_committee.clone(), + next_sync_committee: pre.next_sync_committee.clone(), + // Execution + latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_eip6110(), + // Capella + next_withdrawal_index: pre.next_withdrawal_index, + next_withdrawal_validator_index: pre.next_withdrawal_validator_index, + historical_summaries: pre.historical_summaries.clone(), + // Caches + total_active_balance: pre.total_active_balance, + committee_caches: mem::take(&mut pre.committee_caches), + pubkey_cache: mem::take(&mut pre.pubkey_cache), + exit_cache: mem::take(&mut pre.exit_cache), + tree_hash_cache: mem::take(&mut pre.tree_hash_cache), + // Eip6110 + deposit_receipts_start_index: 0, + }); + + *pre_state = post; + + Ok(()) +} diff --git a/consensus/types/src/beacon_block.rs b/consensus/types/src/beacon_block.rs index 0f26cd0e5e7..7d2a1f19888 100644 --- a/consensus/types/src/beacon_block.rs +++ b/consensus/types/src/beacon_block.rs @@ -1,6 +1,6 @@ use crate::beacon_block_body::{ - BeaconBlockBodyAltair, BeaconBlockBodyBase, BeaconBlockBodyEip4844, BeaconBlockBodyMerge, - BeaconBlockBodyRef, BeaconBlockBodyRefMut, + BeaconBlockBodyAltair, BeaconBlockBodyBase, BeaconBlockBodyEip4844, BeaconBlockBodyEip6110, + BeaconBlockBodyMerge, BeaconBlockBodyRef, BeaconBlockBodyRefMut, }; use crate::test_utils::TestRandom; use crate::*; @@ -17,7 +17,7 @@ use tree_hash_derive::TreeHash; /// A block of the `BeaconChain`. #[superstruct( - variants(Base, Altair, Merge, Capella, Eip4844), + variants(Base, Altair, Merge, Capella, Eip4844, Eip6110), variant_attributes( derive( Debug, @@ -74,6 +74,8 @@ pub struct BeaconBlock = FullPayload pub body: BeaconBlockBodyCapella, #[superstruct(only(Eip4844), partial_getter(rename = "body_eip4844"))] pub body: BeaconBlockBodyEip4844, + #[superstruct(only(Eip6110), partial_getter(rename = "body_eip6110"))] + pub body: BeaconBlockBodyEip6110, } pub type BlindedBeaconBlock = BeaconBlock>; @@ -132,6 +134,7 @@ impl> BeaconBlock { .or_else(|_| BeaconBlockMerge::from_ssz_bytes(bytes).map(BeaconBlock::Merge)) .or_else(|_| BeaconBlockAltair::from_ssz_bytes(bytes).map(BeaconBlock::Altair)) .or_else(|_| BeaconBlockBase::from_ssz_bytes(bytes).map(BeaconBlock::Base)) + .or_else(|_| BeaconBlockEip6110::from_ssz_bytes(bytes).map(BeaconBlock::Eip6110)) } /// Convenience accessor for the `body` as a `BeaconBlockBodyRef`. @@ -207,6 +210,7 @@ impl<'a, T: EthSpec, Payload: AbstractExecPayload> BeaconBlockRef<'a, T, Payl BeaconBlockRef::Merge { .. } => ForkName::Merge, BeaconBlockRef::Capella { .. } => ForkName::Capella, BeaconBlockRef::Eip4844 { .. } => ForkName::Eip4844, + BeaconBlockRef::Eip6110 { .. } => ForkName::Eip6110, }; if fork_at_slot == object_fork { @@ -560,6 +564,36 @@ impl> EmptyBlock for BeaconBlockCape } } +impl> EmptyBlock for BeaconBlockEip6110 { + /// Returns an empty Eip6110 block to be used during genesis. + fn empty(spec: &ChainSpec) -> Self { + BeaconBlockEip6110 { + slot: spec.genesis_slot, + proposer_index: 0, + parent_root: Hash256::zero(), + state_root: Hash256::zero(), + body: BeaconBlockBodyEip6110 { + randao_reveal: Signature::empty(), + eth1_data: Eth1Data { + deposit_root: Hash256::zero(), + block_hash: Hash256::zero(), + deposit_count: 0, + }, + graffiti: Graffiti::default(), + proposer_slashings: VariableList::empty(), + attester_slashings: VariableList::empty(), + attestations: VariableList::empty(), + deposits: VariableList::empty(), + voluntary_exits: VariableList::empty(), + sync_aggregate: SyncAggregate::empty(), + execution_payload: Payload::Eip6110::default(), + bls_to_execution_changes: VariableList::empty(), + blob_kzg_commitments: VariableList::empty(), + }, + } + } +} + impl> EmptyBlock for BeaconBlockEip4844 { /// Returns an empty Eip4844 block to be used during genesis. fn empty(spec: &ChainSpec) -> Self { @@ -670,6 +704,7 @@ impl_from!(BeaconBlockAltair, >, >, |body impl_from!(BeaconBlockMerge, >, >, |body: BeaconBlockBodyMerge<_, _>| body.into()); impl_from!(BeaconBlockCapella, >, >, |body: BeaconBlockBodyCapella<_, _>| body.into()); impl_from!(BeaconBlockEip4844, >, >, |body: BeaconBlockBodyEip4844<_, _>| body.into()); +impl_from!(BeaconBlockEip6110, >, >, |body: BeaconBlockBodyEip6110<_, _>| body.into()); // We can clone blocks with payloads to blocks without payloads, without cloning the payload. macro_rules! impl_clone_as_blinded { @@ -702,6 +737,7 @@ impl_clone_as_blinded!(BeaconBlockAltair, >, >, >); impl_clone_as_blinded!(BeaconBlockCapella, >, >); impl_clone_as_blinded!(BeaconBlockEip4844, >, >); +impl_clone_as_blinded!(BeaconBlockEip6110, >, >); // A reference to a full beacon block can be cloned into a blinded beacon block, without cloning the // execution payload. @@ -853,10 +889,13 @@ mod tests { let capella_slot = capella_epoch.start_slot(E::slots_per_epoch()); let eip4844_epoch = capella_epoch + 1; let eip4844_slot = eip4844_epoch.start_slot(E::slots_per_epoch()); + let eip6110_epoch = eip4844_epoch + 1; + let eip6110_slot = eip6110_epoch.start_slot(E::slots_per_epoch()); spec.altair_fork_epoch = Some(altair_epoch); spec.capella_fork_epoch = Some(capella_epoch); spec.eip4844_fork_epoch = Some(eip4844_epoch); + spec.eip6110_fork_epoch = Some(eip6110_epoch); // BeaconBlockBase { @@ -945,5 +984,27 @@ mod tests { BeaconBlock::from_ssz_bytes(&bad_block.as_ssz_bytes(), &spec) .expect_err("bad eip4844 block cannot be decoded"); } + + // BeaconBlockEip6110 + { + let good_block = BeaconBlock::Eip6110(BeaconBlockEip6110 { + slot: eip6110_slot, + ..<_>::random_for_test(rng) + }); + // It's invalid to have an Eip4844 block with a epoch lower than the fork epoch. + let bad_block = { + let mut bad = good_block.clone(); + *bad.slot_mut() = eip4844_slot; + bad + }; + + assert_eq!( + BeaconBlock::from_ssz_bytes(&good_block.as_ssz_bytes(), &spec) + .expect("good eip6110 block can be decoded"), + good_block + ); + BeaconBlock::from_ssz_bytes(&bad_block.as_ssz_bytes(), &spec) + .expect_err("bad eip6110 block cannot be decoded"); + } } } diff --git a/consensus/types/src/beacon_block_body.rs b/consensus/types/src/beacon_block_body.rs index c7173965224..0506763a925 100644 --- a/consensus/types/src/beacon_block_body.rs +++ b/consensus/types/src/beacon_block_body.rs @@ -1,3 +1,4 @@ +use crate::payload::{BlindedPayloadEip6110, FullPayloadEip6110}; use crate::*; use crate::{blobs_sidecar::KzgCommitments, test_utils::TestRandom}; use derivative::Derivative; @@ -13,7 +14,7 @@ use tree_hash_derive::TreeHash; /// /// This *superstruct* abstracts over the hard-fork. #[superstruct( - variants(Base, Altair, Merge, Capella, Eip4844), + variants(Base, Altair, Merge, Capella, Eip4844, Eip6110), variant_attributes( derive( Debug, @@ -51,7 +52,7 @@ pub struct BeaconBlockBody = FullPay pub attestations: VariableList, T::MaxAttestations>, pub deposits: VariableList, pub voluntary_exits: VariableList, - #[superstruct(only(Altair, Merge, Capella, Eip4844))] + #[superstruct(only(Altair, Merge, Capella, Eip4844, Eip6110))] pub sync_aggregate: SyncAggregate, // We flatten the execution payload so that serde can use the name of the inner type, // either `execution_payload` for full payloads, or `execution_payload_header` for blinded @@ -65,10 +66,13 @@ pub struct BeaconBlockBody = FullPay #[superstruct(only(Eip4844), partial_getter(rename = "execution_payload_eip4844"))] #[serde(flatten)] pub execution_payload: Payload::Eip4844, - #[superstruct(only(Capella, Eip4844))] + #[superstruct(only(Eip6110), partial_getter(rename = "execution_payload_eip6110"))] + #[serde(flatten)] + pub execution_payload: Payload::Eip6110, + #[superstruct(only(Capella, Eip4844, Eip6110))] pub bls_to_execution_changes: VariableList, - #[superstruct(only(Eip4844))] + #[superstruct(only(Eip4844, Eip6110))] pub blob_kzg_commitments: KzgCommitments, #[superstruct(only(Base, Altair))] #[ssz(skip_serializing, skip_deserializing)] @@ -91,6 +95,7 @@ impl<'a, T: EthSpec, Payload: AbstractExecPayload> BeaconBlockBodyRef<'a, T, Self::Merge(body) => Ok(Payload::Ref::from(&body.execution_payload)), Self::Capella(body) => Ok(Payload::Ref::from(&body.execution_payload)), Self::Eip4844(body) => Ok(Payload::Ref::from(&body.execution_payload)), + Self::Eip6110(body) => Ok(Payload::Ref::from(&body.execution_payload)), } } } @@ -104,6 +109,7 @@ impl<'a, T: EthSpec> BeaconBlockBodyRef<'a, T> { BeaconBlockBodyRef::Merge { .. } => ForkName::Merge, BeaconBlockBodyRef::Capella { .. } => ForkName::Capella, BeaconBlockBodyRef::Eip4844 { .. } => ForkName::Eip4844, + BeaconBlockBodyRef::Eip6110 { .. } => ForkName::Eip6110, } } } @@ -372,6 +378,50 @@ impl From>> } } +impl From>> + for ( + BeaconBlockBodyEip6110>, + Option>, + ) +{ + fn from(body: BeaconBlockBodyEip6110>) -> Self { + let BeaconBlockBodyEip6110 { + randao_reveal, + eth1_data, + graffiti, + proposer_slashings, + attester_slashings, + attestations, + deposits, + voluntary_exits, + sync_aggregate, + execution_payload: FullPayloadEip6110 { execution_payload }, + bls_to_execution_changes, + blob_kzg_commitments, + } = body; + + ( + BeaconBlockBodyEip6110 { + randao_reveal, + eth1_data, + graffiti, + proposer_slashings, + attester_slashings, + attestations, + deposits, + voluntary_exits, + sync_aggregate, + execution_payload: BlindedPayloadEip6110 { + execution_payload_header: From::from(&execution_payload), + }, + bls_to_execution_changes, + blob_kzg_commitments, + }, + Some(execution_payload), + ) + } +} + // We can clone a full block into a blinded block, without cloning the payload. impl BeaconBlockBodyBase> { pub fn clone_as_blinded(&self) -> BeaconBlockBodyBase> { @@ -489,6 +539,42 @@ impl BeaconBlockBodyEip4844> { } } +impl BeaconBlockBodyEip6110> { + pub fn clone_as_blinded(&self) -> BeaconBlockBodyEip6110> { + let BeaconBlockBodyEip6110 { + randao_reveal, + eth1_data, + graffiti, + proposer_slashings, + attester_slashings, + attestations, + deposits, + voluntary_exits, + sync_aggregate, + execution_payload: FullPayloadEip6110 { execution_payload }, + bls_to_execution_changes, + blob_kzg_commitments, + } = self; + + BeaconBlockBodyEip6110 { + randao_reveal: randao_reveal.clone(), + eth1_data: eth1_data.clone(), + graffiti: *graffiti, + proposer_slashings: proposer_slashings.clone(), + attester_slashings: attester_slashings.clone(), + attestations: attestations.clone(), + deposits: deposits.clone(), + voluntary_exits: voluntary_exits.clone(), + sync_aggregate: sync_aggregate.clone(), + execution_payload: BlindedPayloadEip6110 { + execution_payload_header: execution_payload.into(), + }, + bls_to_execution_changes: bls_to_execution_changes.clone(), + blob_kzg_commitments: blob_kzg_commitments.clone(), + } + } +} + impl From>> for ( BeaconBlockBody>, diff --git a/consensus/types/src/beacon_state.rs b/consensus/types/src/beacon_state.rs index 4f3a68e3b4f..7f7311b81e2 100644 --- a/consensus/types/src/beacon_state.rs +++ b/consensus/types/src/beacon_state.rs @@ -1,5 +1,6 @@ use self::committee_cache::get_active_validator_indices; use self::exit_cache::ExitCache; +use crate::execution_payload_header::ExecutionPayloadHeaderEip6110; use crate::test_utils::TestRandom; use crate::*; use compare_fields::CompareFields; @@ -176,7 +177,7 @@ impl From for Hash256 { /// The state of the `BeaconChain` at some slot. #[superstruct( - variants(Base, Altair, Merge, Capella, Eip4844), + variants(Base, Altair, Merge, Capella, Eip4844, Eip6110), variant_attributes( derive( Derivative, @@ -256,9 +257,9 @@ where pub current_epoch_attestations: VariableList, T::MaxPendingAttestations>, // Participation (Altair and later) - #[superstruct(only(Altair, Merge, Capella, Eip4844))] + #[superstruct(only(Altair, Merge, Capella, Eip4844, Eip6110))] pub previous_epoch_participation: VariableList, - #[superstruct(only(Altair, Merge, Capella, Eip4844))] + #[superstruct(only(Altair, Merge, Capella, Eip4844, Eip6110))] pub current_epoch_participation: VariableList, // Finality @@ -273,13 +274,13 @@ where // Inactivity #[serde(with = "ssz_types::serde_utils::quoted_u64_var_list")] - #[superstruct(only(Altair, Merge, Capella, Eip4844))] + #[superstruct(only(Altair, Merge, Capella, Eip4844, Eip6110))] pub inactivity_scores: VariableList, // Light-client sync committees - #[superstruct(only(Altair, Merge, Capella, Eip4844))] + #[superstruct(only(Altair, Merge, Capella, Eip4844, Eip6110))] pub current_sync_committee: Arc>, - #[superstruct(only(Altair, Merge, Capella, Eip4844))] + #[superstruct(only(Altair, Merge, Capella, Eip4844, Eip6110))] pub next_sync_committee: Arc>, // Execution @@ -298,18 +299,23 @@ where partial_getter(rename = "latest_execution_payload_header_eip4844") )] pub latest_execution_payload_header: ExecutionPayloadHeaderEip4844, + #[superstruct( + only(Eip6110), + partial_getter(rename = "latest_execution_payload_header_eip6110") + )] + pub latest_execution_payload_header: ExecutionPayloadHeaderEip6110, // Capella - #[superstruct(only(Capella, Eip4844), partial_getter(copy))] + #[superstruct(only(Capella, Eip4844, Eip6110), partial_getter(copy))] #[serde(with = "eth2_serde_utils::quoted_u64")] pub next_withdrawal_index: u64, - #[superstruct(only(Capella, Eip4844), partial_getter(copy))] + #[superstruct(only(Capella, Eip4844, Eip6110), partial_getter(copy))] #[serde(with = "eth2_serde_utils::quoted_u64")] pub next_withdrawal_validator_index: u64, // Deep history valid from Capella onwards. - #[superstruct(only(Capella, Eip4844))] + #[superstruct(only(Capella, Eip4844, Eip6110))] pub historical_summaries: VariableList, - #[superstruct(only(Capella, Eip4844), partial_getter(copy))] + #[superstruct(only(Eip6110), partial_getter(copy))] #[serde(with = "eth2_serde_utils::quoted_u64")] pub deposit_receipts_start_index: u64, @@ -424,6 +430,7 @@ impl BeaconState { BeaconState::Merge { .. } => ForkName::Merge, BeaconState::Capella { .. } => ForkName::Capella, BeaconState::Eip4844 { .. } => ForkName::Eip4844, + BeaconState::Eip6110 { .. } => ForkName::Eip6110, }; if fork_at_slot == object_fork { @@ -726,6 +733,9 @@ impl BeaconState { BeaconState::Eip4844(state) => Ok(ExecutionPayloadHeaderRef::Eip4844( &state.latest_execution_payload_header, )), + BeaconState::Eip6110(state) => Ok(ExecutionPayloadHeaderRef::Eip6110( + &state.latest_execution_payload_header, + )), } } @@ -743,6 +753,9 @@ impl BeaconState { BeaconState::Eip4844(state) => Ok(ExecutionPayloadHeaderRefMut::Eip4844( &mut state.latest_execution_payload_header, )), + BeaconState::Eip6110(state) => Ok(ExecutionPayloadHeaderRefMut::Eip6110( + &mut state.latest_execution_payload_header, + )), } } @@ -1172,6 +1185,7 @@ impl BeaconState { BeaconState::Merge(state) => (&mut state.validators, &mut state.balances), BeaconState::Capella(state) => (&mut state.validators, &mut state.balances), BeaconState::Eip4844(state) => (&mut state.validators, &mut state.balances), + BeaconState::Eip6110(state) => (&mut state.validators, &mut state.balances), } } @@ -1370,6 +1384,7 @@ impl BeaconState { BeaconState::Merge(state) => Ok(&mut state.current_epoch_participation), BeaconState::Capella(state) => Ok(&mut state.current_epoch_participation), BeaconState::Eip4844(state) => Ok(&mut state.current_epoch_participation), + BeaconState::Eip6110(state) => Ok(&mut state.current_epoch_participation), } } else if epoch == self.previous_epoch() { match self { @@ -1378,6 +1393,7 @@ impl BeaconState { BeaconState::Merge(state) => Ok(&mut state.previous_epoch_participation), BeaconState::Capella(state) => Ok(&mut state.previous_epoch_participation), BeaconState::Eip4844(state) => Ok(&mut state.previous_epoch_participation), + BeaconState::Eip6110(state) => Ok(&mut state.previous_epoch_participation), } } else { Err(BeaconStateError::EpochOutOfBounds) @@ -1684,6 +1700,7 @@ impl BeaconState { BeaconState::Merge(inner) => BeaconState::Merge(inner.clone()), BeaconState::Capella(inner) => BeaconState::Capella(inner.clone()), BeaconState::Eip4844(inner) => BeaconState::Eip4844(inner.clone()), + BeaconState::Eip6110(inner) => BeaconState::Eip6110(inner.clone()), }; if config.committee_caches { *res.committee_caches_mut() = self.committee_caches().clone(); @@ -1853,6 +1870,7 @@ impl CompareFields for BeaconState { (BeaconState::Merge(x), BeaconState::Merge(y)) => x.compare_fields(y), (BeaconState::Capella(x), BeaconState::Capella(y)) => x.compare_fields(y), (BeaconState::Eip4844(x), BeaconState::Eip4844(y)) => x.compare_fields(y), + (BeaconState::Eip6110(x), BeaconState::Eip6110(y)) => x.compare_fields(y), _ => panic!("compare_fields: mismatched state variants",), } } diff --git a/consensus/types/src/chain_spec.rs b/consensus/types/src/chain_spec.rs index 806632a6021..c7cc38648b0 100644 --- a/consensus/types/src/chain_spec.rs +++ b/consensus/types/src/chain_spec.rs @@ -261,15 +261,18 @@ impl ChainSpec { /// Returns the name of the fork which is active at `epoch`. pub fn fork_name_at_epoch(&self, epoch: Epoch) -> ForkName { - match self.eip4844_fork_epoch { - Some(fork_epoch) if epoch >= fork_epoch => ForkName::Eip4844, - _ => match self.capella_fork_epoch { - Some(fork_epoch) if epoch >= fork_epoch => ForkName::Capella, - _ => match self.bellatrix_fork_epoch { - Some(fork_epoch) if epoch >= fork_epoch => ForkName::Merge, - _ => match self.altair_fork_epoch { - Some(fork_epoch) if epoch >= fork_epoch => ForkName::Altair, - _ => ForkName::Base, + match self.eip6110_fork_epoch { + Some(fork_epoch) if epoch >= fork_epoch => ForkName::Eip6110, + _ => match self.eip4844_fork_epoch { + Some(fork_epoch) if epoch >= fork_epoch => ForkName::Eip4844, + _ => match self.capella_fork_epoch { + Some(fork_epoch) if epoch >= fork_epoch => ForkName::Capella, + _ => match self.bellatrix_fork_epoch { + Some(fork_epoch) if epoch >= fork_epoch => ForkName::Merge, + _ => match self.altair_fork_epoch { + Some(fork_epoch) if epoch >= fork_epoch => ForkName::Altair, + _ => ForkName::Base, + }, }, }, }, @@ -284,6 +287,7 @@ impl ChainSpec { ForkName::Merge => self.bellatrix_fork_version, ForkName::Capella => self.capella_fork_version, ForkName::Eip4844 => self.eip4844_fork_version, + ForkName::Eip6110 => self.eip6110_fork_version, } } @@ -295,6 +299,7 @@ impl ChainSpec { ForkName::Merge => self.bellatrix_fork_epoch, ForkName::Capella => self.capella_fork_epoch, ForkName::Eip4844 => self.eip4844_fork_epoch, + ForkName::Eip6110 => self.eip6110_fork_epoch, } } @@ -306,6 +311,7 @@ impl ChainSpec { BeaconState::Merge(_) => self.inactivity_penalty_quotient_bellatrix, BeaconState::Capella(_) => self.inactivity_penalty_quotient_bellatrix, BeaconState::Eip4844(_) => self.inactivity_penalty_quotient_bellatrix, + BeaconState::Eip6110(_) => self.inactivity_penalty_quotient_bellatrix, } } @@ -320,6 +326,7 @@ impl ChainSpec { BeaconState::Merge(_) => self.proportional_slashing_multiplier_bellatrix, BeaconState::Capella(_) => self.proportional_slashing_multiplier_bellatrix, BeaconState::Eip4844(_) => self.proportional_slashing_multiplier_bellatrix, + BeaconState::Eip6110(_) => self.proportional_slashing_multiplier_bellatrix, } } @@ -334,6 +341,7 @@ impl ChainSpec { BeaconState::Merge(_) => self.min_slashing_penalty_quotient_bellatrix, BeaconState::Capella(_) => self.min_slashing_penalty_quotient_bellatrix, BeaconState::Eip4844(_) => self.min_slashing_penalty_quotient_bellatrix, + BeaconState::Eip6110(_) => self.min_slashing_penalty_quotient_bellatrix, } } @@ -724,6 +732,9 @@ impl ChainSpec { // Eip4844 eip4844_fork_version: [0x04, 0x00, 0x00, 0x01], eip4844_fork_epoch: None, + // Eip6110 + eip6110_fork_version: [0x05, 0x00, 0x00, 0x01], + eip6110_fork_epoch: None, // Other network_id: 2, // lighthouse testnet network id deposit_chain_id: 5, @@ -996,6 +1007,14 @@ pub struct Config { #[serde(deserialize_with = "deserialize_fork_epoch")] pub eip4844_fork_epoch: Option>, + #[serde(default = "default_eip6110_fork_version")] + #[serde(with = "eth2_serde_utils::bytes_4_hex")] + eip6110_fork_version: [u8; 4], + #[serde(default)] + #[serde(serialize_with = "serialize_fork_epoch")] + #[serde(deserialize_with = "deserialize_fork_epoch")] + pub eip6110_fork_epoch: Option>, + #[serde(with = "eth2_serde_utils::quoted_u64")] seconds_per_slot: u64, #[serde(with = "eth2_serde_utils::quoted_u64")] @@ -1043,6 +1062,11 @@ fn default_eip4844_fork_version() -> [u8; 4] { [0xff, 0xff, 0xff, 0xff] } +fn default_eip6110_fork_version() -> [u8; 4] { + // This value shouldn't be used. + [0xff, 0xff, 0xff, 0xff] +} + /// Placeholder value: 2^256-2^10 (115792089237316195423570985008687907853269984665640564039457584007913129638912). /// /// Taken from https://github.com/ethereum/consensus-specs/blob/d5e4828aecafaf1c57ef67a5f23c4ae7b08c5137/configs/mainnet.yaml#L15-L16 @@ -1147,6 +1171,10 @@ impl Config { eip4844_fork_epoch: spec .eip4844_fork_epoch .map(|epoch| MaybeQuoted { value: epoch }), + eip6110_fork_version: spec.eip6110_fork_version, + eip6110_fork_epoch: spec + .eip6110_fork_epoch + .map(|epoch| MaybeQuoted { value: epoch }), seconds_per_slot: spec.seconds_per_slot, seconds_per_eth1_block: spec.seconds_per_eth1_block, @@ -1196,6 +1224,8 @@ impl Config { capella_fork_version, eip4844_fork_epoch, eip4844_fork_version, + eip6110_fork_epoch, + eip6110_fork_version, seconds_per_slot, seconds_per_eth1_block, min_validator_withdrawability_delay, @@ -1230,6 +1260,8 @@ impl Config { capella_fork_version, eip4844_fork_epoch: eip4844_fork_epoch.map(|q| q.value), eip4844_fork_version, + eip6110_fork_epoch: eip6110_fork_epoch.map(|q| q.value), + eip6110_fork_version, seconds_per_slot, seconds_per_eth1_block, min_validator_withdrawability_delay, diff --git a/consensus/types/src/eip6110.rs b/consensus/types/src/eip6110.rs index 9b375b2aa08..230db75badb 100644 --- a/consensus/types/src/eip6110.rs +++ b/consensus/types/src/eip6110.rs @@ -8,7 +8,7 @@ use tree_hash_derive::TreeHash; #[derive( arbitrary::Arbitrary, Debug, - PartialEq, + // PartialEq, // Eq, Hash, Clone, @@ -29,6 +29,18 @@ pub struct DepositReceipt { pub index: u64, } +// Manually implement the Eq trait for DepositReceipt +impl Eq for DepositReceipt {} + +impl PartialEq for DepositReceipt { + fn eq(&self, other: &DepositReceipt) -> bool { + self.pubkey == other.pubkey + && self.withdrawal_credentials == other.withdrawal_credentials + && self.amount == other.amount + && self.index == other.index + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/consensus/types/src/eth_spec.rs b/consensus/types/src/eth_spec.rs index 66316a699d0..2584d03336a 100644 --- a/consensus/types/src/eth_spec.rs +++ b/consensus/types/src/eth_spec.rs @@ -252,6 +252,11 @@ pub trait EthSpec: Self::MaxWithdrawalsPerPayload::to_usize() } + /// Returns the `MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD` constant for this specification. + fn max_deposit_receipts_per_payload() -> usize { + Self::MaxDepositReceiptsPerPayload::to_usize() + } + /// Returns the `MAX_BLOBS_PER_BLOCK` constant for this specification. fn max_blobs_per_block() -> usize { Self::MaxBlobsPerBlock::to_usize() diff --git a/consensus/types/src/execution_payload.rs b/consensus/types/src/execution_payload.rs index 2e02326de4f..42d3f43839f 100644 --- a/consensus/types/src/execution_payload.rs +++ b/consensus/types/src/execution_payload.rs @@ -18,7 +18,7 @@ pub type DepositReceipts = VariableList::MaxDepositReceiptsPerPayload>; #[superstruct( - variants(Merge, Capella, Eip4844), + variants(Merge, Capella, Eip4844, Eip6110), variant_attributes( derive( Default, @@ -80,7 +80,7 @@ pub struct ExecutionPayload { #[serde(with = "eth2_serde_utils::quoted_u256")] #[superstruct(getter(copy))] pub base_fee_per_gas: Uint256, - #[superstruct(only(Eip4844))] + #[superstruct(only(Eip4844, Eip6110))] #[serde(with = "eth2_serde_utils::quoted_u256")] #[superstruct(getter(copy))] pub excess_data_gas: Uint256, @@ -88,9 +88,9 @@ pub struct ExecutionPayload { pub block_hash: ExecutionBlockHash, #[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")] pub transactions: Transactions, - #[superstruct(only(Capella, Eip4844))] + #[superstruct(only(Capella, Eip4844, Eip6110))] pub withdrawals: Withdrawals, - #[superstruct(only(Eip4844))] + #[superstruct(only(Eip6110))] pub deposit_receipts: DepositReceipts, } @@ -113,6 +113,7 @@ impl ExecutionPayload { ForkName::Merge => ExecutionPayloadMerge::from_ssz_bytes(bytes).map(Self::Merge), ForkName::Capella => ExecutionPayloadCapella::from_ssz_bytes(bytes).map(Self::Capella), ForkName::Eip4844 => ExecutionPayloadEip4844::from_ssz_bytes(bytes).map(Self::Eip4844), + ForkName::Eip6110 => ExecutionPayloadEip6110::from_ssz_bytes(bytes).map(Self::Eip6110), } } @@ -152,6 +153,19 @@ impl ExecutionPayload { // Max size of variable length `withdrawals` field + (T::max_withdrawals_per_payload() * ::ssz_fixed_len()) } + + #[allow(clippy::integer_arithmetic)] + /// Returns the maximum size of an execution payload. + pub fn max_execution_payload_eip6110_size() -> usize { + // Fixed part + ExecutionPayloadEip6110::::default().as_ssz_bytes().len() + // Max size of variable length `extra_data` field + + (T::max_extra_data_bytes() * ::ssz_fixed_len()) + // Max size of variable length `transactions` field + + (T::max_transactions_per_payload() * (ssz::BYTES_PER_LENGTH_OFFSET + T::max_bytes_per_transaction())) + // Max size of variable length `deposit_receipts` field + + (T::max_deposit_receipts_per_payload() * ::ssz_fixed_len()) + } } impl ForkVersionDeserialize for ExecutionPayload { @@ -167,6 +181,7 @@ impl ForkVersionDeserialize for ExecutionPayload { ForkName::Merge => Self::Merge(serde_json::from_value(value).map_err(convert_err)?), ForkName::Capella => Self::Capella(serde_json::from_value(value).map_err(convert_err)?), ForkName::Eip4844 => Self::Eip4844(serde_json::from_value(value).map_err(convert_err)?), + ForkName::Eip6110 => Self::Eip6110(serde_json::from_value(value).map_err(convert_err)?), ForkName::Base | ForkName::Altair => { return Err(serde::de::Error::custom(format!( "ExecutionPayload failed to deserialize: unsupported fork '{}'", diff --git a/consensus/types/src/execution_payload_header.rs b/consensus/types/src/execution_payload_header.rs index fde2fa8880d..dd7b879fb8b 100644 --- a/consensus/types/src/execution_payload_header.rs +++ b/consensus/types/src/execution_payload_header.rs @@ -9,7 +9,7 @@ use tree_hash_derive::TreeHash; use BeaconStateError; #[superstruct( - variants(Merge, Capella, Eip4844), + variants(Merge, Capella, Eip4844, Eip6110), variant_attributes( derive( Default, @@ -70,7 +70,7 @@ pub struct ExecutionPayloadHeader { #[serde(with = "eth2_serde_utils::quoted_u256")] #[superstruct(getter(copy))] pub base_fee_per_gas: Uint256, - #[superstruct(only(Eip4844))] + #[superstruct(only(Eip4844, Eip6110))] #[serde(with = "eth2_serde_utils::quoted_u256")] #[superstruct(getter(copy))] pub excess_data_gas: Uint256, @@ -78,10 +78,10 @@ pub struct ExecutionPayloadHeader { pub block_hash: ExecutionBlockHash, #[superstruct(getter(copy))] pub transactions_root: Hash256, - #[superstruct(only(Capella, Eip4844))] + #[superstruct(only(Capella, Eip4844, Eip6110))] #[superstruct(getter(copy))] pub withdrawals_root: Hash256, - #[superstruct(only(Eip4844))] + #[superstruct(only(Eip6110))] #[superstruct(getter(copy))] pub deposit_receipts_root: Hash256, } @@ -103,6 +103,9 @@ impl ExecutionPayloadHeader { ForkName::Eip4844 => { ExecutionPayloadHeaderEip4844::from_ssz_bytes(bytes).map(Self::Eip4844) } + ForkName::Eip6110 => { + ExecutionPayloadHeaderEip6110::from_ssz_bytes(bytes).map(Self::Eip6110) + } } } } @@ -158,6 +161,29 @@ impl ExecutionPayloadHeaderCapella { block_hash: self.block_hash, transactions_root: self.transactions_root, withdrawals_root: self.withdrawals_root, + } + } +} + +impl ExecutionPayloadHeaderEip4844 { + pub fn upgrade_to_eip6110(&self) -> ExecutionPayloadHeaderEip6110 { + ExecutionPayloadHeaderEip6110 { + parent_hash: self.parent_hash, + fee_recipient: self.fee_recipient, + state_root: self.state_root, + receipts_root: self.receipts_root, + logs_bloom: self.logs_bloom.clone(), + prev_randao: self.prev_randao, + block_number: self.block_number, + gas_limit: self.gas_limit, + gas_used: self.gas_used, + timestamp: self.timestamp, + extra_data: self.extra_data.clone(), + base_fee_per_gas: self.base_fee_per_gas, + excess_data_gas: Uint256::zero(), + block_hash: self.block_hash, + transactions_root: self.transactions_root, + withdrawals_root: self.withdrawals_root, deposit_receipts_root: Hash256::zero(), } } @@ -207,6 +233,29 @@ impl<'a, T: EthSpec> From<&'a ExecutionPayloadCapella> for ExecutionPayloadHe impl<'a, T: EthSpec> From<&'a ExecutionPayloadEip4844> for ExecutionPayloadHeaderEip4844 { fn from(payload: &'a ExecutionPayloadEip4844) -> Self { + Self { + parent_hash: payload.parent_hash, + fee_recipient: payload.fee_recipient, + state_root: payload.state_root, + receipts_root: payload.receipts_root, + logs_bloom: payload.logs_bloom.clone(), + prev_randao: payload.prev_randao, + block_number: payload.block_number, + gas_limit: payload.gas_limit, + gas_used: payload.gas_used, + timestamp: payload.timestamp, + extra_data: payload.extra_data.clone(), + base_fee_per_gas: payload.base_fee_per_gas, + excess_data_gas: payload.excess_data_gas, + block_hash: payload.block_hash, + transactions_root: payload.transactions.tree_hash_root(), + withdrawals_root: payload.withdrawals.tree_hash_root(), + } + } +} + +impl<'a, T: EthSpec> From<&'a ExecutionPayloadEip6110> for ExecutionPayloadHeaderEip6110 { + fn from(payload: &'a ExecutionPayloadEip6110) -> Self { Self { parent_hash: payload.parent_hash, fee_recipient: payload.fee_recipient, @@ -249,6 +298,12 @@ impl<'a, T: EthSpec> From<&'a Self> for ExecutionPayloadHeaderEip4844 { } } +impl<'a, T: EthSpec> From<&'a Self> for ExecutionPayloadHeaderEip6110 { + fn from(payload: &'a Self) -> Self { + payload.clone() + } +} + impl<'a, T: EthSpec> From> for ExecutionPayloadHeader { fn from(payload: ExecutionPayloadRef<'a, T>) -> Self { map_execution_payload_ref_into_execution_payload_header!( @@ -291,6 +346,18 @@ impl TryFrom> for ExecutionPayloadHeaderEi } } +impl TryFrom> for ExecutionPayloadHeaderEip6110 { + type Error = BeaconStateError; + fn try_from(header: ExecutionPayloadHeader) -> Result { + match header { + ExecutionPayloadHeader::Eip6110(execution_payload_header) => { + Ok(execution_payload_header) + } + _ => Err(BeaconStateError::IncorrectStateVariant), + } + } +} + impl ForkVersionDeserialize for ExecutionPayloadHeader { fn deserialize_by_fork<'de, D: serde::Deserializer<'de>>( value: serde_json::value::Value, @@ -307,6 +374,7 @@ impl ForkVersionDeserialize for ExecutionPayloadHeader { ForkName::Merge => Self::Merge(serde_json::from_value(value).map_err(convert_err)?), ForkName::Capella => Self::Capella(serde_json::from_value(value).map_err(convert_err)?), ForkName::Eip4844 => Self::Eip4844(serde_json::from_value(value).map_err(convert_err)?), + ForkName::Eip6110 => Self::Eip6110(serde_json::from_value(value).map_err(convert_err)?), ForkName::Base | ForkName::Altair => { return Err(serde::de::Error::custom(format!( "ExecutionPayloadHeader failed to deserialize: unsupported fork '{}'", diff --git a/consensus/types/src/fork_context.rs b/consensus/types/src/fork_context.rs index f5221dd913d..3bf8687c425 100644 --- a/consensus/types/src/fork_context.rs +++ b/consensus/types/src/fork_context.rs @@ -61,6 +61,13 @@ impl ForkContext { )); } + if spec.eip6110_fork_epoch.is_some() { + fork_to_digest.push(( + ForkName::Eip6110, + ChainSpec::compute_fork_digest(spec.eip6110_fork_version, genesis_validators_root), + )); + } + let fork_to_digest: HashMap = fork_to_digest.into_iter().collect(); let digest_to_fork = fork_to_digest diff --git a/consensus/types/src/fork_name.rs b/consensus/types/src/fork_name.rs index 89eaff7985d..6160d92b90f 100644 --- a/consensus/types/src/fork_name.rs +++ b/consensus/types/src/fork_name.rs @@ -13,6 +13,7 @@ pub enum ForkName { Merge, Capella, Eip4844, + Eip6110, } impl ForkName { @@ -23,6 +24,7 @@ impl ForkName { ForkName::Merge, ForkName::Capella, ForkName::Eip4844, + ForkName::Eip6110, ] } @@ -36,6 +38,7 @@ impl ForkName { spec.bellatrix_fork_epoch = None; spec.capella_fork_epoch = None; spec.eip4844_fork_epoch = None; + spec.eip6110_fork_epoch = None; spec } ForkName::Altair => { @@ -43,6 +46,7 @@ impl ForkName { spec.bellatrix_fork_epoch = None; spec.capella_fork_epoch = None; spec.eip4844_fork_epoch = None; + spec.eip6110_fork_epoch = None; spec } ForkName::Merge => { @@ -50,6 +54,7 @@ impl ForkName { spec.bellatrix_fork_epoch = Some(Epoch::new(0)); spec.capella_fork_epoch = None; spec.eip4844_fork_epoch = None; + spec.eip6110_fork_epoch = None; spec } ForkName::Capella => { @@ -57,6 +62,7 @@ impl ForkName { spec.bellatrix_fork_epoch = Some(Epoch::new(0)); spec.capella_fork_epoch = Some(Epoch::new(0)); spec.eip4844_fork_epoch = None; + spec.eip6110_fork_epoch = None; spec } ForkName::Eip4844 => { @@ -64,6 +70,15 @@ impl ForkName { spec.bellatrix_fork_epoch = Some(Epoch::new(0)); spec.capella_fork_epoch = Some(Epoch::new(0)); spec.eip4844_fork_epoch = Some(Epoch::new(0)); + spec.eip6110_fork_epoch = None; + spec + } + ForkName::Eip6110 => { + spec.altair_fork_epoch = Some(Epoch::new(0)); + spec.bellatrix_fork_epoch = Some(Epoch::new(0)); + spec.capella_fork_epoch = Some(Epoch::new(0)); + spec.eip4844_fork_epoch = Some(Epoch::new(0)); + spec.eip6110_fork_epoch = Some(Epoch::new(0)); spec } } @@ -79,6 +94,7 @@ impl ForkName { ForkName::Merge => Some(ForkName::Altair), ForkName::Capella => Some(ForkName::Merge), ForkName::Eip4844 => Some(ForkName::Capella), + ForkName::Eip6110 => Some(ForkName::Eip4844), } } @@ -91,7 +107,8 @@ impl ForkName { ForkName::Altair => Some(ForkName::Merge), ForkName::Merge => Some(ForkName::Capella), ForkName::Capella => Some(ForkName::Eip4844), - ForkName::Eip4844 => None, + ForkName::Eip4844 => Some(ForkName::Eip6110), + ForkName::Eip6110 => None, } } } @@ -141,6 +158,10 @@ macro_rules! map_fork_name_with { let (value, extra_data) = $body; ($t::Eip4844(value), extra_data) } + ForkName::Eip6110 => { + let (value, extra_data) = $body; + ($t::Eip6110(value), extra_data) + } } }; } @@ -155,6 +176,7 @@ impl FromStr for ForkName { "bellatrix" | "merge" => ForkName::Merge, "capella" => ForkName::Capella, "eip4844" => ForkName::Eip4844, + "eip6110" => ForkName::Eip6110, _ => return Err(format!("unknown fork name: {}", fork_name)), }) } @@ -168,6 +190,7 @@ impl Display for ForkName { ForkName::Merge => "bellatrix".fmt(f), ForkName::Capella => "capella".fmt(f), ForkName::Eip4844 => "eip4844".fmt(f), + ForkName::Eip6110 => "eip6110".fmt(f), } } } diff --git a/consensus/types/src/lib.rs b/consensus/types/src/lib.rs index b38a6080b6c..04514aa5617 100644 --- a/consensus/types/src/lib.rs +++ b/consensus/types/src/lib.rs @@ -111,11 +111,13 @@ pub use crate::attestation_duty::AttestationDuty; pub use crate::attester_slashing::AttesterSlashing; pub use crate::beacon_block::{ BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockCapella, BeaconBlockEip4844, - BeaconBlockMerge, BeaconBlockRef, BeaconBlockRefMut, BlindedBeaconBlock, EmptyBlock, + BeaconBlockEip6110, BeaconBlockMerge, BeaconBlockRef, BeaconBlockRefMut, BlindedBeaconBlock, + EmptyBlock, }; pub use crate::beacon_block_body::{ BeaconBlockBody, BeaconBlockBodyAltair, BeaconBlockBodyBase, BeaconBlockBodyCapella, - BeaconBlockBodyEip4844, BeaconBlockBodyMerge, BeaconBlockBodyRef, BeaconBlockBodyRefMut, + BeaconBlockBodyEip4844, BeaconBlockBodyEip6110, BeaconBlockBodyMerge, BeaconBlockBodyRef, + BeaconBlockBodyRefMut, }; pub use crate::beacon_block_header::BeaconBlockHeader; pub use crate::beacon_committee::{BeaconCommittee, OwnedBeaconCommittee}; @@ -140,11 +142,13 @@ pub use crate::execution_block_hash::ExecutionBlockHash; pub use crate::execution_block_header::ExecutionBlockHeader; pub use crate::execution_payload::{ DepositReceipts, ExecutionPayload, ExecutionPayloadCapella, ExecutionPayloadEip4844, - ExecutionPayloadMerge, ExecutionPayloadRef, Transaction, Transactions, Withdrawals, + ExecutionPayloadEip6110, ExecutionPayloadMerge, ExecutionPayloadRef, Transaction, Transactions, + Withdrawals, }; pub use crate::execution_payload_header::{ ExecutionPayloadHeader, ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderEip4844, - ExecutionPayloadHeaderMerge, ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut, + ExecutionPayloadHeaderEip6110, ExecutionPayloadHeaderMerge, ExecutionPayloadHeaderRef, + ExecutionPayloadHeaderRefMut, }; pub use crate::fork::Fork; pub use crate::fork_context::ForkContext; @@ -162,8 +166,9 @@ pub use crate::participation_flags::ParticipationFlags; pub use crate::participation_list::ParticipationList; pub use crate::payload::{ AbstractExecPayload, BlindedPayload, BlindedPayloadCapella, BlindedPayloadEip4844, - BlindedPayloadMerge, BlindedPayloadRef, BlockType, ExecPayload, FullPayload, - FullPayloadCapella, FullPayloadEip4844, FullPayloadMerge, FullPayloadRef, OwnedExecPayload, + BlindedPayloadEip6110, BlindedPayloadMerge, BlindedPayloadRef, BlockType, ExecPayload, + FullPayload, FullPayloadCapella, FullPayloadEip4844, FullPayloadEip6110, FullPayloadMerge, + FullPayloadRef, OwnedExecPayload, }; pub use crate::pending_attestation::PendingAttestation; pub use crate::preset::{AltairPreset, BasePreset, BellatrixPreset, CapellaPreset}; @@ -175,8 +180,8 @@ pub use crate::shuffling_id::AttestationShufflingId; pub use crate::signed_aggregate_and_proof::SignedAggregateAndProof; pub use crate::signed_beacon_block::{ SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockBase, SignedBeaconBlockCapella, - SignedBeaconBlockEip4844, SignedBeaconBlockHash, SignedBeaconBlockMerge, - SignedBlindedBeaconBlock, + SignedBeaconBlockEip4844, SignedBeaconBlockEip6110, SignedBeaconBlockHash, + SignedBeaconBlockMerge, SignedBlindedBeaconBlock, }; pub use crate::signed_beacon_block_header::SignedBeaconBlockHeader; pub use crate::signed_block_and_blobs::SignedBeaconBlockAndBlobsSidecar; diff --git a/consensus/types/src/payload.rs b/consensus/types/src/payload.rs index bbc6423c057..eeece8f96bd 100644 --- a/consensus/types/src/payload.rs +++ b/consensus/types/src/payload.rs @@ -83,12 +83,14 @@ pub trait AbstractExecPayload: + TryInto + TryInto + TryInto + + TryInto { type Ref<'a>: ExecPayload + Copy + From<&'a Self::Merge> + From<&'a Self::Capella> - + From<&'a Self::Eip4844>; + + From<&'a Self::Eip4844> + + From<&'a Self::Eip6110>; type Merge: OwnedExecPayload + Into @@ -102,12 +104,16 @@ pub trait AbstractExecPayload: + Into + for<'a> From>> + TryFrom>; + type Eip6110: OwnedExecPayload + + Into + + for<'a> From>> + + TryFrom>; fn default_at_fork(fork_name: ForkName) -> Result; } #[superstruct( - variants(Merge, Capella, Eip4844), + variants(Merge, Capella, Eip4844, Eip6110), variant_attributes( derive( Debug, @@ -148,6 +154,8 @@ pub struct FullPayload { pub execution_payload: ExecutionPayloadCapella, #[superstruct(only(Eip4844), partial_getter(rename = "execution_payload_eip4844"))] pub execution_payload: ExecutionPayloadEip4844, + #[superstruct(only(Eip6110), partial_getter(rename = "execution_payload_eip6110"))] + pub execution_payload: ExecutionPayloadEip6110, } impl From> for ExecutionPayload { @@ -254,6 +262,9 @@ impl ExecPayload for FullPayload { FullPayload::Eip4844(ref inner) => { Ok(inner.execution_payload.withdrawals.tree_hash_root()) } + FullPayload::Eip6110(ref inner) => { + Ok(inner.execution_payload.withdrawals.tree_hash_root()) + } } } @@ -279,7 +290,11 @@ impl ExecPayload for FullPayload { // Return an "empty" or "default" value for the Capella variant Ok(Vec::new().into()) } - FullPayload::Eip4844(ref inner) => Ok(inner.execution_payload.deposit_receipts.clone()), + FullPayload::Eip4844(_) => { + // Return an "empty" or "default" value for the EIP-4844 variant + Ok(Vec::new().into()) + } + FullPayload::Eip6110(ref inner) => Ok(inner.execution_payload.deposit_receipts.clone()), } } } @@ -377,6 +392,9 @@ impl<'b, T: EthSpec> ExecPayload for FullPayloadRef<'b, T> { FullPayloadRef::Eip4844(inner) => { Ok(inner.execution_payload.withdrawals.tree_hash_root()) } + FullPayloadRef::Eip6110(inner) => { + Ok(inner.execution_payload.withdrawals.tree_hash_root()) + } } } @@ -402,7 +420,11 @@ impl<'b, T: EthSpec> ExecPayload for FullPayloadRef<'b, T> { // Return an "empty" or "default" value for the Capella variant Ok(Vec::new().into()) } - FullPayloadRef::Eip4844(ref inner) => { + FullPayloadRef::Eip4844(_) => { + // Return an "empty" or "default" value for the EIP-4844 variant + Ok(Vec::new().into()) + } + FullPayloadRef::Eip6110(ref inner) => { Ok(inner.execution_payload.deposit_receipts.clone()) } } @@ -414,6 +436,7 @@ impl AbstractExecPayload for FullPayload { type Merge = FullPayloadMerge; type Capella = FullPayloadCapella; type Eip4844 = FullPayloadEip4844; + type Eip6110 = FullPayloadEip6110; fn default_at_fork(fork_name: ForkName) -> Result { match fork_name { @@ -421,6 +444,7 @@ impl AbstractExecPayload for FullPayload { ForkName::Merge => Ok(FullPayloadMerge::default().into()), ForkName::Capella => Ok(FullPayloadCapella::default().into()), ForkName::Eip4844 => Ok(FullPayloadEip4844::default().into()), + ForkName::Eip6110 => Ok(FullPayloadEip6110::default().into()), } } } @@ -441,7 +465,7 @@ impl TryFrom> for FullPayload { } #[superstruct( - variants(Merge, Capella, Eip4844), + variants(Merge, Capella, Eip4844, Eip6110), variant_attributes( derive( Debug, @@ -481,6 +505,8 @@ pub struct BlindedPayload { pub execution_payload_header: ExecutionPayloadHeaderCapella, #[superstruct(only(Eip4844), partial_getter(rename = "execution_payload_eip4844"))] pub execution_payload_header: ExecutionPayloadHeaderEip4844, + #[superstruct(only(Eip6110), partial_getter(rename = "execution_payload_eip6110"))] + pub execution_payload_header: ExecutionPayloadHeaderEip6110, } impl<'a, T: EthSpec> From> for BlindedPayload { @@ -565,6 +591,9 @@ impl ExecPayload for BlindedPayload { BlindedPayload::Eip4844(ref inner) => { Ok(inner.execution_payload_header.withdrawals_root) } + BlindedPayload::Eip6110(ref inner) => { + Ok(inner.execution_payload_header.withdrawals_root) + } } } @@ -659,6 +688,9 @@ impl<'b, T: EthSpec> ExecPayload for BlindedPayloadRef<'b, T> { BlindedPayloadRef::Eip4844(inner) => { Ok(inner.execution_payload_header.withdrawals_root) } + BlindedPayloadRef::Eip6110(inner) => { + Ok(inner.execution_payload_header.withdrawals_root) + } } } @@ -690,6 +722,10 @@ impl<'b, T: EthSpec> ExecPayload for BlindedPayloadRef<'b, T> { // Return an "empty" or "default" value for the Eip4844 variant Ok(Vec::new().into()) } + BlindedPayloadRef::Eip6110(_) => { + // Return an "empty" or "default" value for the Eip6110 variant + Ok(Vec::new().into()) + } } } } @@ -950,12 +986,20 @@ impl_exec_payload_for_fork!( ExecutionPayloadEip4844, Eip4844 ); +impl_exec_payload_for_fork!( + BlindedPayloadEip6110, + FullPayloadEip6110, + ExecutionPayloadHeaderEip6110, + ExecutionPayloadEip6110, + Eip6110 +); impl AbstractExecPayload for BlindedPayload { type Ref<'a> = BlindedPayloadRef<'a, T>; type Merge = BlindedPayloadMerge; type Capella = BlindedPayloadCapella; type Eip4844 = BlindedPayloadEip4844; + type Eip6110 = BlindedPayloadEip6110; fn default_at_fork(fork_name: ForkName) -> Result { match fork_name { @@ -963,6 +1007,7 @@ impl AbstractExecPayload for BlindedPayload { ForkName::Merge => Ok(BlindedPayloadMerge::default().into()), ForkName::Capella => Ok(BlindedPayloadCapella::default().into()), ForkName::Eip4844 => Ok(BlindedPayloadEip4844::default().into()), + ForkName::Eip6110 => Ok(BlindedPayloadEip6110::default().into()), } } } @@ -996,6 +1041,11 @@ impl From> for BlindedPayload { execution_payload_header, }) } + ExecutionPayloadHeader::Eip6110(execution_payload_header) => { + Self::Eip6110(BlindedPayloadEip6110 { + execution_payload_header, + }) + } } } } @@ -1012,6 +1062,9 @@ impl From> for ExecutionPayloadHeader { BlindedPayload::Eip4844(blinded_payload) => { ExecutionPayloadHeader::Eip4844(blinded_payload.execution_payload_header) } + BlindedPayload::Eip6110(blinded_payload) => { + ExecutionPayloadHeader::Eip6110(blinded_payload.execution_payload_header) + } } } } diff --git a/consensus/types/src/signed_beacon_block.rs b/consensus/types/src/signed_beacon_block.rs index ae59690bf2d..1546bc1e04a 100644 --- a/consensus/types/src/signed_beacon_block.rs +++ b/consensus/types/src/signed_beacon_block.rs @@ -45,7 +45,7 @@ pub enum BlobReconstructionError { /// A `BeaconBlock` and a signature from its proposer. #[superstruct( - variants(Base, Altair, Merge, Capella, Eip4844), + variants(Base, Altair, Merge, Capella, Eip4844, Eip6110), variant_attributes( derive( Debug, @@ -86,6 +86,8 @@ pub struct SignedBeaconBlock = FullP pub message: BeaconBlockCapella, #[superstruct(only(Eip4844), partial_getter(rename = "message_eip4844"))] pub message: BeaconBlockEip4844, + #[superstruct(only(Eip6110), partial_getter(rename = "message_eip6110"))] + pub message: BeaconBlockEip6110, pub signature: Signature, } @@ -149,6 +151,9 @@ impl> SignedBeaconBlock BeaconBlock::Eip4844(message) => { SignedBeaconBlock::Eip4844(SignedBeaconBlockEip4844 { message, signature }) } + BeaconBlock::Eip6110(message) => { + SignedBeaconBlock::Eip6110(SignedBeaconBlockEip6110 { message, signature }) + } } } @@ -464,6 +469,62 @@ impl SignedBeaconBlockEip4844> { } } +impl SignedBeaconBlockEip6110> { + pub fn into_full_block( + self, + execution_payload: ExecutionPayloadEip6110, + ) -> SignedBeaconBlockEip6110> { + let SignedBeaconBlockEip6110 { + message: + BeaconBlockEip6110 { + slot, + proposer_index, + parent_root, + state_root, + body: + BeaconBlockBodyEip6110 { + randao_reveal, + eth1_data, + graffiti, + proposer_slashings, + attester_slashings, + attestations, + deposits, + voluntary_exits, + sync_aggregate, + execution_payload: BlindedPayloadEip6110 { .. }, + bls_to_execution_changes, + blob_kzg_commitments, + }, + }, + signature, + } = self; + SignedBeaconBlockEip6110 { + message: BeaconBlockEip6110 { + slot, + proposer_index, + parent_root, + state_root, + body: BeaconBlockBodyEip6110 { + randao_reveal, + eth1_data, + graffiti, + proposer_slashings, + attester_slashings, + attestations, + deposits, + voluntary_exits, + sync_aggregate, + execution_payload: FullPayloadEip6110 { execution_payload }, + bls_to_execution_changes, + blob_kzg_commitments, + }, + }, + signature, + } + } +} + impl SignedBeaconBlock> { pub fn try_into_full_block( self, @@ -481,11 +542,15 @@ impl SignedBeaconBlock> { (SignedBeaconBlock::Eip4844(block), Some(ExecutionPayload::Eip4844(payload))) => { SignedBeaconBlock::Eip4844(block.into_full_block(payload)) } + (SignedBeaconBlock::Eip6110(block), Some(ExecutionPayload::Eip6110(payload))) => { + SignedBeaconBlock::Eip6110(block.into_full_block(payload)) + } // avoid wildcard matching forks so that compiler will // direct us here when a new fork has been added (SignedBeaconBlock::Merge(_), _) => return None, (SignedBeaconBlock::Capella(_), _) => return None, (SignedBeaconBlock::Eip4844(_), _) => return None, + (SignedBeaconBlock::Eip6110(_), _) => return None, }; Some(full_block) } diff --git a/lcli/src/create_payload_header.rs b/lcli/src/create_payload_header.rs index 7700f23d9dd..6a75ec11640 100644 --- a/lcli/src/create_payload_header.rs +++ b/lcli/src/create_payload_header.rs @@ -6,7 +6,7 @@ use std::io::Write; use std::time::{SystemTime, UNIX_EPOCH}; use types::{ EthSpec, ExecutionPayloadHeader, ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderEip4844, - ExecutionPayloadHeaderMerge, ForkName, + ExecutionPayloadHeaderEip6110, ExecutionPayloadHeaderMerge, ForkName, }; pub fn run(matches: &ArgMatches) -> Result<(), String> { @@ -48,6 +48,14 @@ pub fn run(matches: &ArgMatches) -> Result<(), String> { prev_randao: eth1_block_hash.into_root(), ..ExecutionPayloadHeaderEip4844::default() }), + ForkName::Eip6110 => ExecutionPayloadHeader::Eip6110(ExecutionPayloadHeaderEip6110 { + gas_limit, + base_fee_per_gas, + timestamp: genesis_time, + block_hash: eth1_block_hash, + prev_randao: eth1_block_hash.into_root(), + ..ExecutionPayloadHeaderEip6110::default() + }), }; let mut file = File::create(file_name).map_err(|_| "Unable to create file".to_string())?; diff --git a/lcli/src/main.rs b/lcli/src/main.rs index 92ecc78ed16..b31f1d6dd21 100644 --- a/lcli/src/main.rs +++ b/lcli/src/main.rs @@ -425,7 +425,7 @@ fn main() { .takes_value(true) .default_value("bellatrix") .help("The fork for which the execution payload header should be created.") - .possible_values(&["merge", "bellatrix", "capella", "eip4844"]) + .possible_values(&["merge", "bellatrix", "capella", "eip4844", "eip6110"]) ) ) .subcommand( @@ -594,6 +594,15 @@ fn main() { "The epoch at which to enable the eip4844 hard fork", ), ) + .arg( + Arg::with_name("eip6110-fork-epoch") + .long("eip6110-fork-epoch") + .value_name("EPOCH") + .takes_value(true) + .help( + "The epoch at which to enable the eip6110 hard fork", + ), + ) .arg( Arg::with_name("ttd") .long("ttd") diff --git a/lcli/src/new_testnet.rs b/lcli/src/new_testnet.rs index e28197e6178..43b1cd7b096 100644 --- a/lcli/src/new_testnet.rs +++ b/lcli/src/new_testnet.rs @@ -16,8 +16,8 @@ use types::ExecutionBlockHash; use types::{ test_utils::generate_deterministic_keypairs, Address, BeaconState, ChainSpec, Config, Epoch, Eth1Data, EthSpec, ExecutionPayloadHeader, ExecutionPayloadHeaderCapella, - ExecutionPayloadHeaderEip4844, ExecutionPayloadHeaderMerge, ForkName, Hash256, Keypair, - PublicKey, Validator, + ExecutionPayloadHeaderEip4844, ExecutionPayloadHeaderEip6110, ExecutionPayloadHeaderMerge, + ForkName, Hash256, Keypair, PublicKey, Validator, }; pub fn run(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Result<(), String> { @@ -86,6 +86,10 @@ pub fn run(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Resul spec.eip4844_fork_epoch = Some(fork_epoch); } + if let Some(fork_epoch) = parse_optional(matches, "eip6110-fork-epoch")? { + spec.eip6110_fork_epoch = Some(fork_epoch); + } + if let Some(ttd) = parse_optional(matches, "ttd")? { spec.terminal_total_difficulty = ttd; } @@ -116,6 +120,10 @@ pub fn run(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Resul ExecutionPayloadHeaderEip4844::::from_ssz_bytes(bytes.as_slice()) .map(ExecutionPayloadHeader::Eip4844) } + ForkName::Eip6110 => { + ExecutionPayloadHeaderEip6110::::from_ssz_bytes(bytes.as_slice()) + .map(ExecutionPayloadHeader::Eip6110) + } } .map_err(|e| format!("SSZ decode failed: {:?}", e)) }) diff --git a/lcli/src/parse_ssz.rs b/lcli/src/parse_ssz.rs index 0e87e330b13..7876d7e60e5 100644 --- a/lcli/src/parse_ssz.rs +++ b/lcli/src/parse_ssz.rs @@ -53,16 +53,19 @@ pub fn run_parse_ssz(matches: &ArgMatches) -> Result<(), String> { "signed_block_merge" => decode_and_print::>(&bytes, format)?, "signed_block_capella" => decode_and_print::>(&bytes, format)?, "signed_block_eip4844" => decode_and_print::>(&bytes, format)?, + "signed_block_eip6110" => decode_and_print::>(&bytes, format)?, "block_base" => decode_and_print::>(&bytes, format)?, "block_altair" => decode_and_print::>(&bytes, format)?, "block_merge" => decode_and_print::>(&bytes, format)?, "block_capella" => decode_and_print::>(&bytes, format)?, "block_eip4844" => decode_and_print::>(&bytes, format)?, + "block_eip6110" => decode_and_print::>(&bytes, format)?, "state_base" => decode_and_print::>(&bytes, format)?, "state_altair" => decode_and_print::>(&bytes, format)?, "state_merge" => decode_and_print::>(&bytes, format)?, "state_capella" => decode_and_print::>(&bytes, format)?, "state_eip4844" => decode_and_print::>(&bytes, format)?, + "state_eip6110" => decode_and_print::>(&bytes, format)?, "blobs_sidecar" => decode_and_print::>(&bytes, format)?, other => return Err(format!("Unknown type: {}", other)), }; diff --git a/scripts/local_testnet/setup.sh b/scripts/local_testnet/setup.sh index 1dc7566f6b2..05f2288658f 100755 --- a/scripts/local_testnet/setup.sh +++ b/scripts/local_testnet/setup.sh @@ -30,6 +30,7 @@ lcli \ --bellatrix-fork-epoch $BELLATRIX_FORK_EPOCH \ --capella-fork-epoch $CAPELLA_FORK_EPOCH \ --eip4844-fork-epoch $EIP4844_FORK_EPOCH \ + --eip6110-fork-epoch $EIP6110_FORK_EPOCH \ --ttd $TTD \ --eth1-block-hash $ETH1_BLOCK_HASH \ --eth1-id $CHAIN_ID \ @@ -55,6 +56,7 @@ echo Validators generated with keystore passwords at $DATADIR. GENESIS_TIME=$(lcli pretty-ssz state_merge ~/.lighthouse/local-testnet/testnet/genesis.ssz | jq | grep -Po 'genesis_time": "\K.*\d') CAPELLA_TIME=$((GENESIS_TIME + (CAPELLA_FORK_EPOCH * 32 * SECONDS_PER_SLOT))) EIP4844_TIME=$((GENESIS_TIME + (EIP4844_FORK_EPOCH * 32 * SECONDS_PER_SLOT))) +EIP6110_TIME=$((GENESIS_TIME + (EIP6110_FORK_EPOCH * 32 * SECONDS_PER_SLOT))) sed -i 's/"shanghaiTime".*$/"shanghaiTime": '"$CAPELLA_TIME"',/g' genesis.json sed -i 's/"shardingForkTime".*$/"shardingForkTime": '"$EIP4844_TIME"',/g' genesis.json diff --git a/scripts/local_testnet/vars.env b/scripts/local_testnet/vars.env index dcdf671e3f1..ba860365753 100644 --- a/scripts/local_testnet/vars.env +++ b/scripts/local_testnet/vars.env @@ -42,6 +42,7 @@ ALTAIR_FORK_EPOCH=0 BELLATRIX_FORK_EPOCH=0 CAPELLA_FORK_EPOCH=1 EIP4844_FORK_EPOCH=2 +EIP6110_FORK_EPOCH=3 TTD=0 diff --git a/scripts/tests/vars.env b/scripts/tests/vars.env index e7a688769a9..1c39640c026 100644 --- a/scripts/tests/vars.env +++ b/scripts/tests/vars.env @@ -37,6 +37,7 @@ ALTAIR_FORK_EPOCH=18446744073709551615 BELLATRIX_FORK_EPOCH=18446744073709551615 CAPELLA_FORK_EPOCH=18446744073709551615 EIP4844_FORK_EPOCH=18446744073709551615 +EIP6110_FORK_EPOCH=18446744073709551615 # Spec version (mainnet or minimal) SPEC_PRESET=mainnet diff --git a/testing/ef_tests/src/cases/common.rs b/testing/ef_tests/src/cases/common.rs index f889002bd88..4475f34fbee 100644 --- a/testing/ef_tests/src/cases/common.rs +++ b/testing/ef_tests/src/cases/common.rs @@ -67,6 +67,7 @@ pub fn previous_fork(fork_name: ForkName) -> ForkName { ForkName::Merge => ForkName::Altair, ForkName::Capella => ForkName::Merge, ForkName::Eip4844 => ForkName::Capella, + ForkName::Eip6110 => ForkName::Eip4844, } } diff --git a/testing/ef_tests/src/cases/epoch_processing.rs b/testing/ef_tests/src/cases/epoch_processing.rs index 8b04319f648..6685a9682d8 100644 --- a/testing/ef_tests/src/cases/epoch_processing.rs +++ b/testing/ef_tests/src/cases/epoch_processing.rs @@ -104,7 +104,8 @@ impl EpochTransition for JustificationAndFinalization { BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) - | BeaconState::Eip4844(_) => { + | BeaconState::Eip4844(_) + | BeaconState::Eip6110(_) => { let justification_and_finalization_state = altair::process_justification_and_finalization( state, @@ -128,7 +129,8 @@ impl EpochTransition for RewardsAndPenalties { BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) - | BeaconState::Eip4844(_) => altair::process_rewards_and_penalties( + | BeaconState::Eip4844(_) + | BeaconState::Eip6110(_) => altair::process_rewards_and_penalties( state, &altair::ParticipationCache::new(state, spec).unwrap(), spec, @@ -158,7 +160,8 @@ impl EpochTransition for Slashings { BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) - | BeaconState::Eip4844(_) => { + | BeaconState::Eip4844(_) + | BeaconState::Eip6110(_) => { process_slashings( state, altair::ParticipationCache::new(state, spec) @@ -235,7 +238,8 @@ impl EpochTransition for SyncCommitteeUpdates { BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) - | BeaconState::Eip4844(_) => altair::process_sync_committee_updates(state, spec), + | BeaconState::Eip4844(_) + | BeaconState::Eip6110(_) => altair::process_sync_committee_updates(state, spec), } } } @@ -247,7 +251,8 @@ impl EpochTransition for InactivityUpdates { BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) - | BeaconState::Eip4844(_) => altair::process_inactivity_updates( + | BeaconState::Eip4844(_) + | BeaconState::Eip6110(_) => altair::process_inactivity_updates( state, &altair::ParticipationCache::new(state, spec).unwrap(), spec, @@ -263,7 +268,8 @@ impl EpochTransition for ParticipationFlagUpdates { BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) - | BeaconState::Eip4844(_) => altair::process_participation_flag_updates(state), + | BeaconState::Eip4844(_) + | BeaconState::Eip6110(_) => altair::process_participation_flag_updates(state), } } } @@ -318,6 +324,10 @@ impl> Case for EpochProcessing { T::name() != "participation_record_updates" && T::name() != "historical_roots_update" } + ForkName::Eip4844 | ForkName::Eip6110 => { + T::name() != "participation_record_updates" + && T::name() != "historical_roots_update" + } } } diff --git a/testing/ef_tests/src/cases/fork.rs b/testing/ef_tests/src/cases/fork.rs index 26939ce0447..7003e09dcb5 100644 --- a/testing/ef_tests/src/cases/fork.rs +++ b/testing/ef_tests/src/cases/fork.rs @@ -5,6 +5,7 @@ use crate::decode::{ssz_decode_state, yaml_decode_file}; use serde_derive::Deserialize; use state_processing::upgrade::{ upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_eip4844, + upgrade_to_eip6110, }; use types::{BeaconState, ForkName}; @@ -65,6 +66,7 @@ impl Case for ForkTest { ForkName::Merge => upgrade_to_bellatrix(&mut result_state, spec).map(|_| result_state), ForkName::Capella => upgrade_to_capella(&mut result_state, spec).map(|_| result_state), ForkName::Eip4844 => upgrade_to_eip4844(&mut result_state, spec).map(|_| result_state), + ForkName::Eip6110 => upgrade_to_eip6110(&mut result_state, spec).map(|_| result_state), }; compare_beacon_state_results_without_caches(&mut result, &mut expected) diff --git a/testing/ef_tests/src/cases/operations.rs b/testing/ef_tests/src/cases/operations.rs index 71954405c0c..f2741167c81 100644 --- a/testing/ef_tests/src/cases/operations.rs +++ b/testing/ef_tests/src/cases/operations.rs @@ -98,7 +98,8 @@ impl Operation for Attestation { BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) - | BeaconState::Eip4844(_) => { + | BeaconState::Eip4844(_) + | BeaconState::Eip6110(_) => { altair::process_attestation(state, self, 0, &mut ctxt, VerifySignatures::True, spec) } } diff --git a/testing/ef_tests/src/cases/transition.rs b/testing/ef_tests/src/cases/transition.rs index fb7ccfea644..33b614a4f14 100644 --- a/testing/ef_tests/src/cases/transition.rs +++ b/testing/ef_tests/src/cases/transition.rs @@ -53,6 +53,13 @@ impl LoadCase for TransitionTest { spec.capella_fork_epoch = Some(Epoch::new(0)); spec.eip4844_fork_epoch = Some(metadata.fork_epoch); } + ForkName::Eip6110 => { + spec.altair_fork_epoch = Some(Epoch::new(0)); + spec.bellatrix_fork_epoch = Some(Epoch::new(0)); + spec.capella_fork_epoch = Some(Epoch::new(0)); + spec.eip4844_fork_epoch = Some(Epoch::new(0)); + spec.eip6110_fork_epoch = Some(metadata.fork_epoch); + } } // Load blocks diff --git a/testing/ef_tests/src/handler.rs b/testing/ef_tests/src/handler.rs index 9a20c3a3e9c..504d9035498 100644 --- a/testing/ef_tests/src/handler.rs +++ b/testing/ef_tests/src/handler.rs @@ -222,6 +222,10 @@ impl SszStaticHandler { Self::for_forks(vec![ForkName::Eip4844]) } + pub fn eip6110_only() -> Self { + Self::for_forks(vec![ForkName::Eip6110]) + } + pub fn altair_and_later() -> Self { Self::for_forks(ForkName::list_all()[1..].to_vec()) } diff --git a/testing/ef_tests/src/type_name.rs b/testing/ef_tests/src/type_name.rs index 19b3535fbfa..29d365a5167 100644 --- a/testing/ef_tests/src/type_name.rs +++ b/testing/ef_tests/src/type_name.rs @@ -48,6 +48,7 @@ type_name_generic!(BeaconBlockBodyAltair, "BeaconBlockBody"); type_name_generic!(BeaconBlockBodyMerge, "BeaconBlockBody"); type_name_generic!(BeaconBlockBodyCapella, "BeaconBlockBody"); type_name_generic!(BeaconBlockBodyEip4844, "BeaconBlockBody"); +type_name_generic!(BeaconBlockBodyEip6110, "BeaconBlockBody"); type_name!(BeaconBlockHeader); type_name_generic!(BeaconState); type_name_generic!(BlobsSidecar); @@ -61,11 +62,13 @@ type_name_generic!(ExecutionPayload); type_name_generic!(ExecutionPayloadMerge, "ExecutionPayload"); type_name_generic!(ExecutionPayloadCapella, "ExecutionPayload"); type_name_generic!(ExecutionPayloadEip4844, "ExecutionPayload"); +type_name_generic!(ExecutionPayloadEip6110, "ExecutionPayload"); type_name_generic!(FullPayload, "ExecutionPayload"); type_name_generic!(ExecutionPayloadHeader); type_name_generic!(ExecutionPayloadHeaderMerge, "ExecutionPayloadHeader"); type_name_generic!(ExecutionPayloadHeaderCapella, "ExecutionPayloadHeader"); type_name_generic!(ExecutionPayloadHeaderEip4844, "ExecutionPayloadHeader"); +type_name_generic!(ExecutionPayloadHeaderEip6110, "ExecutionPayloadHeader"); type_name_generic!(BlindedPayload, "ExecutionPayloadHeader"); type_name!(Fork); type_name!(ForkData); diff --git a/testing/ef_tests/tests/tests.rs b/testing/ef_tests/tests/tests.rs index fe2c5f796fc..634eff6c291 100644 --- a/testing/ef_tests/tests/tests.rs +++ b/testing/ef_tests/tests/tests.rs @@ -272,6 +272,10 @@ mod ssz_static { .run(); SszStaticHandler::, MainnetEthSpec>::eip4844_only() .run(); + SszStaticHandler::, MinimalEthSpec>::eip6110_only() + .run(); + SszStaticHandler::, MainnetEthSpec>::eip6110_only() + .run(); } // Altair and later @@ -336,6 +340,10 @@ mod ssz_static { .run(); SszStaticHandler::, MainnetEthSpec>::eip4844_only() .run(); + SszStaticHandler::, MinimalEthSpec>::eip6110_only() + .run(); + SszStaticHandler::, MainnetEthSpec>::eip6110_only() + .run(); } #[test] @@ -352,6 +360,10 @@ mod ssz_static { ::eip4844_only().run(); SszStaticHandler::, MainnetEthSpec> ::eip4844_only().run(); + SszStaticHandler::, MinimalEthSpec> + ::eip6110_only().run(); + SszStaticHandler::, MainnetEthSpec> + ::eip6110_only().run(); } #[test] diff --git a/validator_client/src/signing_method/web3signer.rs b/validator_client/src/signing_method/web3signer.rs index 54352394af2..6edfd83496e 100644 --- a/validator_client/src/signing_method/web3signer.rs +++ b/validator_client/src/signing_method/web3signer.rs @@ -28,6 +28,7 @@ pub enum ForkName { Bellatrix, Capella, Eip4844, + Eip6110, } #[derive(Debug, PartialEq, Serialize)] @@ -101,6 +102,11 @@ impl<'a, T: EthSpec, Payload: AbstractExecPayload> Web3SignerObject<'a, T, Pa block: None, block_header: Some(block.block_header()), }), + BeaconBlock::Eip6110(_) => Ok(Web3SignerObject::BeaconBlock { + version: ForkName::Eip6110, + block: None, + block_header: Some(block.block_header()), + }), } } From bb983bbf15ded4c4aa657bfb77b4cb8220c9aff7 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Tue, 28 Mar 2023 17:50:08 +0200 Subject: [PATCH 11/52] minor fixes --- .../beacon_chain/src/beacon_block_streamer.rs | 3 ++- beacon_node/execution_layer/src/engine_api.rs | 1 + consensus/types/src/eip6110.rs | 24 +++++++++---------- consensus/types/src/execution_payload.rs | 1 + consensus/types/src/payload.rs | 4 +--- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_block_streamer.rs b/beacon_node/beacon_chain/src/beacon_block_streamer.rs index e56c0c3e399..bb74b368557 100644 --- a/beacon_node/beacon_chain/src/beacon_block_streamer.rs +++ b/beacon_node/beacon_chain/src/beacon_block_streamer.rs @@ -3,7 +3,7 @@ use execution_layer::{ExecutionLayer, ExecutionPayloadBodyV1}; use slog::{crit, debug, Logger}; use std::collections::HashMap; use std::sync::Arc; -use store::{DatabaseBlock, ExecutionPayloadEip4844}; +use store::{DatabaseBlock, ExecutionPayloadEip4844, ExecutionPayloadEip6110}; use task_executor::TaskExecutor; use tokio::sync::{ mpsc::{self, UnboundedSender}, @@ -98,6 +98,7 @@ fn reconstruct_default_header_block( ForkName::Merge => ExecutionPayloadMerge::default().into(), ForkName::Capella => ExecutionPayloadCapella::default().into(), ForkName::Eip4844 => ExecutionPayloadEip4844::default().into(), + ForkName::Eip6110 => ExecutionPayloadEip6110::default().into(), ForkName::Base | ForkName::Altair => { return Err(Error::PayloadReconstruction(format!( "Block with fork variant {} has execution payload", diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index 0769a86a382..24544bf640d 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -558,6 +558,7 @@ impl ExecutionPayloadBodyV1 { )) } } + ExecutionPayloadHeader::Eip6110(_) => todo!(), } } } diff --git a/consensus/types/src/eip6110.rs b/consensus/types/src/eip6110.rs index 230db75badb..926e62d251a 100644 --- a/consensus/types/src/eip6110.rs +++ b/consensus/types/src/eip6110.rs @@ -2,22 +2,12 @@ use crate::test_utils::TestRandom; use crate::*; use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; +use std::hash::{Hash, Hasher}; use test_random_derive::TestRandom; use tree_hash_derive::TreeHash; #[derive( - arbitrary::Arbitrary, - Debug, - // PartialEq, - // Eq, - Hash, - Clone, - Serialize, - Deserialize, - Encode, - Decode, - TreeHash, - TestRandom, + arbitrary::Arbitrary, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, )] pub struct DepositReceipt { pub pubkey: PublicKeyBytes, @@ -41,6 +31,16 @@ impl PartialEq for DepositReceipt { } } +// Manually implement the Hash trait for DepositReceipt +impl Hash for DepositReceipt { + fn hash(&self, state: &mut H) { + self.pubkey.hash(state); + self.withdrawal_credentials.hash(state); + self.amount.hash(state); + self.index.hash(state); + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/consensus/types/src/execution_payload.rs b/consensus/types/src/execution_payload.rs index 42d3f43839f..3635779b790 100644 --- a/consensus/types/src/execution_payload.rs +++ b/consensus/types/src/execution_payload.rs @@ -198,6 +198,7 @@ impl ExecutionPayload { ExecutionPayload::Merge(_) => ForkName::Merge, ExecutionPayload::Capella(_) => ForkName::Capella, ExecutionPayload::Eip4844(_) => ForkName::Eip4844, + ExecutionPayload::Eip6110(_) => ForkName::Eip6110, } } } diff --git a/consensus/types/src/payload.rs b/consensus/types/src/payload.rs index eeece8f96bd..38e58a6d74c 100644 --- a/consensus/types/src/payload.rs +++ b/consensus/types/src/payload.rs @@ -424,9 +424,7 @@ impl<'b, T: EthSpec> ExecPayload for FullPayloadRef<'b, T> { // Return an "empty" or "default" value for the EIP-4844 variant Ok(Vec::new().into()) } - FullPayloadRef::Eip6110(ref inner) => { - Ok(inner.execution_payload.deposit_receipts.clone()) - } + FullPayloadRef::Eip6110(inner) => Ok(inner.execution_payload.deposit_receipts.clone()), } } } From 30c8cea79466fdaa2084feaffb2a52e11ecc7589 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Wed, 29 Mar 2023 17:07:42 +0200 Subject: [PATCH 12/52] minor fixes --- .../src/per_block_processing.rs | 4 +- .../src/per_epoch_processing.rs | 6 +- .../src/per_epoch_processing/eip4844.rs | 75 ------------------- .../ef_tests/src/cases/epoch_processing.rs | 2 +- 4 files changed, 6 insertions(+), 81 deletions(-) delete mode 100644 consensus/state_processing/src/per_epoch_processing/eip4844.rs diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 49ecaf23c36..1961c4fea84 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -442,10 +442,10 @@ pub fn process_deposit_receipt( // Create a Deposit object from the DepositReceipt let deposit_data = DepositData { - pubkey: deposit_receipt.pubkey.clone().into(), + pubkey: deposit_receipt.pubkey, withdrawal_credentials: deposit_receipt.withdrawal_credentials, amount: deposit_receipt.amount, - signature: deposit_receipt.signature.clone().into(), + signature: deposit_receipt.signature.clone(), }; let deposit = Deposit { proof: FixedVector::from_elem(Hash256::zero()), // Set an empty proof, since it's not included in DepositReceipt diff --git a/consensus/state_processing/src/per_epoch_processing.rs b/consensus/state_processing/src/per_epoch_processing.rs index 8653b3541cb..765591c647d 100644 --- a/consensus/state_processing/src/per_epoch_processing.rs +++ b/consensus/state_processing/src/per_epoch_processing.rs @@ -14,7 +14,6 @@ pub mod altair; pub mod base; pub mod capella; pub mod effective_balance_updates; -pub mod eip4844; pub mod epoch_processing_summary; pub mod errors; pub mod historical_roots_update; @@ -41,8 +40,9 @@ pub fn process_epoch( match state { BeaconState::Base(_) => base::process_epoch(state, spec), BeaconState::Altair(_) | BeaconState::Merge(_) => altair::process_epoch(state, spec), - BeaconState::Capella(_) | BeaconState::Eip4844(_) => capella::process_epoch(state, spec), - BeaconState::Eip4844(_) | BeaconState::Eip6110(_) => capella::process_epoch(state, spec), + BeaconState::Capella(_) | BeaconState::Eip4844(_) | BeaconState::Eip6110(_) => { + capella::process_epoch(state, spec) + } } } diff --git a/consensus/state_processing/src/per_epoch_processing/eip4844.rs b/consensus/state_processing/src/per_epoch_processing/eip4844.rs deleted file mode 100644 index 5af3758e5b6..00000000000 --- a/consensus/state_processing/src/per_epoch_processing/eip4844.rs +++ /dev/null @@ -1,75 +0,0 @@ -use super::altair::inactivity_updates::process_inactivity_updates; -use super::altair::justification_and_finalization::process_justification_and_finalization; -use super::altair::participation_cache::ParticipationCache; -use super::altair::participation_flag_updates::process_participation_flag_updates; -use super::altair::rewards_and_penalties::process_rewards_and_penalties; -use super::altair::sync_committee_updates::process_sync_committee_updates; -use super::capella::process_historical_summaries_update; -use super::{process_registry_updates, process_slashings, EpochProcessingSummary, Error}; -use crate::per_epoch_processing::{ - effective_balance_updates::process_effective_balance_updates, - resets::{process_eth1_data_reset, process_randao_mixes_reset, process_slashings_reset}, -}; -use types::{BeaconState, ChainSpec, EthSpec, RelativeEpoch}; - -pub fn process_epoch( - state: &mut BeaconState, - spec: &ChainSpec, -) -> Result, Error> { - // Ensure the committee caches are built. - state.build_committee_cache(RelativeEpoch::Previous, spec)?; - state.build_committee_cache(RelativeEpoch::Current, spec)?; - state.build_committee_cache(RelativeEpoch::Next, spec)?; - - // Pre-compute participating indices and total balances. - let participation_cache = ParticipationCache::new(state, spec)?; - let sync_committee = state.current_sync_committee()?.clone(); - - // Justification and finalization. - let justification_and_finalization_state = - process_justification_and_finalization(state, &participation_cache)?; - justification_and_finalization_state.apply_changes_to_state(state); - - process_inactivity_updates(state, &participation_cache, spec)?; - - // Rewards and Penalties. - process_rewards_and_penalties(state, &participation_cache, spec)?; - - // Registry Updates. - process_registry_updates(state, spec)?; - - // Slashings. - process_slashings( - state, - participation_cache.current_epoch_total_active_balance(), - spec, - )?; - - // Reset eth1 data votes. - process_eth1_data_reset(state)?; - - // Update effective balances with hysteresis (lag). - process_effective_balance_updates(state, spec)?; - - // Reset slashings - process_slashings_reset(state)?; - - // Set randao mix - process_randao_mixes_reset(state)?; - - // Set historical summaries accumulator - process_historical_summaries_update(state)?; - - // Rotate current/previous epoch participation - process_participation_flag_updates(state)?; - - process_sync_committee_updates(state, spec)?; - - // Rotate the epoch caches to suit the epoch transition. - state.advance_caches(spec)?; - - Ok(EpochProcessingSummary::Altair { - participation_cache, - sync_committee, - }) -} diff --git a/testing/ef_tests/src/cases/epoch_processing.rs b/testing/ef_tests/src/cases/epoch_processing.rs index 6685a9682d8..adbb890af08 100644 --- a/testing/ef_tests/src/cases/epoch_processing.rs +++ b/testing/ef_tests/src/cases/epoch_processing.rs @@ -324,7 +324,7 @@ impl> Case for EpochProcessing { T::name() != "participation_record_updates" && T::name() != "historical_roots_update" } - ForkName::Eip4844 | ForkName::Eip6110 => { + ForkName::Eip6110 => { T::name() != "participation_record_updates" && T::name() != "historical_roots_update" } From 1369a2902dfe63b9af14ad5b9adfbb632a4c3f27 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Wed, 29 Mar 2023 17:43:57 +0200 Subject: [PATCH 13/52] remove tests for `Eip6110` for now --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 711b783aa69..316a990de03 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,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 merge capella eip4844 eip6110 +FORKS=phase0 altair merge capella eip4844 # eip6110 # Extra flags for Cargo CARGO_INSTALL_EXTRA_FLAGS?= From ffd03f85cb7929a4a2510fb9629b85483ce5d71f Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Thu, 30 Mar 2023 16:07:26 +0200 Subject: [PATCH 14/52] clippy --- .../execution_layer/src/engine_api/json_structures.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index c028abdd0e1..d73cd587e5f 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -447,10 +447,10 @@ pub struct JsonDepositReceipt { impl From for JsonDepositReceipt { fn from(deposit_receipt: DepositReceipt) -> Self { Self { - pubkey: deposit_receipt.pubkey.decompress().unwrap().into(), // Convert PublicKeyBytes to PublicKey + pubkey: deposit_receipt.pubkey.decompress().unwrap().into(), withdrawal_credentials: deposit_receipt.withdrawal_credentials, amount: deposit_receipt.amount, - signature: (deposit_receipt.signature).try_into().unwrap(), // Convert SignatureBytes to Signature + signature: deposit_receipt.signature, index: deposit_receipt.index, } } @@ -459,10 +459,10 @@ impl From for JsonDepositReceipt { impl From for DepositReceipt { fn from(json_deposit_receipt: JsonDepositReceipt) -> Self { Self { - pubkey: json_deposit_receipt.pubkey.into(), + pubkey: json_deposit_receipt.pubkey, withdrawal_credentials: json_deposit_receipt.withdrawal_credentials, amount: json_deposit_receipt.amount, - signature: json_deposit_receipt.signature.into(), + signature: json_deposit_receipt.signature, index: json_deposit_receipt.index, } } From d255634002f83fff889c8668759ef1820913f504 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Thu, 30 Mar 2023 16:16:39 +0200 Subject: [PATCH 15/52] fix Makefile --- Makefile | 2 +- testing/ef_tests/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 316a990de03..bf2ad679453 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,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 merge capella eip4844 # eip6110 +FORKS=phase0 altair merge capella eip4844 # Extra flags for Cargo CARGO_INSTALL_EXTRA_FLAGS?= diff --git a/testing/ef_tests/Makefile b/testing/ef_tests/Makefile index eb2aa10307e..1feba41c86f 100644 --- a/testing/ef_tests/Makefile +++ b/testing/ef_tests/Makefile @@ -1,4 +1,4 @@ -TESTS_TAG := v1.3.0-rc.1 # FIXME: move to latest +TESTS_TAG := v1.3.0-rc.1 TESTS = general minimal mainnet TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS)) From 38f8b54a12c476bd65c71d309e791d4ad6752b6e Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Mon, 3 Apr 2023 11:27:21 +0200 Subject: [PATCH 16/52] `V4` -> `V6110` --- .../execution_layer/src/engine_api/http.rs | 14 ++++----- .../src/engine_api/json_structures.rs | 31 ++++++++++--------- .../src/test_utils/handle_rpc.rs | 16 +++++----- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/beacon_node/execution_layer/src/engine_api/http.rs b/beacon_node/execution_layer/src/engine_api/http.rs index 505eb11cd61..5b6c7b2cc04 100644 --- a/beacon_node/execution_layer/src/engine_api/http.rs +++ b/beacon_node/execution_layer/src/engine_api/http.rs @@ -33,13 +33,13 @@ pub const ETH_SYNCING_TIMEOUT: Duration = Duration::from_secs(1); pub const ENGINE_NEW_PAYLOAD_V1: &str = "engine_newPayloadV1"; pub const ENGINE_NEW_PAYLOAD_V2: &str = "engine_newPayloadV2"; pub const ENGINE_NEW_PAYLOAD_V3: &str = "engine_newPayloadV3"; -pub const ENGINE_NEW_PAYLOAD_V4: &str = "engine_newPayloadV4"; +pub const ENGINE_NEW_PAYLOAD_V6110: &str = "engine_newPayloadV6110"; pub const ENGINE_NEW_PAYLOAD_TIMEOUT: Duration = Duration::from_secs(8); pub const ENGINE_GET_PAYLOAD_V1: &str = "engine_getPayloadV1"; pub const ENGINE_GET_PAYLOAD_V2: &str = "engine_getPayloadV2"; pub const ENGINE_GET_PAYLOAD_V3: &str = "engine_getPayloadV3"; -pub const ENGINE_GET_PAYLOAD_V4: &str = "engine_getPayloadV4"; +pub const ENGINE_GET_PAYLOAD_V6110: &str = "engine_getPayloadV6110"; pub const ENGINE_GET_PAYLOAD_TIMEOUT: Duration = Duration::from_secs(2); pub const ENGINE_GET_BLOBS_BUNDLE_V1: &str = "engine_getBlobsBundleV1"; @@ -897,14 +897,14 @@ impl HttpJsonRpc { Ok(JsonGetPayloadResponse::V3(response).into()) } ForkName::Eip6110 => { - let response: JsonGetPayloadResponseV4 = self + let response: JsonGetPayloadResponseV6110 = self .rpc_request( ENGINE_GET_PAYLOAD_V2, params, ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, ) .await?; - Ok(JsonGetPayloadResponse::V4(response).into()) + Ok(JsonGetPayloadResponse::V6110(response).into()) } ForkName::Base | ForkName::Altair => Err(Error::UnsupportedForkVariant(format!( "called get_payload_v2 with {}", @@ -952,14 +952,14 @@ impl HttpJsonRpc { Ok(JsonGetPayloadResponse::V3(response).into()) } ForkName::Eip6110 => { - let response: JsonGetPayloadResponseV4 = self + let response: JsonGetPayloadResponseV6110 = self .rpc_request( - ENGINE_GET_PAYLOAD_V4, + ENGINE_GET_PAYLOAD_V6110, params, ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, ) .await?; - Ok(JsonGetPayloadResponse::V4(response).into()) + Ok(JsonGetPayloadResponse::V6110(response).into()) } ForkName::Base | ForkName::Altair => Err(Error::UnsupportedForkVariant(format!( "called get_payload_v3 with {}", diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index d73cd587e5f..921aef4a2bd 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -65,7 +65,7 @@ pub struct JsonPayloadIdResponse { } #[superstruct( - variants(V1, V2, V3, V4), + variants(V1, V2, V3, V6110), variant_attributes( derive(Debug, PartialEq, Default, Serialize, Deserialize,), serde(bound = "T: EthSpec", rename_all = "camelCase"), @@ -95,16 +95,17 @@ pub struct JsonExecutionPayload { pub extra_data: VariableList, #[serde(with = "eth2_serde_utils::u256_hex_be")] pub base_fee_per_gas: Uint256, - #[superstruct(only(V3, V4))] + #[superstruct(only(V3, V6110))] #[serde(with = "eth2_serde_utils::u256_hex_be")] pub excess_data_gas: Uint256, pub block_hash: ExecutionBlockHash, #[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")] pub transactions: VariableList, T::MaxTransactionsPerPayload>, - #[superstruct(only(V2, V3, V4))] + #[superstruct(only(V2, V3, V6110))] pub withdrawals: VariableList, - #[superstruct(only(V4))] - pub deposit_receipts: VariableList, + #[superstruct(only(V6110))] + pub deposit_receipts: VariableList, + } impl From> for JsonExecutionPayloadV1 { @@ -180,9 +181,9 @@ impl From> for JsonExecutionPayloadV3 } } } -impl From> for JsonExecutionPayloadV4 { +impl From> for JsonExecutionPayloadV6110 { fn from(payload: ExecutionPayloadEip6110) -> Self { - JsonExecutionPayloadV4 { + JsonExecutionPayloadV6110 { parent_hash: payload.parent_hash, fee_recipient: payload.fee_recipient, state_root: payload.state_root, @@ -220,7 +221,7 @@ impl From> for JsonExecutionPayload { ExecutionPayload::Merge(payload) => JsonExecutionPayload::V1(payload.into()), ExecutionPayload::Capella(payload) => JsonExecutionPayload::V2(payload.into()), ExecutionPayload::Eip4844(payload) => JsonExecutionPayload::V3(payload.into()), - ExecutionPayload::Eip6110(payload) => JsonExecutionPayload::V4(payload.into()), + ExecutionPayload::Eip6110(payload) => JsonExecutionPayload::V6110(payload.into()), } } } @@ -298,8 +299,8 @@ impl From> for ExecutionPayloadEip4844 } } } -impl From> for ExecutionPayloadEip6110 { - fn from(payload: JsonExecutionPayloadV4) -> Self { +impl From> for ExecutionPayloadEip6110 { + fn from(payload: JsonExecutionPayloadV6110) -> Self { ExecutionPayloadEip6110 { parent_hash: payload.parent_hash, fee_recipient: payload.fee_recipient, @@ -338,13 +339,13 @@ impl From> for ExecutionPayload { JsonExecutionPayload::V1(payload) => ExecutionPayload::Merge(payload.into()), JsonExecutionPayload::V2(payload) => ExecutionPayload::Capella(payload.into()), JsonExecutionPayload::V3(payload) => ExecutionPayload::Eip4844(payload.into()), - JsonExecutionPayload::V4(payload) => ExecutionPayload::Eip6110(payload.into()), + JsonExecutionPayload::V6110(payload) => ExecutionPayload::Eip6110(payload.into()), } } } #[superstruct( - variants(V1, V2, V3, V4), + variants(V1, V2, V3, V6110), variant_attributes( derive(Debug, PartialEq, Serialize, Deserialize), serde(bound = "T: EthSpec", rename_all = "camelCase") @@ -361,8 +362,8 @@ pub struct JsonGetPayloadResponse { pub execution_payload: JsonExecutionPayloadV2, #[superstruct(only(V3), partial_getter(rename = "execution_payload_v3"))] pub execution_payload: JsonExecutionPayloadV3, - #[superstruct(only(V4), partial_getter(rename = "execution_payload_v4"))] - pub execution_payload: JsonExecutionPayloadV4, + #[superstruct(only(V6110), partial_getter(rename = "execution_payload_v6110"))] + pub execution_payload: JsonExecutionPayloadV6110, #[serde(with = "eth2_serde_utils::u256_hex_be")] pub block_value: Uint256, } @@ -388,7 +389,7 @@ impl From> for GetPayloadResponse { block_value: response.block_value, }) } - JsonGetPayloadResponse::V4(response) => { + JsonGetPayloadResponse::V6110(response) => { GetPayloadResponse::Eip6110(GetPayloadResponseEip6110 { execution_payload: response.execution_payload.into(), block_value: response.block_value, diff --git a/beacon_node/execution_layer/src/test_utils/handle_rpc.rs b/beacon_node/execution_layer/src/test_utils/handle_rpc.rs index 3c483bdb8fb..9dcd03a60f4 100644 --- a/beacon_node/execution_layer/src/test_utils/handle_rpc.rs +++ b/beacon_node/execution_layer/src/test_utils/handle_rpc.rs @@ -112,8 +112,8 @@ pub async fn handle_rpc( }) }) .map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?, - ENGINE_NEW_PAYLOAD_V4 => get_param::>(params, 0) - .map(|jep| JsonExecutionPayload::V4(jep)) + ENGINE_NEW_PAYLOAD_V6110 => get_param::>(params, 0) + .map(|jep| JsonExecutionPayload::V6110(jep)) .or_else(|_| { get_param::>(params, 0) .map(|jep| JsonExecutionPayload::V3(jep)) @@ -264,7 +264,7 @@ pub async fn handle_rpc( ENGINE_GET_PAYLOAD_V1 | ENGINE_GET_PAYLOAD_V2 | ENGINE_GET_PAYLOAD_V3 - | ENGINE_GET_PAYLOAD_V4 => { + | ENGINE_GET_PAYLOAD_V6110 => { let request: JsonPayloadIdRequest = get_param(params, 0).map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?; let id = request.into(); @@ -350,15 +350,15 @@ pub async fn handle_rpc( }) .unwrap() } - JsonExecutionPayload::V4(execution_payload) => { - serde_json::to_value(JsonGetPayloadResponseV4 { + JsonExecutionPayload::V6110(execution_payload) => { + serde_json::to_value(JsonGetPayloadResponseV6110 { execution_payload, block_value: DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI.into(), }) .unwrap() } }), - ENGINE_GET_PAYLOAD_V4 => Ok(match JsonExecutionPayload::from(response) { + ENGINE_GET_PAYLOAD_V6110 => Ok(match JsonExecutionPayload::from(response) { JsonExecutionPayload::V1(execution_payload) => { serde_json::to_value(JsonGetPayloadResponseV1 { execution_payload, @@ -380,8 +380,8 @@ pub async fn handle_rpc( }) .unwrap() } - JsonExecutionPayload::V4(execution_payload) => { - serde_json::to_value(JsonGetPayloadResponseV4 { + JsonExecutionPayload::V6110(execution_payload) => { + serde_json::to_value(JsonGetPayloadResponseV6110 { execution_payload, block_value: DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI.into(), }) From f733a23a2f95961af0e53952c0cd0276511b41a5 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Mon, 10 Apr 2023 10:27:12 +0200 Subject: [PATCH 17/52] Fix `JsonPayloadAttributes` --- beacon_node/execution_layer/src/engine_api.rs | 6 +----- .../execution_layer/src/engine_api/json_structures.rs | 4 ---- .../src/test_utils/execution_block_generator.rs | 2 +- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index 24544bf640d..8750a9bf3a5 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -22,7 +22,7 @@ pub use types::{ Withdrawal, Withdrawals, }; use types::{ - DepositReceipt, ExecutionPayloadCapella, ExecutionPayloadEip4844, ExecutionPayloadEip6110, + ExecutionPayloadCapella, ExecutionPayloadEip4844, ExecutionPayloadEip6110, ExecutionPayloadMerge, }; @@ -327,8 +327,6 @@ pub struct PayloadAttributes { pub suggested_fee_recipient: Address, #[superstruct(only(V2))] pub withdrawals: Vec, - #[superstruct(only(V2))] - pub deposit_receipts: Vec, } impl PayloadAttributes { @@ -344,7 +342,6 @@ impl PayloadAttributes { prev_randao, suggested_fee_recipient, withdrawals, - deposit_receipts: Vec::new(), }), None => PayloadAttributes::V1(PayloadAttributesV1 { timestamp, @@ -372,7 +369,6 @@ impl From for SsePayloadAttributes { prev_randao, suggested_fee_recipient, withdrawals, - deposit_receipts: _, }) => Self::V2(SsePayloadAttributesV2 { timestamp, prev_randao, diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index 921aef4a2bd..82423746965 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -487,8 +487,6 @@ pub struct JsonPayloadAttributes { pub suggested_fee_recipient: Address, #[superstruct(only(V2))] pub withdrawals: Vec, - #[superstruct(only(V2))] - pub deposit_receipts: Vec, } impl From for JsonPayloadAttributes { @@ -504,7 +502,6 @@ impl From for JsonPayloadAttributes { prev_randao: pa.prev_randao, suggested_fee_recipient: pa.suggested_fee_recipient, withdrawals: pa.withdrawals.into_iter().map(Into::into).collect(), - deposit_receipts: pa.deposit_receipts.into_iter().map(Into::into).collect(), }), } } @@ -523,7 +520,6 @@ impl From for PayloadAttributes { prev_randao: jpa.prev_randao, suggested_fee_recipient: jpa.suggested_fee_recipient, withdrawals: jpa.withdrawals.into_iter().map(Into::into).collect(), - deposit_receipts: jpa.deposit_receipts.into_iter().map(Into::into).collect(), }), } } diff --git a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs index 768c2d35dc5..99df3cbf3dc 100644 --- a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs +++ b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs @@ -582,7 +582,7 @@ impl ExecutionBlockGenerator { block_hash: ExecutionBlockHash::zero(), transactions: vec![].into(), withdrawals: pa.withdrawals.clone().into(), - deposit_receipts: pa.deposit_receipts.clone().into(), + deposit_receipts: vec![].into(), }) } _ => unreachable!(), From 6bc054beb86e97b60f0315af7a3b4a1646f586e9 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Tue, 11 Apr 2023 12:27:46 +0200 Subject: [PATCH 18/52] add consensus-spec-tests of `deposit_receipt` --- testing/ef_tests/src/cases/operations.rs | 31 ++++++++++++++++++++++-- testing/ef_tests/src/type_name.rs | 1 + testing/ef_tests/tests/tests.rs | 6 +++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/testing/ef_tests/src/cases/operations.rs b/testing/ef_tests/src/cases/operations.rs index f2741167c81..fc0366a48a0 100644 --- a/testing/ef_tests/src/cases/operations.rs +++ b/testing/ef_tests/src/cases/operations.rs @@ -7,7 +7,7 @@ use serde_derive::Deserialize; use state_processing::{ per_block_processing::{ errors::BlockProcessingError, - process_block_header, process_execution_payload, + process_block_header, process_deposit_receipt, process_execution_payload, process_operations::{ altair, base, process_attester_slashings, process_bls_to_execution_changes, process_deposits, process_exits, process_proposer_slashings, @@ -19,7 +19,7 @@ use state_processing::{ use std::fmt::Debug; use std::path::Path; use types::{ - Attestation, AttesterSlashing, BeaconBlock, BeaconState, BlindedPayload, ChainSpec, Deposit, + Attestation, AttesterSlashing, BeaconBlock, BeaconState, BlindedPayload, ChainSpec, Deposit, DepositReceipt, EthSpec, ExecutionPayload, ForkName, FullPayload, ProposerSlashing, SignedBlsToExecutionChange, SignedVoluntaryExit, SyncAggregate, }; @@ -367,6 +367,33 @@ impl Operation for WithdrawalsPayload { } } +impl Operation for DepositReceipt { + fn handler_name() -> String { + "deposit_receipt".into() + } + + fn filename() -> String { + "deposit_receipt.ssz_snappy".into() + } + + fn is_enabled_for_fork(fork_name: ForkName) -> bool { + fork_name != ForkName::Base && fork_name != ForkName::Altair && fork_name != ForkName::Merge && fork_name != ForkName::Capella && fork_name != ForkName::Eip4844 + } + + fn decode(path: &Path, _fork_name: ForkName, _spec: &ChainSpec) -> Result { + ssz_decode_file(path) + } + + fn apply_to( + &self, + state: &mut BeaconState, + spec: &ChainSpec, + _: &Operations, + ) -> Result<(), BlockProcessingError> { + process_deposit_receipt(state, self, spec) + } + } + impl Operation for SignedBlsToExecutionChange { fn handler_name() -> String { "bls_to_execution_change".into() diff --git a/testing/ef_tests/src/type_name.rs b/testing/ef_tests/src/type_name.rs index 29d365a5167..07af7ccc9a3 100644 --- a/testing/ef_tests/src/type_name.rs +++ b/testing/ef_tests/src/type_name.rs @@ -55,6 +55,7 @@ type_name_generic!(BlobsSidecar); type_name!(Checkpoint); type_name_generic!(ContributionAndProof); type_name!(Deposit); +type_name!(DepositReceipt); type_name!(DepositData); type_name!(DepositMessage); type_name!(Eth1Data); diff --git a/testing/ef_tests/tests/tests.rs b/testing/ef_tests/tests/tests.rs index 634eff6c291..acaf38c667e 100644 --- a/testing/ef_tests/tests/tests.rs +++ b/testing/ef_tests/tests/tests.rs @@ -34,6 +34,12 @@ fn operations_deposit() { OperationsHandler::::default().run(); } +#[test] +fn operations_deposit_receipt() { + OperationsHandler::::default().run(); + OperationsHandler::::default().run(); +} + #[test] fn operations_exit() { OperationsHandler::::default().run(); From 850988cec82abd73e104e6c0d37f5f97dbcab8fa Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Tue, 11 Apr 2023 13:43:13 +0200 Subject: [PATCH 19/52] fmt and clippy :< --- .../execution_layer/src/test_utils/mod.rs | 1 + testing/ef_tests/src/cases/operations.rs | 26 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/beacon_node/execution_layer/src/test_utils/mod.rs b/beacon_node/execution_layer/src/test_utils/mod.rs index e1a148caaa5..3428f9d91cb 100644 --- a/beacon_node/execution_layer/src/test_utils/mod.rs +++ b/beacon_node/execution_layer/src/test_utils/mod.rs @@ -173,6 +173,7 @@ impl MockServer { *self.ctx.engine_capabilities.write() = engine_capabilities; } + #[allow(clippy::too_many_arguments)] // FIXME: refactor pub fn new( handle: &runtime::Handle, jwt_key: JwtKey, diff --git a/testing/ef_tests/src/cases/operations.rs b/testing/ef_tests/src/cases/operations.rs index fc0366a48a0..ebb5142d685 100644 --- a/testing/ef_tests/src/cases/operations.rs +++ b/testing/ef_tests/src/cases/operations.rs @@ -19,9 +19,9 @@ use state_processing::{ use std::fmt::Debug; use std::path::Path; use types::{ - Attestation, AttesterSlashing, BeaconBlock, BeaconState, BlindedPayload, ChainSpec, Deposit, DepositReceipt, - EthSpec, ExecutionPayload, ForkName, FullPayload, ProposerSlashing, SignedBlsToExecutionChange, - SignedVoluntaryExit, SyncAggregate, + Attestation, AttesterSlashing, BeaconBlock, BeaconState, BlindedPayload, ChainSpec, Deposit, + DepositReceipt, EthSpec, ExecutionPayload, ForkName, FullPayload, ProposerSlashing, + SignedBlsToExecutionChange, SignedVoluntaryExit, SyncAggregate, }; #[derive(Debug, Clone, Default, Deserialize)] @@ -377,7 +377,11 @@ impl Operation for DepositReceipt { } fn is_enabled_for_fork(fork_name: ForkName) -> bool { - fork_name != ForkName::Base && fork_name != ForkName::Altair && fork_name != ForkName::Merge && fork_name != ForkName::Capella && fork_name != ForkName::Eip4844 + fork_name != ForkName::Base + && fork_name != ForkName::Altair + && fork_name != ForkName::Merge + && fork_name != ForkName::Capella + && fork_name != ForkName::Eip4844 } fn decode(path: &Path, _fork_name: ForkName, _spec: &ChainSpec) -> Result { @@ -385,14 +389,14 @@ impl Operation for DepositReceipt { } fn apply_to( - &self, - state: &mut BeaconState, - spec: &ChainSpec, - _: &Operations, - ) -> Result<(), BlockProcessingError> { - process_deposit_receipt(state, self, spec) - } + &self, + state: &mut BeaconState, + spec: &ChainSpec, + _: &Operations, + ) -> Result<(), BlockProcessingError> { + process_deposit_receipt(state, self, spec) } +} impl Operation for SignedBlsToExecutionChange { fn handler_name() -> String { From d2731f061c6a65b287a6170a00f947c207cf542a Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Wed, 12 Apr 2023 11:53:27 +0200 Subject: [PATCH 20/52] minor fix --- consensus/state_processing/src/per_block_processing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 1961c4fea84..8b9be9f576f 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -453,7 +453,7 @@ pub fn process_deposit_receipt( }; // Call process_deposit with the created Deposit object - process_deposit(state, &deposit, spec, true)?; + process_deposit(state, &deposit, spec, false)?; Ok(()) } From f5c97fd291c955ef6ed47a80e1b44592659f4066 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Wed, 12 Apr 2023 12:31:17 +0200 Subject: [PATCH 21/52] cargo fmt --- .../execution_layer/src/engine_api/json_structures.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index 82423746965..4e057a21779 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -7,8 +7,8 @@ use superstruct::superstruct; use types::blobs_sidecar::KzgCommitments; use types::{ Blobs, DepositReceipt, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadCapella, - ExecutionPayloadEip4844, ExecutionPayloadEip6110, ExecutionPayloadMerge, FixedVector, Transactions, Transaction, Unsigned, - VariableList, Withdrawal, + ExecutionPayloadEip4844, ExecutionPayloadEip6110, ExecutionPayloadMerge, FixedVector, + Transaction, Transactions, Unsigned, VariableList, Withdrawal, }; #[derive(Debug, PartialEq, Serialize, Deserialize)] @@ -100,12 +100,12 @@ pub struct JsonExecutionPayload { pub excess_data_gas: Uint256, pub block_hash: ExecutionBlockHash, #[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")] - pub transactions: VariableList, T::MaxTransactionsPerPayload>, + pub transactions: + VariableList, T::MaxTransactionsPerPayload>, #[superstruct(only(V2, V3, V6110))] pub withdrawals: VariableList, #[superstruct(only(V6110))] pub deposit_receipts: VariableList, - } impl From> for JsonExecutionPayloadV1 { From c5e5e85edcc5e78307e74c943c307e6071d5f8dc Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Wed, 12 Apr 2023 17:34:51 +0200 Subject: [PATCH 22/52] fix `operations_deposit_receipt` test --- consensus/state_processing/src/per_block_processing.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 8b9be9f576f..b05b6a7885d 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -452,9 +452,15 @@ pub fn process_deposit_receipt( data: deposit_data, }; + // Store the current eth1_deposit_index + let current_eth1_deposit_index = state.eth1_deposit_index(); + // Call process_deposit with the created Deposit object process_deposit(state, &deposit, spec, false)?; + // Set eth1_deposit_index back to the original value + *state.eth1_deposit_index_mut() = current_eth1_deposit_index; + Ok(()) } From 5db79a92013c13c5c854842a889b178981fc2ec8 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Fri, 14 Apr 2023 16:29:33 +0200 Subject: [PATCH 23/52] cleanup --- beacon_node/execution_layer/src/engine_api.rs | 2 + .../execution_layer/src/engine_api/http.rs | 53 ++++++++++++++----- beacon_node/execution_layer/src/lib.rs | 1 - .../execution_layer/src/test_utils/mod.rs | 2 + consensus/fork_choice/src/fork_choice.rs | 4 +- .../src/per_block_processing.rs | 2 +- .../src/per_block_processing/eip6110.rs | 2 - .../per_block_processing/eip6110/eip6110.rs | 1 - .../process_operations.rs | 23 ++++++-- consensus/types/src/beacon_block.rs | 6 +-- consensus/types/src/beacon_block_body.rs | 1 - consensus/types/src/beacon_state.rs | 1 - 12 files changed, 69 insertions(+), 29 deletions(-) delete mode 100644 consensus/state_processing/src/per_block_processing/eip6110.rs delete mode 100644 consensus/state_processing/src/per_block_processing/eip6110/eip6110.rs diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index 8750a9bf3a5..09be765fa4e 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -564,6 +564,7 @@ pub struct EngineCapabilities { pub new_payload_v1: bool, pub new_payload_v2: bool, pub new_payload_v3: bool, + pub new_payload_v6110: bool, pub forkchoice_updated_v1: bool, pub forkchoice_updated_v2: bool, pub get_payload_bodies_by_hash_v1: bool, @@ -571,6 +572,7 @@ pub struct EngineCapabilities { pub get_payload_v1: bool, pub get_payload_v2: bool, pub get_payload_v3: bool, + pub get_payload_v6110: bool, pub exchange_transition_configuration_v1: bool, } diff --git a/beacon_node/execution_layer/src/engine_api/http.rs b/beacon_node/execution_layer/src/engine_api/http.rs index 5b6c7b2cc04..9eadb44d77e 100644 --- a/beacon_node/execution_layer/src/engine_api/http.rs +++ b/beacon_node/execution_layer/src/engine_api/http.rs @@ -88,6 +88,7 @@ pub static PRE_CAPELLA_ENGINE_CAPABILITIES: EngineCapabilities = EngineCapabilit new_payload_v1: true, new_payload_v2: false, new_payload_v3: false, + new_payload_v6110: false, forkchoice_updated_v1: true, forkchoice_updated_v2: false, get_payload_bodies_by_hash_v1: false, @@ -95,6 +96,7 @@ pub static PRE_CAPELLA_ENGINE_CAPABILITIES: EngineCapabilities = EngineCapabilit get_payload_v1: true, get_payload_v2: false, get_payload_v3: false, + get_payload_v6110: false, exchange_transition_configuration_v1: true, }; @@ -835,6 +837,23 @@ impl HttpJsonRpc { Ok(response.into()) } + pub async fn new_payload_v6110( + &self, + execution_payload: ExecutionPayload, + ) -> Result { + let params = json!([JsonExecutionPayload::from(execution_payload)]); + + let response: JsonPayloadStatusV1 = self + .rpc_request( + ENGINE_NEW_PAYLOAD_V6110, + params, + ENGINE_NEW_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, + ) + .await?; + + Ok(response.into()) + } + pub async fn get_payload_v1( &self, payload_id: PayloadId, @@ -919,7 +938,7 @@ impl HttpJsonRpc { payload_id: PayloadId, ) -> Result, Error> { let params = json!([JsonPayloadIdRequest::from(payload_id)]); - + match fork_name { ForkName::Merge => { let response: JsonGetPayloadResponseV1 = self @@ -951,22 +970,30 @@ impl HttpJsonRpc { .await?; Ok(JsonGetPayloadResponse::V3(response).into()) } - ForkName::Eip6110 => { - let response: JsonGetPayloadResponseV6110 = self - .rpc_request( - ENGINE_GET_PAYLOAD_V6110, - params, - ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, - ) - .await?; - Ok(JsonGetPayloadResponse::V6110(response).into()) - } + ForkName::Eip6110 => self.get_payload_v6110(payload_id).await, ForkName::Base | ForkName::Altair => Err(Error::UnsupportedForkVariant(format!( "called get_payload_v3 with {}", fork_name ))), } - } + } + + pub async fn get_payload_v6110( + &self, + payload_id: PayloadId, + ) -> Result, Error> { + let params = json!([JsonPayloadIdRequest::from(payload_id)]); + + let response: JsonGetPayloadResponseV6110 = self + .rpc_request( + ENGINE_GET_PAYLOAD_V6110, + params, + ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, + ) + .await?; + + Ok(JsonGetPayloadResponse::V6110(response).into()) + } pub async fn get_blobs_bundle_v1( &self, @@ -1112,6 +1139,7 @@ impl HttpJsonRpc { new_payload_v1: capabilities.contains(ENGINE_NEW_PAYLOAD_V1), new_payload_v2: capabilities.contains(ENGINE_NEW_PAYLOAD_V2), new_payload_v3: capabilities.contains(ENGINE_NEW_PAYLOAD_V3), + new_payload_v6110: capabilities.contains(ENGINE_NEW_PAYLOAD_V6110), forkchoice_updated_v1: capabilities.contains(ENGINE_FORKCHOICE_UPDATED_V1), forkchoice_updated_v2: capabilities.contains(ENGINE_FORKCHOICE_UPDATED_V2), get_payload_bodies_by_hash_v1: capabilities @@ -1121,6 +1149,7 @@ impl HttpJsonRpc { get_payload_v1: capabilities.contains(ENGINE_GET_PAYLOAD_V1), get_payload_v2: capabilities.contains(ENGINE_GET_PAYLOAD_V2), get_payload_v3: capabilities.contains(ENGINE_GET_PAYLOAD_V3), + get_payload_v6110: capabilities.contains(ENGINE_GET_PAYLOAD_V6110), exchange_transition_configuration_v1: capabilities .contains(ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_V1), }), diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 4a7ea6ccdb7..8a7d15703b2 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -1792,7 +1792,6 @@ impl ExecutionLayer { .collect(), ) .map_err(ApiError::DeserializeWithdrawals)?; - ExecutionPayload::Eip4844(ExecutionPayloadEip4844 { parent_hash: eip4844_block.parent_hash, fee_recipient: eip4844_block.fee_recipient, diff --git a/beacon_node/execution_layer/src/test_utils/mod.rs b/beacon_node/execution_layer/src/test_utils/mod.rs index 3428f9d91cb..e4b7579f289 100644 --- a/beacon_node/execution_layer/src/test_utils/mod.rs +++ b/beacon_node/execution_layer/src/test_utils/mod.rs @@ -38,6 +38,7 @@ pub const DEFAULT_ENGINE_CAPABILITIES: EngineCapabilities = EngineCapabilities { new_payload_v1: true, new_payload_v2: true, new_payload_v3: true, + new_payload_v6110: true, forkchoice_updated_v1: true, forkchoice_updated_v2: true, get_payload_bodies_by_hash_v1: true, @@ -45,6 +46,7 @@ pub const DEFAULT_ENGINE_CAPABILITIES: EngineCapabilities = EngineCapabilities { get_payload_v1: true, get_payload_v2: true, get_payload_v3: true, + get_payload_v6110: true, exchange_transition_configuration_v1: true, }; diff --git a/consensus/fork_choice/src/fork_choice.rs b/consensus/fork_choice/src/fork_choice.rs index cf8407934c5..1839925f58b 100644 --- a/consensus/fork_choice/src/fork_choice.rs +++ b/consensus/fork_choice/src/fork_choice.rs @@ -753,8 +753,8 @@ where let justification_and_finalization_state = match block { // TODO(eip4844): Ensure that the final specification // does not substantially modify per epoch processing. - BeaconBlockRef::Eip4844(_) - | BeaconBlockRef::Eip6110(_) + BeaconBlockRef::Eip6110(_) + | BeaconBlockRef::Eip4844(_) | BeaconBlockRef::Capella(_) | BeaconBlockRef::Merge(_) | BeaconBlockRef::Altair(_) => { diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index b05b6a7885d..016410fa477 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -29,7 +29,6 @@ pub use verify_exit::verify_exit; pub mod altair; pub mod block_signature_verifier; pub mod eip4844; -pub mod eip6110; pub mod errors; mod is_valid_indexed_attestation; pub mod process_operations; @@ -455,6 +454,7 @@ pub fn process_deposit_receipt( // Store the current eth1_deposit_index let current_eth1_deposit_index = state.eth1_deposit_index(); + // FIXME: This is a workaround to apply_deposit() // Call process_deposit with the created Deposit object process_deposit(state, &deposit, spec, false)?; diff --git a/consensus/state_processing/src/per_block_processing/eip6110.rs b/consensus/state_processing/src/per_block_processing/eip6110.rs deleted file mode 100644 index 3358e302a60..00000000000 --- a/consensus/state_processing/src/per_block_processing/eip6110.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[allow(clippy::module_inception)] -pub mod eip6110; diff --git a/consensus/state_processing/src/per_block_processing/eip6110/eip6110.rs b/consensus/state_processing/src/per_block_processing/eip6110/eip6110.rs deleted file mode 100644 index 8b137891791..00000000000 --- a/consensus/state_processing/src/per_block_processing/eip6110/eip6110.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index bb9fc9bf5ac..78c0b6f9d72 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -21,6 +21,23 @@ pub fn process_operations>( .deposit_count .saturating_sub(state.eth1_deposit_index()); let max_deposits = ::MaxDeposits::to_u64(); + let eth1_deposit_index_limit = state + .deposit_receipts_start_index() + .unwrap_or_else(|_| state.eth1_data().deposit_count); + + if state.eth1_deposit_index() < eth1_deposit_index_limit { + assert_eq!( + block_body.deposits().len(), + std::cmp::min(max_deposits as usize, unprocessed_deposits_count as usize), + "Number of deposits in block does not match the minimum of the maximum number of deposits and the number of unprocessed deposits" + ); + } else { + assert_eq!( + block_body.deposits().len(), + 0, + "Number of deposits in block must be zero when all prior deposits are processed" + ); + } process_proposer_slashings( state, @@ -37,11 +54,6 @@ pub fn process_operations>( spec, )?; process_attestations(state, block_body, verify_signatures, ctxt, spec)?; - assert_eq!( - block_body.deposits().len(), - std::cmp::min(max_deposits as usize, unprocessed_deposits_count as usize), - "Number of deposits in block does not match the minimum of the maximum number of deposits and the number of unprocessed deposits" - ); process_deposits(state, block_body.deposits(), spec)?; process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?; @@ -57,6 +69,7 @@ pub fn process_operations>( Ok(()) } + pub mod base { use super::*; diff --git a/consensus/types/src/beacon_block.rs b/consensus/types/src/beacon_block.rs index 7d2a1f19888..04a315f2309 100644 --- a/consensus/types/src/beacon_block.rs +++ b/consensus/types/src/beacon_block.rs @@ -128,13 +128,13 @@ impl> BeaconBlock { /// Usually it's better to prefer `from_ssz_bytes` which will decode the correct variant based /// on the fork slot. pub fn any_from_ssz_bytes(bytes: &[u8]) -> Result { - BeaconBlockEip4844::from_ssz_bytes(bytes) - .map(BeaconBlock::Eip4844) + BeaconBlockEip6110::from_ssz_bytes(bytes) + .map(BeaconBlock::Eip6110) .or_else(|_| BeaconBlockCapella::from_ssz_bytes(bytes).map(BeaconBlock::Capella)) .or_else(|_| BeaconBlockMerge::from_ssz_bytes(bytes).map(BeaconBlock::Merge)) .or_else(|_| BeaconBlockAltair::from_ssz_bytes(bytes).map(BeaconBlock::Altair)) .or_else(|_| BeaconBlockBase::from_ssz_bytes(bytes).map(BeaconBlock::Base)) - .or_else(|_| BeaconBlockEip6110::from_ssz_bytes(bytes).map(BeaconBlock::Eip6110)) + .or_else(|_| BeaconBlockEip4844::from_ssz_bytes(bytes).map(BeaconBlock::Eip4844)) } /// Convenience accessor for the `body` as a `BeaconBlockBodyRef`. diff --git a/consensus/types/src/beacon_block_body.rs b/consensus/types/src/beacon_block_body.rs index 0506763a925..54cd730fedc 100644 --- a/consensus/types/src/beacon_block_body.rs +++ b/consensus/types/src/beacon_block_body.rs @@ -1,4 +1,3 @@ -use crate::payload::{BlindedPayloadEip6110, FullPayloadEip6110}; use crate::*; use crate::{blobs_sidecar::KzgCommitments, test_utils::TestRandom}; use derivative::Derivative; diff --git a/consensus/types/src/beacon_state.rs b/consensus/types/src/beacon_state.rs index 7f7311b81e2..f82b9884fd8 100644 --- a/consensus/types/src/beacon_state.rs +++ b/consensus/types/src/beacon_state.rs @@ -1,6 +1,5 @@ use self::committee_cache::get_active_validator_indices; use self::exit_cache::ExitCache; -use crate::execution_payload_header::ExecutionPayloadHeaderEip6110; use crate::test_utils::TestRandom; use crate::*; use compare_fields::CompareFields; From 8c3f0d3edb591220ab803018786a85d454b4126e Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Fri, 14 Apr 2023 16:31:20 +0200 Subject: [PATCH 24/52] cargo fmt --- beacon_node/execution_layer/src/engine_api/http.rs | 10 +++++----- .../src/per_block_processing/process_operations.rs | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/beacon_node/execution_layer/src/engine_api/http.rs b/beacon_node/execution_layer/src/engine_api/http.rs index 9eadb44d77e..64558bfcd87 100644 --- a/beacon_node/execution_layer/src/engine_api/http.rs +++ b/beacon_node/execution_layer/src/engine_api/http.rs @@ -938,7 +938,7 @@ impl HttpJsonRpc { payload_id: PayloadId, ) -> Result, Error> { let params = json!([JsonPayloadIdRequest::from(payload_id)]); - + match fork_name { ForkName::Merge => { let response: JsonGetPayloadResponseV1 = self @@ -976,14 +976,14 @@ impl HttpJsonRpc { fork_name ))), } - } + } pub async fn get_payload_v6110( &self, payload_id: PayloadId, ) -> Result, Error> { let params = json!([JsonPayloadIdRequest::from(payload_id)]); - + let response: JsonGetPayloadResponseV6110 = self .rpc_request( ENGINE_GET_PAYLOAD_V6110, @@ -991,9 +991,9 @@ impl HttpJsonRpc { ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, ) .await?; - + Ok(JsonGetPayloadResponse::V6110(response).into()) - } + } pub async fn get_blobs_bundle_v1( &self, diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 78c0b6f9d72..5999df06d74 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -69,7 +69,6 @@ pub fn process_operations>( Ok(()) } - pub mod base { use super::*; From 5070adda43a249fe4d8d973b436d0a582fff7247 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Fri, 14 Apr 2023 17:45:16 +0200 Subject: [PATCH 25/52] add `apply_deposit()` --- .../src/per_block_processing.rs | 13 ++--- .../process_operations.rs | 48 +++++++++++++++++++ 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 016410fa477..e866d3b140d 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -7,7 +7,7 @@ use std::borrow::Cow; use tree_hash::TreeHash; use types::*; -use self::process_operations::process_deposit; +use self::process_operations::apply_deposit; pub use self::verify_attester_slashing::{ get_slashable_indices, get_slashable_indices_modular, verify_attester_slashing, }; @@ -451,15 +451,8 @@ pub fn process_deposit_receipt( data: deposit_data, }; - // Store the current eth1_deposit_index - let current_eth1_deposit_index = state.eth1_deposit_index(); - - // FIXME: This is a workaround to apply_deposit() - // Call process_deposit with the created Deposit object - process_deposit(state, &deposit, spec, false)?; - - // Set eth1_deposit_index back to the original value - *state.eth1_deposit_index_mut() = current_eth1_deposit_index; + // Call apply with the created Deposit object + apply_deposit(state, &deposit, spec)?; Ok(()) } diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 5999df06d74..3d32877b8c1 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -450,3 +450,51 @@ pub fn process_deposit( Ok(()) } + +pub fn apply_deposit( + state: &mut BeaconState, + deposit: &Deposit, + spec: &ChainSpec, +) -> Result<(), BlockProcessingError> { + let amount = deposit.data.amount; + + if let Ok(Some(index)) = get_existing_validator_index(state, &deposit.data.pubkey) { + // Update the existing validator balance. + increase_balance(state, index as usize, amount)?; + } else { + // The signature should be checked for new validators. Return early for a bad signature. + if verify_deposit_signature(&deposit.data, spec).is_err() { + return Ok(()); + } + + // Create a new validator. + let validator = Validator { + pubkey: deposit.data.pubkey, + withdrawal_credentials: deposit.data.withdrawal_credentials, + activation_eligibility_epoch: spec.far_future_epoch, + activation_epoch: spec.far_future_epoch, + exit_epoch: spec.far_future_epoch, + withdrawable_epoch: spec.far_future_epoch, + effective_balance: std::cmp::min( + amount.safe_sub(amount.safe_rem(spec.effective_balance_increment)?)?, + spec.max_effective_balance, + ), + slashed: false, + }; + state.validators_mut().push(validator)?; + state.balances_mut().push(deposit.data.amount)?; + + // Altair or later initializations. + if let Ok(previous_epoch_participation) = state.previous_epoch_participation_mut() { + previous_epoch_participation.push(ParticipationFlags::default())?; + } + if let Ok(current_epoch_participation) = state.current_epoch_participation_mut() { + current_epoch_participation.push(ParticipationFlags::default())?; + } + if let Ok(inactivity_scores) = state.inactivity_scores_mut() { + inactivity_scores.push(0)?; + } + } + + Ok(()) +} From 732326eb5e822cc30d5875af038d8d983c0b5170 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Fri, 14 Apr 2023 18:25:40 +0200 Subject: [PATCH 26/52] minor fix --- consensus/types/src/payload.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/consensus/types/src/payload.rs b/consensus/types/src/payload.rs index 38e58a6d74c..f9847f4f93e 100644 --- a/consensus/types/src/payload.rs +++ b/consensus/types/src/payload.rs @@ -608,7 +608,21 @@ impl ExecPayload for BlindedPayload { } fn deposit_receipts(&self) -> Result, Error> { - todo!() + match self { + BlindedPayload::Merge(_) => { + // Return an "empty" or "default" value for the Merge variant + Ok(Vec::new().into()) + } + BlindedPayload::Capella(_) => { + // Return an "empty" or "default" value for the Capella variant + Ok(Vec::new().into()) + } + BlindedPayload::Eip4844(_) => { + // Return an "empty" or "default" value for the EIP-4844 variant + Ok(Vec::new().into()) + } + BlindedPayload::Eip6110(ref inner) => Ok(inner.deposit_receipts()?.clone()), + } } } From d77f51b656338b06b363719e5b81387276acb27e Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Fri, 14 Apr 2023 19:51:21 +0200 Subject: [PATCH 27/52] clippy --- consensus/types/src/payload.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/consensus/types/src/payload.rs b/consensus/types/src/payload.rs index f9847f4f93e..0d2760e9e6f 100644 --- a/consensus/types/src/payload.rs +++ b/consensus/types/src/payload.rs @@ -621,7 +621,8 @@ impl ExecPayload for BlindedPayload { // Return an "empty" or "default" value for the EIP-4844 variant Ok(Vec::new().into()) } - BlindedPayload::Eip6110(ref inner) => Ok(inner.deposit_receipts()?.clone()), + BlindedPayload::Eip6110(ref inner) => Ok(inner.deposit_receipts()?), + } } } From 96a4f36f79c6e2c7eca7208c318ea4404cbabf22 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Fri, 14 Apr 2023 19:52:51 +0200 Subject: [PATCH 28/52] fmt... --- consensus/types/src/payload.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/consensus/types/src/payload.rs b/consensus/types/src/payload.rs index 0d2760e9e6f..5846ce5fb44 100644 --- a/consensus/types/src/payload.rs +++ b/consensus/types/src/payload.rs @@ -622,7 +622,6 @@ impl ExecPayload for BlindedPayload { Ok(Vec::new().into()) } BlindedPayload::Eip6110(ref inner) => Ok(inner.deposit_receipts()?), - } } } From 042e66068fa3817657bdc271a5dcdbe437f68f69 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Sun, 16 Apr 2023 16:14:04 +0200 Subject: [PATCH 29/52] cleanup --- beacon_node/beacon_chain/src/test_utils.rs | 5 ++++- beacon_node/execution_layer/src/engine_api.rs | 2 +- .../src/test_utils/mock_builder.rs | 14 ++++++++------ .../lighthouse_network/src/types/topics.rs | 2 +- .../per_block_processing/process_operations.rs | 18 ++++++++---------- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index 949310bdd7a..3bcd0d36743 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -447,12 +447,15 @@ where let eip4844_time = spec.eip4844_fork_epoch.map(|epoch| { HARNESS_GENESIS_TIME + spec.seconds_per_slot * E::slots_per_epoch() * epoch.as_u64() }); + let eip6110_time = spec.eip6110_fork_epoch.map(|epoch| { + HARNESS_GENESIS_TIME + spec.seconds_per_slot * E::slots_per_epoch() * epoch.as_u64() + }); let mock = MockExecutionLayer::new( self.runtime.task_executor.clone(), DEFAULT_TERMINAL_BLOCK, shanghai_time, eip4844_time, - None, + eip6110_time, None, Some(JwtKey::from_slice(&DEFAULT_JWT_SECRET).unwrap()), spec, diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index 09be765fa4e..1b18108c262 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -302,7 +302,7 @@ impl TryFrom> for ExecutionBlockWithTransactions .collect(), deposit_receipts: Vec::from(block.deposit_receipts) .into_iter() - .map(|receipt| receipt.into()) + .map(|deposit_receipt| deposit_receipt.into()) .collect(), }) } diff --git a/beacon_node/execution_layer/src/test_utils/mock_builder.rs b/beacon_node/execution_layer/src/test_utils/mock_builder.rs index b5a500c3f3e..9ba63d7937c 100644 --- a/beacon_node/execution_layer/src/test_utils/mock_builder.rs +++ b/beacon_node/execution_layer/src/test_utils/mock_builder.rs @@ -442,17 +442,19 @@ impl mev_rs::BlindedBlockProvider for MockBuilder { let json_payload = serde_json::to_string(&payload).map_err(convert_err)?; let mut message = match fork { - ForkName::Capella => BuilderBid::Capella(BuilderBidCapella { - header: serde_json::from_str(json_payload.as_str()).map_err(convert_err)?, - value: to_ssz_rs(&Uint256::from(DEFAULT_BUILDER_PAYLOAD_VALUE_WEI))?, - public_key: self.builder_sk.public_key(), - }), + ForkName::Capella | ForkName::Eip4844 | ForkName::Eip6110 => { + BuilderBid::Capella(BuilderBidCapella { + header: serde_json::from_str(json_payload.as_str()).map_err(convert_err)?, + value: to_ssz_rs(&Uint256::from(DEFAULT_BUILDER_PAYLOAD_VALUE_WEI))?, + public_key: self.builder_sk.public_key(), + }) + } ForkName::Merge => BuilderBid::Bellatrix(BuilderBidBellatrix { header: serde_json::from_str(json_payload.as_str()).map_err(convert_err)?, value: to_ssz_rs(&Uint256::from(DEFAULT_BUILDER_PAYLOAD_VALUE_WEI))?, public_key: self.builder_sk.public_key(), }), - ForkName::Base | ForkName::Altair | ForkName::Eip4844 | ForkName::Eip6110 => { + ForkName::Base | ForkName::Altair => { return Err(BlindedBlockProviderError::Custom(format!( "Unsupported fork: {}", fork diff --git a/beacon_node/lighthouse_network/src/types/topics.rs b/beacon_node/lighthouse_network/src/types/topics.rs index a78f21af9cd..3dc0ebcdb0f 100644 --- a/beacon_node/lighthouse_network/src/types/topics.rs +++ b/beacon_node/lighthouse_network/src/types/topics.rs @@ -48,7 +48,7 @@ pub fn fork_core_topics(fork_name: &ForkName) -> Vec { ForkName::Merge => vec![], ForkName::Capella => CAPELLA_CORE_TOPICS.to_vec(), ForkName::Eip4844 => vec![], // TODO - ForkName::Eip6110 => vec![], // TODO + ForkName::Eip6110 => vec![], } } diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 3d32877b8c1..986a25eadb8 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -26,17 +26,15 @@ pub fn process_operations>( .unwrap_or_else(|_| state.eth1_data().deposit_count); if state.eth1_deposit_index() < eth1_deposit_index_limit { - assert_eq!( - block_body.deposits().len(), - std::cmp::min(max_deposits as usize, unprocessed_deposits_count as usize), - "Number of deposits in block does not match the minimum of the maximum number of deposits and the number of unprocessed deposits" - ); + if block_body.deposits().len() + != std::cmp::min(max_deposits as usize, unprocessed_deposits_count as usize) + { + return Err(BlockProcessingError::DepositReceiptError); + } } else { - assert_eq!( - block_body.deposits().len(), - 0, - "Number of deposits in block must be zero when all prior deposits are processed" - ); + if block_body.deposits().len() != 0 { + return Err(BlockProcessingError::DepositReceiptError); + } } process_proposer_slashings( From 40f5897dfa6dd527bf37df0c7b719059f268f536 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Sun, 16 Apr 2023 16:27:13 +0200 Subject: [PATCH 30/52] clippy --- .../src/per_block_processing/process_operations.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 986a25eadb8..e026a03944d 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -31,10 +31,8 @@ pub fn process_operations>( { return Err(BlockProcessingError::DepositReceiptError); } - } else { - if block_body.deposits().len() != 0 { - return Err(BlockProcessingError::DepositReceiptError); - } + } else if !block_body.deposits().is_empty() { + return Err(BlockProcessingError::DepositReceiptError); } process_proposer_slashings( From c96d79d3f6de0ed54d953fb2917d35b2e1776b07 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Mon, 24 Apr 2023 11:41:57 +0200 Subject: [PATCH 31/52] add `upgrade_to_eip6110` --- consensus/state_processing/src/genesis.rs | 102 +++++++++++++++++----- 1 file changed, 79 insertions(+), 23 deletions(-) diff --git a/consensus/state_processing/src/genesis.rs b/consensus/state_processing/src/genesis.rs index 10b9577400b..bd592c9e082 100644 --- a/consensus/state_processing/src/genesis.rs +++ b/consensus/state_processing/src/genesis.rs @@ -3,6 +3,10 @@ use super::per_block_processing::{ }; use crate::common::DepositDataTree; use crate::per_block_processing::UNSET_DEPOSIT_RECEIPTS_START_INDEX; +use crate::upgrade::{ + upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_eip4844, + upgrade_to_eip6110, +}; use safe_arith::{ArithError, SafeArith}; use tree_hash::TreeHash; use types::DEPOSIT_TREE_DEPTH; @@ -51,29 +55,81 @@ pub fn initialize_beacon_state_from_eth1( // Add deposit_receipts_start_index field with the value UNSET_DEPOSIT_RECEIPTS_START_INDEX *state.deposit_receipts_start_index_mut()? = UNSET_DEPOSIT_RECEIPTS_START_INDEX; - // Initialize the execution payload header - if let Some(header) = execution_payload_header { - match state.latest_execution_payload_header_mut()? { - ExecutionPayloadHeaderRefMut::Merge(header_mut) => { - if let ExecutionPayloadHeader::Merge(header) = header { - *header_mut = header; - } - } - ExecutionPayloadHeaderRefMut::Capella(header_mut) => { - if let ExecutionPayloadHeader::Capella(header) = header { - *header_mut = header; - } - } - ExecutionPayloadHeaderRefMut::Eip4844(header_mut) => { - if let ExecutionPayloadHeader::Eip4844(header) = header { - *header_mut = header; - } - } - ExecutionPayloadHeaderRefMut::Eip6110(header_mut) => { - if let ExecutionPayloadHeader::Eip6110(header) = header { - *header_mut = header; - } - } + if spec + .altair_fork_epoch + .map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch()) + { + upgrade_to_altair(&mut state, spec)?; + + state.fork_mut().previous_version = spec.altair_fork_version; + } + + // Similarly, perform an upgrade to the merge if configured from genesis. + if spec + .bellatrix_fork_epoch + .map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch()) + { + // this will set state.latest_execution_payload_header = ExecutionPayloadHeaderMerge::default() + upgrade_to_bellatrix(&mut state, spec)?; + + // Remove intermediate Altair fork from `state.fork`. + state.fork_mut().previous_version = spec.bellatrix_fork_version; + + // Override latest execution payload header. + // See https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/bellatrix/beacon-chain.md#testing + if let Some(ExecutionPayloadHeader::Merge(ref header)) = execution_payload_header { + *state.latest_execution_payload_header_merge_mut()? = header.clone(); + } + } + + // Upgrade to capella if configured from genesis + if spec + .capella_fork_epoch + .map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch()) + { + upgrade_to_capella(&mut state, spec)?; + + // Remove intermediate Bellatrix fork from `state.fork`. + state.fork_mut().previous_version = spec.capella_fork_version; + + // Override latest execution payload header. + // See https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#testing + if let Some(ExecutionPayloadHeader::Capella(ref header)) = execution_payload_header { + *state.latest_execution_payload_header_capella_mut()? = header.clone(); + } + } + + // Upgrade to eip4844 if configured from genesis + if spec + .eip4844_fork_epoch + .map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch()) + { + upgrade_to_eip4844(&mut state, spec)?; + + // Remove intermediate Capella fork from `state.fork`. + state.fork_mut().previous_version = spec.eip4844_fork_version; + + // Override latest execution payload header. + // See https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/beacon-chain.md#testing + if let Some(ExecutionPayloadHeader::Eip4844(ref header)) = execution_payload_header { + *state.latest_execution_payload_header_eip4844_mut()? = header.clone(); + } + } + + // Upgrade to eip6110 if configured from genesis + if spec + .eip6110_fork_epoch + .map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch()) + { + upgrade_to_eip6110(&mut state, spec)?; + + // Remove intermediate Eip4844 fork from `state.fork`. + state.fork_mut().previous_version = spec.eip6110_fork_version; + + // Override latest execution payload header. + // See https://github.com/ethereum/consensus-specs/blob/dev/specs/_features/eip6110/beacon-chain.md#testing + if let Some(ExecutionPayloadHeader::Eip6110(header)) = execution_payload_header { + *state.latest_execution_payload_header_eip6110_mut()? = header; } } From e5343916e082e9d984393cc3a5532f3fac5e0341 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Mon, 1 May 2023 10:10:14 +0200 Subject: [PATCH 32/52] minor fix --- beacon_node/execution_layer/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 61430350fec..15ad7764c55 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -1709,6 +1709,7 @@ impl ExecutionLayer { ForkName::Merge => ExecutionPayloadMerge::default().into(), ForkName::Capella => ExecutionPayloadCapella::default().into(), ForkName::Eip4844 => ExecutionPayloadEip4844::default().into(), + ForkName::Eip6110 => ExecutionPayloadEip6110::default().into(), ForkName::Base | ForkName::Altair => { return Err(Error::InvalidForkForPayload); } From 8068c14528c8758a926d15a04ba706e3cde9ab1e Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Tue, 2 May 2023 13:06:43 +0200 Subject: [PATCH 33/52] fix `config.yaml` --- .../built_in_network_configs/eip4844/config.yaml | 4 ---- .../built_in_network_configs/gnosis/config.yaml | 3 --- .../built_in_network_configs/sepolia/config.yaml | 4 ---- 3 files changed, 11 deletions(-) diff --git a/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml b/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml index ecd9ad80cc8..f7334b6187c 100644 --- a/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml @@ -38,10 +38,6 @@ CAPELLA_FORK_EPOCH: 1 EIP4844_FORK_VERSION: 0x50484404 EIP4844_FORK_EPOCH: 5 -# EIP6110 -EIP6110_FORK_VERSION: 0x60484404 -EIP6110_FORK_EPOCH: 10 - # Time parameters # --------------------------------------------------------------- # 12 seconds diff --git a/common/eth2_network_config/built_in_network_configs/gnosis/config.yaml b/common/eth2_network_config/built_in_network_configs/gnosis/config.yaml index 0386babb800..6aa2c9590a5 100644 --- a/common/eth2_network_config/built_in_network_configs/gnosis/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/gnosis/config.yaml @@ -42,9 +42,6 @@ CAPELLA_FORK_EPOCH: 18446744073709551615 # Eip4844 EIP4844_FORK_VERSION: 0x04000064 EIP4844_FORK_EPOCH: 18446744073709551615 -# Eip6110 -EIP6110_FORK_VERSION: 0x05000064 -EIP6110_FORK_EPOCH: 18446744073709551615 # Sharding SHARDING_FORK_VERSION: 0x03000064 SHARDING_FORK_EPOCH: 18446744073709551615 diff --git a/common/eth2_network_config/built_in_network_configs/sepolia/config.yaml b/common/eth2_network_config/built_in_network_configs/sepolia/config.yaml index 95a2eaf0d28..4ba006ec945 100644 --- a/common/eth2_network_config/built_in_network_configs/sepolia/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/sepolia/config.yaml @@ -36,10 +36,6 @@ CAPELLA_FORK_EPOCH: 56832 EIP4844_FORK_VERSION: 0x03001020 EIP4844_FORK_EPOCH: 18446744073709551615 -# Eip6110 -EIP6110_FORK_VERSION: 0x04001020 -EIP6110_FORK_EPOCH: 18446744073709551615 - # Sharding SHARDING_FORK_VERSION: 0x04001020 SHARDING_FORK_EPOCH: 18446744073709551615 From 8cb5ce75ea9de307307687f7f54c528d8ed54d79 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Wed, 3 May 2023 10:46:13 +0200 Subject: [PATCH 34/52] add `$h:block` --- consensus/types/src/payload.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/consensus/types/src/payload.rs b/consensus/types/src/payload.rs index 5846ce5fb44..c28e61740dc 100644 --- a/consensus/types/src/payload.rs +++ b/consensus/types/src/payload.rs @@ -752,7 +752,8 @@ macro_rules! impl_exec_payload_common { $block_type_variant:ident, // Blinded | Full $is_default_with_empty_roots:block, $f:block, - $g:block) => { + $g:block, + $h:block) => { impl ExecPayload for $wrapper_type { fn block_type() -> BlockType { BlockType::$block_type_variant @@ -812,7 +813,8 @@ macro_rules! impl_exec_payload_common { } fn deposit_receipts(&self) -> Result, Error> { - todo!() + let h = $h; + h(self) } } @@ -851,6 +853,15 @@ macro_rules! impl_exec_payload_for_fork { wrapper_ref_type.withdrawals_root() }; c + }, + { + let c: for<'a> fn( + &'a $wrapper_type_header, + ) -> Result, Error> = |payload: &$wrapper_type_header| { + let wrapper_ref_type = BlindedPayloadRef::$fork_variant(&payload); + wrapper_ref_type.deposit_receipts() + }; + c } ); @@ -930,6 +941,14 @@ macro_rules! impl_exec_payload_for_fork { wrapper_ref_type.withdrawals_root() }; c + }, + { + let c: for<'a> fn(&'a $wrapper_type_full) -> Result, Error> = + |payload: &$wrapper_type_full| { + let wrapper_ref_type = FullPayloadRef::$fork_variant(&payload); + wrapper_ref_type.deposit_receipts() + }; + c } ); From 875d834ce923c42ed384c2a58260a68fad8a5f99 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Wed, 3 May 2023 11:33:16 +0200 Subject: [PATCH 35/52] add `deposit_receipts` to `ExecutionPayloadBodyV1` --- beacon_node/execution_layer/src/engine_api.rs | 7 ++++--- .../execution_layer/src/engine_api/json_structures.rs | 9 +++++++++ beacon_node/execution_layer/src/test_utils/handle_rpc.rs | 3 +++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index 1b18108c262..382d91da57a 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -17,9 +17,9 @@ use std::convert::TryFrom; use strum::IntoStaticStr; use superstruct::superstruct; pub use types::{ - Address, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadHeader, - ExecutionPayloadRef, FixedVector, ForkName, Hash256, Transactions, Uint256, VariableList, - Withdrawal, Withdrawals, + Address, DepositReceipt, DepositReceipts, EthSpec, ExecutionBlockHash, ExecutionPayload, + ExecutionPayloadHeader, ExecutionPayloadRef, FixedVector, ForkName, Hash256, Transactions, + Uint256, VariableList, Withdrawal, Withdrawals, }; use types::{ ExecutionPayloadCapella, ExecutionPayloadEip4844, ExecutionPayloadEip6110, @@ -469,6 +469,7 @@ impl GetPayloadResponse { pub struct ExecutionPayloadBodyV1 { pub transactions: Transactions, pub withdrawals: Option>, + pub deposit_receipts: Option>, } impl ExecutionPayloadBodyV1 { diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index 4e057a21779..7761a5747fd 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -694,6 +694,7 @@ pub struct JsonExecutionPayloadBodyV1 { #[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")] pub transactions: Transactions, pub withdrawals: Option>, + pub deposit_receipts: Option>, } impl From> for ExecutionPayloadBodyV1 { @@ -708,6 +709,14 @@ impl From> for ExecutionPayloadBodyV1< .collect::>(), ) }), + deposit_receipts: value.deposit_receipts.map(|json_receipts| { + DepositReceipts::::from( + json_receipts + .into_iter() + .map(Into::into) + .collect::>(), + ) + }), } } } diff --git a/beacon_node/execution_layer/src/test_utils/handle_rpc.rs b/beacon_node/execution_layer/src/test_utils/handle_rpc.rs index 9dcd03a60f4..77806b897af 100644 --- a/beacon_node/execution_layer/src/test_utils/handle_rpc.rs +++ b/beacon_node/execution_layer/src/test_utils/handle_rpc.rs @@ -569,6 +569,9 @@ pub async fn handle_rpc( .withdrawals() .ok() .map(|withdrawals| VariableList::from(withdrawals.clone())), + deposit_receipts: block.deposit_receipts().ok().map( + |deposit_receipts| VariableList::from(deposit_receipts.clone()), + ), })); } None => response.push(None), From b9ea79a739790b98f6a93b2f7f4d92c28d61f650 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Wed, 3 May 2023 13:03:05 +0200 Subject: [PATCH 36/52] fix `process_operations` --- .../src/per_block_processing/process_operations.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 0698558b498..558554ed6fb 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -53,6 +53,10 @@ pub fn process_operations>( process_deposits(state, block_body.deposits(), spec)?; process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?; + if let Ok(bls_to_execution_changes) = block_body.bls_to_execution_changes() { + process_bls_to_execution_changes(state, bls_to_execution_changes, verify_signatures, spec)?; + } + if let Ok(payload) = block_body.execution_payload() { if is_execution_enabled(state, block_body) { let deposit_receipts = payload.deposit_receipts()?; From a6782af3232fec08fef7dd5b500ee33639041293 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Thu, 4 May 2023 20:30:59 +0200 Subject: [PATCH 37/52] `deposit_receipts` -> `deposit_receipts_root` --- beacon_node/execution_layer/src/engine_api.rs | 31 +++- .../process_operations.rs | 2 + consensus/types/src/payload.rs | 138 +++++++----------- 3 files changed, 85 insertions(+), 86 deletions(-) diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index 382d91da57a..932b86b76d0 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -555,7 +555,36 @@ impl ExecutionPayloadBodyV1 { )) } } - ExecutionPayloadHeader::Eip6110(_) => todo!(), + ExecutionPayloadHeader::Eip6110(header) => { + if let (Some(withdrawals), Some(deposit_receipts)) = + (self.withdrawals, self.deposit_receipts) + { + Ok(ExecutionPayload::Eip6110(ExecutionPayloadEip6110 { + 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, + excess_data_gas: header.excess_data_gas, + block_hash: header.block_hash, + transactions: self.transactions, + withdrawals, + deposit_receipts, + })) + } else { + Err(format!( + "block {} is eip6110 but payload body doesn't have withdrawals and deposit_receipts", + header.block_hash + )) + } + } } } } diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 558554ed6fb..92237b4083b 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -57,6 +57,7 @@ pub fn process_operations>( process_bls_to_execution_changes(state, bls_to_execution_changes, verify_signatures, spec)?; } + /* if let Ok(payload) = block_body.execution_payload() { if is_execution_enabled(state, block_body) { let deposit_receipts = payload.deposit_receipts()?; @@ -65,6 +66,7 @@ pub fn process_operations>( } } } + */ Ok(()) } diff --git a/consensus/types/src/payload.rs b/consensus/types/src/payload.rs index c28e61740dc..6c948bb5b04 100644 --- a/consensus/types/src/payload.rs +++ b/consensus/types/src/payload.rs @@ -39,7 +39,7 @@ pub trait ExecPayload: Debug + Clone + PartialEq + Hash + TreeHash + fn transactions(&self) -> Option<&Transactions>; /// fork-specific fields fn withdrawals_root(&self) -> Result; - fn deposit_receipts(&self) -> Result, Error>; + fn deposit_receipts_root(&self) -> Result; /// Is this a default payload with 0x0 roots for transactions and withdrawals? fn is_default_with_zero_roots(&self) -> bool; @@ -268,6 +268,17 @@ impl ExecPayload for FullPayload { } } + fn deposit_receipts_root(&self) -> Result { + match self { + FullPayload::Merge(_) => Err(Error::IncorrectStateVariant), + FullPayload::Capella(_) => Err(Error::IncorrectStateVariant), + FullPayload::Eip4844(_) => Err(Error::IncorrectStateVariant), + FullPayload::Eip6110(ref inner) => { + Ok(inner.execution_payload.deposit_receipts.tree_hash_root()) + } + } + } + fn is_default_with_zero_roots<'a>(&'a self) -> bool { map_full_payload_ref!(&'a _, self.to_ref(), move |payload, cons| { cons(payload); @@ -279,24 +290,6 @@ impl ExecPayload for FullPayload { // For full payloads the empty/zero distinction does not exist. self.is_default_with_zero_roots() } - - fn deposit_receipts(&self) -> Result, Error> { - match self { - FullPayload::Merge(_) => { - // Return an "empty" or "default" value for the Merge variant - Ok(Vec::new().into()) - } - FullPayload::Capella(_) => { - // Return an "empty" or "default" value for the Capella variant - Ok(Vec::new().into()) - } - FullPayload::Eip4844(_) => { - // Return an "empty" or "default" value for the EIP-4844 variant - Ok(Vec::new().into()) - } - FullPayload::Eip6110(ref inner) => Ok(inner.execution_payload.deposit_receipts.clone()), - } - } } impl FullPayload { @@ -398,6 +391,17 @@ impl<'b, T: EthSpec> ExecPayload for FullPayloadRef<'b, T> { } } + fn deposit_receipts_root(&self) -> Result { + match self { + FullPayloadRef::Merge(_) => Err(Error::IncorrectStateVariant), + FullPayloadRef::Capella(_) => Err(Error::IncorrectStateVariant), + FullPayloadRef::Eip4844(_) => Err(Error::IncorrectStateVariant), + FullPayloadRef::Eip6110(inner) => { + Ok(inner.execution_payload.deposit_receipts.tree_hash_root()) + } + } + } + fn is_default_with_zero_roots<'a>(&'a self) -> bool { map_full_payload_ref!(&'a _, self, move |payload, cons| { cons(payload); @@ -409,24 +413,6 @@ impl<'b, T: EthSpec> ExecPayload for FullPayloadRef<'b, T> { // For full payloads the empty/zero distinction does not exist. self.is_default_with_zero_roots() } - - fn deposit_receipts(&self) -> Result, Error> { - match self { - FullPayloadRef::Merge(_) => { - // Return an "empty" or "default" value for the Merge variant - Ok(Vec::new().into()) - } - FullPayloadRef::Capella(_) => { - // Return an "empty" or "default" value for the Capella variant - Ok(Vec::new().into()) - } - FullPayloadRef::Eip4844(_) => { - // Return an "empty" or "default" value for the EIP-4844 variant - Ok(Vec::new().into()) - } - FullPayloadRef::Eip6110(inner) => Ok(inner.execution_payload.deposit_receipts.clone()), - } - } } impl AbstractExecPayload for FullPayload { @@ -595,6 +581,17 @@ impl ExecPayload for BlindedPayload { } } + fn deposit_receipts_root(&self) -> Result { + match self { + BlindedPayload::Merge(_) => Err(Error::IncorrectStateVariant), + BlindedPayload::Capella(_) => Err(Error::IncorrectStateVariant), + BlindedPayload::Eip4844(_) => Err(Error::IncorrectStateVariant), + BlindedPayload::Eip6110(ref inner) => { + Ok(inner.execution_payload_header.deposit_receipts_root) + } + } + } + fn is_default_with_zero_roots(&self) -> bool { self.to_ref().is_default_with_zero_roots() } @@ -606,24 +603,6 @@ impl ExecPayload for BlindedPayload { fn is_default_with_empty_roots(&self) -> bool { self.to_ref().is_default_with_empty_roots() } - - fn deposit_receipts(&self) -> Result, Error> { - match self { - BlindedPayload::Merge(_) => { - // Return an "empty" or "default" value for the Merge variant - Ok(Vec::new().into()) - } - BlindedPayload::Capella(_) => { - // Return an "empty" or "default" value for the Capella variant - Ok(Vec::new().into()) - } - BlindedPayload::Eip4844(_) => { - // Return an "empty" or "default" value for the EIP-4844 variant - Ok(Vec::new().into()) - } - BlindedPayload::Eip6110(ref inner) => Ok(inner.deposit_receipts()?), - } - } } impl<'b, T: EthSpec> ExecPayload for BlindedPayloadRef<'b, T> { @@ -706,6 +685,17 @@ impl<'b, T: EthSpec> ExecPayload for BlindedPayloadRef<'b, T> { } } + fn deposit_receipts_root(&self) -> Result { + match self { + BlindedPayloadRef::Merge(_) => Err(Error::IncorrectStateVariant), + BlindedPayloadRef::Capella(_) => Err(Error::IncorrectStateVariant), + BlindedPayloadRef::Eip4844(_) => Err(Error::IncorrectStateVariant), + BlindedPayloadRef::Eip6110(inner) => { + Ok(inner.execution_payload_header.deposit_receipts_root) + } + } + } + fn is_default_with_zero_roots<'a>(&'a self) -> bool { map_blinded_payload_ref!(&'b _, self, move |payload, cons| { cons(payload); @@ -719,27 +709,6 @@ impl<'b, T: EthSpec> ExecPayload for BlindedPayloadRef<'b, T> { payload.is_default_with_empty_roots() }) } - - fn deposit_receipts(&self) -> Result, Error> { - match self { - BlindedPayloadRef::Merge(_) => { - // Return an "empty" or "default" value for the Merge variant - Ok(Vec::new().into()) - } - BlindedPayloadRef::Capella(_) => { - // Return an "empty" or "default" value for the Capella variant - Ok(Vec::new().into()) - } - BlindedPayloadRef::Eip4844(_) => { - // Return an "empty" or "default" value for the Eip4844 variant - Ok(Vec::new().into()) - } - BlindedPayloadRef::Eip6110(_) => { - // Return an "empty" or "default" value for the Eip6110 variant - Ok(Vec::new().into()) - } - } - } } macro_rules! impl_exec_payload_common { @@ -812,7 +781,7 @@ macro_rules! impl_exec_payload_common { g(self) } - fn deposit_receipts(&self) -> Result, Error> { + fn deposit_receipts_root(&self) -> Result { let h = $h; h(self) } @@ -855,12 +824,11 @@ macro_rules! impl_exec_payload_for_fork { c }, { - let c: for<'a> fn( - &'a $wrapper_type_header, - ) -> Result, Error> = |payload: &$wrapper_type_header| { - let wrapper_ref_type = BlindedPayloadRef::$fork_variant(&payload); - wrapper_ref_type.deposit_receipts() - }; + let c: for<'a> fn(&'a $wrapper_type_header) -> Result = + |payload: &$wrapper_type_header| { + let wrapper_ref_type = BlindedPayloadRef::$fork_variant(&payload); + wrapper_ref_type.deposit_receipts_root() + }; c } ); @@ -943,10 +911,10 @@ macro_rules! impl_exec_payload_for_fork { c }, { - let c: for<'a> fn(&'a $wrapper_type_full) -> Result, Error> = + let c: for<'a> fn(&'a $wrapper_type_full) -> Result = |payload: &$wrapper_type_full| { let wrapper_ref_type = FullPayloadRef::$fork_variant(&payload); - wrapper_ref_type.deposit_receipts() + wrapper_ref_type.deposit_receipts_root() }; c } From b451305ed1f2c80859a81a3887f40f952bb60102 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Mon, 8 May 2023 10:44:06 +0200 Subject: [PATCH 38/52] `deposit_receipts_root` -> `deposit_receipts` --- .../process_operations.rs | 2 - .../types/src/execution_payload_header.rs | 6 +-- consensus/types/src/payload.rs | 39 +++++++++---------- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 92237b4083b..558554ed6fb 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -57,7 +57,6 @@ pub fn process_operations>( process_bls_to_execution_changes(state, bls_to_execution_changes, verify_signatures, spec)?; } - /* if let Ok(payload) = block_body.execution_payload() { if is_execution_enabled(state, block_body) { let deposit_receipts = payload.deposit_receipts()?; @@ -66,7 +65,6 @@ pub fn process_operations>( } } } - */ Ok(()) } diff --git a/consensus/types/src/execution_payload_header.rs b/consensus/types/src/execution_payload_header.rs index dd7b879fb8b..14a8f28d03b 100644 --- a/consensus/types/src/execution_payload_header.rs +++ b/consensus/types/src/execution_payload_header.rs @@ -83,7 +83,7 @@ pub struct ExecutionPayloadHeader { pub withdrawals_root: Hash256, #[superstruct(only(Eip6110))] #[superstruct(getter(copy))] - pub deposit_receipts_root: Hash256, + pub deposit_receipts: DepositReceipts, } impl ExecutionPayloadHeader { @@ -184,7 +184,7 @@ impl ExecutionPayloadHeaderEip4844 { block_hash: self.block_hash, transactions_root: self.transactions_root, withdrawals_root: self.withdrawals_root, - deposit_receipts_root: Hash256::zero(), + deposit_receipts: DepositReceipts::::default(), } } } @@ -273,7 +273,7 @@ impl<'a, T: EthSpec> From<&'a ExecutionPayloadEip6110> for ExecutionPayloadHe block_hash: payload.block_hash, transactions_root: payload.transactions.tree_hash_root(), withdrawals_root: payload.withdrawals.tree_hash_root(), - deposit_receipts_root: payload.deposit_receipts.tree_hash_root(), + deposit_receipts: payload.deposit_receipts.clone(), } } } diff --git a/consensus/types/src/payload.rs b/consensus/types/src/payload.rs index 6c948bb5b04..c1f31cb6155 100644 --- a/consensus/types/src/payload.rs +++ b/consensus/types/src/payload.rs @@ -39,7 +39,7 @@ pub trait ExecPayload: Debug + Clone + PartialEq + Hash + TreeHash + fn transactions(&self) -> Option<&Transactions>; /// fork-specific fields fn withdrawals_root(&self) -> Result; - fn deposit_receipts_root(&self) -> Result; + fn deposit_receipts(&self) -> Result, Error>; /// Is this a default payload with 0x0 roots for transactions and withdrawals? fn is_default_with_zero_roots(&self) -> bool; @@ -268,14 +268,12 @@ impl ExecPayload for FullPayload { } } - fn deposit_receipts_root(&self) -> Result { + fn deposit_receipts(&self) -> Result, Error> { match self { FullPayload::Merge(_) => Err(Error::IncorrectStateVariant), FullPayload::Capella(_) => Err(Error::IncorrectStateVariant), FullPayload::Eip4844(_) => Err(Error::IncorrectStateVariant), - FullPayload::Eip6110(ref inner) => { - Ok(inner.execution_payload.deposit_receipts.tree_hash_root()) - } + FullPayload::Eip6110(ref inner) => Ok(inner.execution_payload.deposit_receipts.clone()), } } @@ -391,14 +389,12 @@ impl<'b, T: EthSpec> ExecPayload for FullPayloadRef<'b, T> { } } - fn deposit_receipts_root(&self) -> Result { + fn deposit_receipts(&self) -> Result, Error> { match self { FullPayloadRef::Merge(_) => Err(Error::IncorrectStateVariant), FullPayloadRef::Capella(_) => Err(Error::IncorrectStateVariant), FullPayloadRef::Eip4844(_) => Err(Error::IncorrectStateVariant), - FullPayloadRef::Eip6110(inner) => { - Ok(inner.execution_payload.deposit_receipts.tree_hash_root()) - } + FullPayloadRef::Eip6110(inner) => Ok(inner.execution_payload.deposit_receipts.clone()), } } @@ -581,13 +577,13 @@ impl ExecPayload for BlindedPayload { } } - fn deposit_receipts_root(&self) -> Result { + fn deposit_receipts(&self) -> Result, Error> { match self { BlindedPayload::Merge(_) => Err(Error::IncorrectStateVariant), BlindedPayload::Capella(_) => Err(Error::IncorrectStateVariant), BlindedPayload::Eip4844(_) => Err(Error::IncorrectStateVariant), BlindedPayload::Eip6110(ref inner) => { - Ok(inner.execution_payload_header.deposit_receipts_root) + Ok(inner.execution_payload_header.deposit_receipts.clone()) } } } @@ -685,13 +681,13 @@ impl<'b, T: EthSpec> ExecPayload for BlindedPayloadRef<'b, T> { } } - fn deposit_receipts_root(&self) -> Result { + fn deposit_receipts(&self) -> Result, Error> { match self { BlindedPayloadRef::Merge(_) => Err(Error::IncorrectStateVariant), BlindedPayloadRef::Capella(_) => Err(Error::IncorrectStateVariant), BlindedPayloadRef::Eip4844(_) => Err(Error::IncorrectStateVariant), BlindedPayloadRef::Eip6110(inner) => { - Ok(inner.execution_payload_header.deposit_receipts_root) + Ok(inner.execution_payload_header.deposit_receipts.clone()) } } } @@ -781,7 +777,7 @@ macro_rules! impl_exec_payload_common { g(self) } - fn deposit_receipts_root(&self) -> Result { + fn deposit_receipts(&self) -> Result, Error> { let h = $h; h(self) } @@ -824,11 +820,12 @@ macro_rules! impl_exec_payload_for_fork { c }, { - let c: for<'a> fn(&'a $wrapper_type_header) -> Result = - |payload: &$wrapper_type_header| { - let wrapper_ref_type = BlindedPayloadRef::$fork_variant(&payload); - wrapper_ref_type.deposit_receipts_root() - }; + let c: for<'a> fn( + &'a $wrapper_type_header, + ) -> Result, Error> = |payload: &$wrapper_type_header| { + let wrapper_ref_type = BlindedPayloadRef::$fork_variant(&payload); + wrapper_ref_type.deposit_receipts() + }; c } ); @@ -911,10 +908,10 @@ macro_rules! impl_exec_payload_for_fork { c }, { - let c: for<'a> fn(&'a $wrapper_type_full) -> Result = + let c: for<'a> fn(&'a $wrapper_type_full) -> Result, Error> = |payload: &$wrapper_type_full| { let wrapper_ref_type = FullPayloadRef::$fork_variant(&payload); - wrapper_ref_type.deposit_receipts_root() + wrapper_ref_type.deposit_receipts() }; c } From 8f3e8f50f83329b7249051806594dcd4cc5ba23d Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Mon, 15 May 2023 09:54:48 +0200 Subject: [PATCH 39/52] minor fixes --- .../process_operations.rs | 22 +++++++++---------- .../ef_tests/src/cases/epoch_processing.rs | 6 +---- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 558554ed6fb..a13131c11c4 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -16,22 +16,20 @@ pub fn process_operations>( ctxt: &mut ConsensusContext, spec: &ChainSpec, ) -> Result<(), BlockProcessingError> { - let unprocessed_deposits_count = state - .eth1_data() - .deposit_count - .saturating_sub(state.eth1_deposit_index()); - let max_deposits = ::MaxDeposits::to_u64(); let eth1_deposit_index_limit = state .deposit_receipts_start_index() .unwrap_or_else(|_| state.eth1_data().deposit_count); - if state.eth1_deposit_index() < eth1_deposit_index_limit { - if block_body.deposits().len() - != std::cmp::min(max_deposits as usize, unprocessed_deposits_count as usize) - { - return Err(BlockProcessingError::DepositReceiptError); - } - } else if !block_body.deposits().is_empty() { + let expected_deposit_count = if state.eth1_deposit_index() < eth1_deposit_index_limit { + std::cmp::min( + ::MaxDeposits::to_u64() as usize, + (eth1_deposit_index_limit - state.eth1_deposit_index()) as usize, + ) as u64 + } else { + 0 + }; + + if block_body.deposits().len() as u64 != expected_deposit_count { return Err(BlockProcessingError::DepositReceiptError); } diff --git a/testing/ef_tests/src/cases/epoch_processing.rs b/testing/ef_tests/src/cases/epoch_processing.rs index adbb890af08..34c192063ad 100644 --- a/testing/ef_tests/src/cases/epoch_processing.rs +++ b/testing/ef_tests/src/cases/epoch_processing.rs @@ -320,11 +320,7 @@ impl> Case for EpochProcessing { T::name() != "participation_record_updates" && T::name() != "historical_summaries_update" } - ForkName::Capella | ForkName::Eip4844 => { - T::name() != "participation_record_updates" - && T::name() != "historical_roots_update" - } - ForkName::Eip6110 => { + ForkName::Capella | ForkName::Eip4844 | ForkName::Eip6110 => { T::name() != "participation_record_updates" && T::name() != "historical_roots_update" } From 6495fc1171276aaf9c068132d356c0c2dfa4cc83 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Thu, 18 May 2023 15:40:41 +0200 Subject: [PATCH 40/52] Merge deneb-free-blobs into eip6110-deneb --- beacon_node/beacon_chain/src/beacon_chain.rs | 3 +- beacon_node/beacon_chain/src/test_utils.rs | 2 +- beacon_node/execution_layer/src/engine_api.rs | 22 ++-- .../execution_layer/src/engine_api/http.rs | 102 ++++++++++-------- .../src/engine_api/json_structures.rs | 12 +-- beacon_node/execution_layer/src/lib.rs | 31 +----- .../test_utils/execution_block_generator.rs | 7 +- .../src/test_utils/handle_rpc.rs | 18 ++++ .../src/test_utils/mock_builder.rs | 12 +-- .../src/test_utils/mock_execution_layer.rs | 2 - .../execution_layer/src/test_utils/mod.rs | 4 +- .../http_api/src/build_block_contents.rs | 2 +- beacon_node/http_api/src/publish_blocks.rs | 2 +- .../src/rpc/codec/ssz_snappy.rs | 4 +- .../lighthouse_network/src/types/pubsub.rs | 11 +- .../store/src/impls/execution_payload.rs | 2 +- common/eth2/src/types.rs | 3 +- consensus/state_processing/src/genesis.rs | 4 +- .../state_processing/src/upgrade/eip6110.rs | 2 +- consensus/types/src/beacon_block.rs | 7 +- consensus/types/src/beacon_block_body.rs | 5 +- consensus/types/src/beacon_state.rs | 6 +- .../types/src/execution_payload_header.rs | 6 +- consensus/types/src/fork_name.rs | 2 +- consensus/types/src/lib.rs | 11 +- consensus/types/src/payload.rs | 14 +-- consensus/types/src/signed_beacon_block.rs | 3 + lcli/src/parse_ssz.rs | 2 +- testing/ef_tests/src/cases/operations.rs | 3 +- testing/ef_tests/src/cases/transition.rs | 2 +- 30 files changed, 162 insertions(+), 144 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 8e56c834b5a..bb7677dd302 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -4861,7 +4861,7 @@ impl BeaconChain { ) } BeaconState::Eip6110(_) => { - let (payload, kzg_commitments, blobs) = block_contents + let (payload, kzg_commitments, blobs, proofs) = block_contents .ok_or(BlockProductionError::MissingExecutionPayload)? .deconstruct(); ( @@ -4890,6 +4890,7 @@ impl BeaconChain { }, }), blobs, + proofs, ) } }; diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index 22c50156a3c..9d740634000 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -824,7 +824,7 @@ where | SignedBeaconBlock::Altair(_) | SignedBeaconBlock::Merge(_) | SignedBeaconBlock::Capella(_) => (signed_block, None), - SignedBeaconBlock::Deneb(_) => { + SignedBeaconBlock::Deneb(_) | SignedBeaconBlock::Eip6110(_) => { if let Some(blobs) = self .chain .proposal_blob_cache diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index 6dfa67fe688..aabe29c4827 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -24,10 +24,9 @@ pub use types::{ Uint256, VariableList, Withdrawal, Withdrawals, }; use types::{ - ExecutionPayloadCapella, ExecutionPayloadEip4844, ExecutionPayloadEip6110, - ExecutionPayloadMerge, + ExecutionPayloadCapella, ExecutionPayloadDeneb, ExecutionPayloadEip6110, ExecutionPayloadMerge, + KzgProofs, }; -use types::{ExecutionPayloadCapella, ExecutionPayloadDeneb, ExecutionPayloadMerge, KzgProofs}; pub mod auth; pub mod http; @@ -191,7 +190,7 @@ pub struct ExecutionBlockWithTransactions { #[serde(rename = "hash")] pub block_hash: ExecutionBlockHash, pub transactions: Vec, - #[superstruct(only(Capella, Deneb))] + #[superstruct(only(Capella, Deneb, Eip6110))] pub withdrawals: Vec, #[superstruct(only(Eip6110))] pub deposit_receipts: Vec, @@ -264,19 +263,18 @@ impl TryFrom> for ExecutionBlockWithTransactions timestamp: block.timestamp, extra_data: block.extra_data, base_fee_per_gas: block.base_fee_per_gas, + excess_data_gas: block.excess_data_gas, block_hash: block.block_hash, transactions: block - .transactions - .iter() - .map(|tx| Transaction::decode(&Rlp::new(tx))) + .transactions + .iter() + .map(|tx| Transaction::decode(&Rlp::new(tx))) .collect::, _>>()?, withdrawals: Vec::from(block.withdrawals) .into_iter() .map(|withdrawal| withdrawal.into()) .collect(), - excess_data_gas: block.excess_data_gas, - }) - } + }), ExecutionPayload::Eip6110(block) => { Self::Eip6110(ExecutionBlockWithTransactionsEip6110 { parent_hash: block.parent_hash, @@ -308,6 +306,7 @@ impl TryFrom> for ExecutionBlockWithTransactions .collect(), }) } + }; Ok(json_payload) } } @@ -419,7 +418,7 @@ pub struct GetPayloadResponse { #[superstruct(only(Eip6110), partial_getter(rename = "execution_payload_eip6110"))] pub execution_payload: ExecutionPayloadEip6110, pub block_value: Uint256, - #[superstruct(only(Deneb))] + #[superstruct(only(Deneb, Eip6110))] pub blobs_bundle: BlobsBundleV1, } @@ -462,6 +461,7 @@ impl From> GetPayloadResponse::Eip6110(inner) => ( ExecutionPayload::Eip6110(inner.execution_payload), inner.block_value, + Some(inner.blobs_bundle), ), } } diff --git a/beacon_node/execution_layer/src/engine_api/http.rs b/beacon_node/execution_layer/src/engine_api/http.rs index 8c99a37ccaa..d3b37a96871 100644 --- a/beacon_node/execution_layer/src/engine_api/http.rs +++ b/beacon_node/execution_layer/src/engine_api/http.rs @@ -834,23 +834,6 @@ impl HttpJsonRpc { Ok(response.into()) } - pub async fn new_payload_v6110( - &self, - execution_payload: ExecutionPayload, - ) -> Result { - let params = json!([JsonExecutionPayload::from(execution_payload)]); - - let response: JsonPayloadStatusV1 = self - .rpc_request( - ENGINE_NEW_PAYLOAD_V6110, - params, - ENGINE_NEW_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, - ) - .await?; - - Ok(response.into()) - } - pub async fn get_payload_v1( &self, payload_id: PayloadId, @@ -946,7 +929,16 @@ impl HttpJsonRpc { .await?; Ok(JsonGetPayloadResponse::V3(response).into()) } - ForkName::Eip6110 => self.get_payload_v6110(payload_id).await, + ForkName::Eip6110 => { + let response: JsonGetPayloadResponseV6110 = self + .rpc_request( + ENGINE_GET_PAYLOAD_V6110, + params, + ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, + ) + .await?; + Ok(JsonGetPayloadResponse::V6110(response).into()) + } ForkName::Base | ForkName::Altair => Err(Error::UnsupportedForkVariant(format!( "called get_payload_v3 with {}", fork_name @@ -956,35 +948,57 @@ impl HttpJsonRpc { pub async fn get_payload_v6110( &self, + fork_name: ForkName, payload_id: PayloadId, ) -> Result, Error> { let params = json!([JsonPayloadIdRequest::from(payload_id)]); - let response: JsonGetPayloadResponseV6110 = self - .rpc_request( - ENGINE_GET_PAYLOAD_V6110, - params, - ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, - ) - .await?; - - Ok(JsonGetPayloadResponse::V6110(response).into()) - } - - pub async fn get_blobs_bundle_v1( - &self, - payload_id: PayloadId, - ) -> Result, Error> { - let params = json!([JsonPayloadIdRequest::from(payload_id)]); - - let response: JsonBlobsBundle = self - .rpc_request( - ENGINE_GET_BLOBS_BUNDLE_V1, - ENGINE_GET_BLOBS_BUNDLE_TIMEOUT, - ) - .await?; - - Ok(response) + match fork_name { + ForkName::Merge => { + let response: JsonGetPayloadResponseV1 = self + .rpc_request( + ENGINE_GET_PAYLOAD_V2, + params, + ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, + ) + .await?; + Ok(JsonGetPayloadResponse::V1(response).into()) + } + ForkName::Capella => { + let response: JsonGetPayloadResponseV2 = self + .rpc_request( + ENGINE_GET_PAYLOAD_V2, + params, + ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, + ) + .await?; + Ok(JsonGetPayloadResponse::V2(response).into()) + } + ForkName::Deneb => { + let response: JsonGetPayloadResponseV3 = self + .rpc_request( + ENGINE_GET_PAYLOAD_V3, + params, + ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, + ) + .await?; + Ok(JsonGetPayloadResponse::V3(response).into()) + } + ForkName::Eip6110 => { + let response: JsonGetPayloadResponseV6110 = self + .rpc_request( + ENGINE_GET_PAYLOAD_V6110, + params, + ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, + ) + .await?; + Ok(JsonGetPayloadResponse::V6110(response).into()) + } + ForkName::Base | ForkName::Altair => Err(Error::UnsupportedForkVariant(format!( + "called get_payload_v6110 with {}", + fork_name + ))), + } } pub async fn forkchoice_updated_v1( @@ -1012,6 +1026,8 @@ impl HttpJsonRpc { &self, forkchoice_state: ForkchoiceState, payload_attributes: Option, + ) -> Result { + let params = json!([ JsonForkchoiceStateV1::from(forkchoice_state), payload_attributes.map(JsonPayloadAttributes::from) ]); diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index d3cd4ffb205..2753bd4d269 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -7,9 +7,9 @@ use superstruct::superstruct; use types::beacon_block_body::KzgCommitments; use types::blob_sidecar::Blobs; use types::{ - Blobs, DepositReceipt, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadCapella, - ExecutionPayloadDeneb, ExecutionPayloadEip6110, ExecutionPayloadMerge, FixedVector, - Transaction, Transactions, Unsigned, VariableList, Withdrawal, + EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadCapella, ExecutionPayloadDeneb, + ExecutionPayloadEip6110, ExecutionPayloadMerge, FixedVector, Transactions, Unsigned, + VariableList, Withdrawal, }; #[derive(Debug, PartialEq, Serialize, Deserialize)] @@ -98,8 +98,7 @@ pub struct JsonExecutionPayload { pub base_fee_per_gas: Uint256, pub block_hash: ExecutionBlockHash, #[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")] - pub transactions: - VariableList, T::MaxTransactionsPerPayload>, + pub transactions: Transactions, #[superstruct(only(V2, V3, V6110))] pub withdrawals: VariableList, #[superstruct(only(V6110))] @@ -367,7 +366,7 @@ pub struct JsonGetPayloadResponse { pub execution_payload: JsonExecutionPayloadV6110, #[serde(with = "eth2_serde_utils::u256_hex_be")] pub block_value: Uint256, - #[superstruct(only(V3))] + #[superstruct(only(V3, V6110))] pub blobs_bundle: JsonBlobsBundleV1, } @@ -397,6 +396,7 @@ impl From> for GetPayloadResponse { GetPayloadResponse::Eip6110(GetPayloadResponseEip6110 { execution_payload: response.execution_payload.into(), block_value: response.block_value, + blobs_bundle: response.blobs_bundle.into(), }) } } diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 9e16b7566a8..804f3586493 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -45,17 +45,11 @@ use types::beacon_block_body::KzgCommitments; use types::blob_sidecar::Blobs; use types::consts::deneb::BLOB_TX_TYPE; use types::transaction::{AccessTuple, BlobTransaction, EcdsaSignature, SignedBlobTransaction}; -use types::Withdrawals; -use types::{ - blobs_sidecar::{Blobs, KzgCommitments}, - BlindedPayload, BlockType, ChainSpec, Epoch, ExecutionBlockHash, ExecutionPayload, - ExecutionPayloadCapella, ExecutionPayloadDeneb, ExecutionPayloadEip6110, - ExecutionPayloadMerge, ForkName, -}; use types::{AbstractExecPayload, BeaconStateError, ExecPayload, VersionedHash}; use types::{ BlindedPayload, BlockType, ChainSpec, Epoch, ExecutionBlockHash, ExecutionPayload, - ExecutionPayloadCapella, ExecutionPayloadDeneb, ExecutionPayloadMerge, ForkName, + ExecutionPayloadCapella, ExecutionPayloadDeneb, ExecutionPayloadEip6110, ExecutionPayloadMerge, + ForkName, }; use types::{KzgProofs, Withdrawals}; use types::{ @@ -263,6 +257,7 @@ impl> BlockProposalContents ExecutionLayer { } }; - let blob_fut = async { - match current_fork { - ForkName::Base | ForkName::Altair | ForkName::Merge | ForkName::Capella => { - None - } - ForkName::Deneb | ForkName::Eip6110 => { - debug!( - self.log(), - "Issuing engine_getBlobsBundle"; - "suggested_fee_recipient" => ?payload_attributes.suggested_fee_recipient(), - "prev_randao" => ?payload_attributes.prev_randao(), - "timestamp" => payload_attributes.timestamp(), - "parent_hash" => ?parent_hash, - ); - Some(engine.api.get_blobs_bundle_v1::(payload_id).await) - } - } - }; - let payload_fut = async { + let payload_response = async { debug!( self.log(), "Issuing engine_getPayload"; diff --git a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs index d848a8fa461..e225c483b14 100644 --- a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs +++ b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs @@ -19,9 +19,9 @@ use tree_hash_derive::TreeHash; use types::consts::deneb::BLOB_TX_TYPE; use types::transaction::{BlobTransaction, EcdsaSignature, SignedBlobTransaction}; use types::{ - EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadCapella, + Blob, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadCapella, ExecutionPayloadDeneb, ExecutionPayloadEip6110, ExecutionPayloadMerge, ForkName, Hash256, - Uint256, + Transaction, Transactions, Uint256, }; const GAS_LIMIT: u64 = 16384; @@ -611,7 +611,7 @@ impl ExecutionBlockGenerator { match execution_payload.fork_name() { ForkName::Base | ForkName::Altair | ForkName::Merge | ForkName::Capella => {} - ForkName::Deneb => { + ForkName::Deneb | ForkName::Eip6110 => { // get random number between 0 and Max Blobs let num_blobs = rand::random::() % T::max_blobs_per_block(); let (bundle, transactions) = self.generate_random_blobs(num_blobs)?; @@ -797,6 +797,7 @@ mod test { None, None, None, + None, ); for i in 0..=TERMINAL_BLOCK { diff --git a/beacon_node/execution_layer/src/test_utils/handle_rpc.rs b/beacon_node/execution_layer/src/test_utils/handle_rpc.rs index 7f4922fecad..992fd104ebd 100644 --- a/beacon_node/execution_layer/src/test_utils/handle_rpc.rs +++ b/beacon_node/execution_layer/src/test_utils/handle_rpc.rs @@ -362,6 +362,12 @@ pub async fn handle_rpc( serde_json::to_value(JsonGetPayloadResponseV6110 { execution_payload, block_value: DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI.into(), + blobs_bundle: maybe_blobs + .ok_or(( + "No blobs returned despite V6110 Payload".to_string(), + GENERIC_ERROR_CODE, + ))? + .into(), }) .unwrap() } @@ -385,6 +391,12 @@ pub async fn handle_rpc( serde_json::to_value(JsonGetPayloadResponseV3 { execution_payload, block_value: DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI.into(), + blobs_bundle: maybe_blobs + .ok_or(( + "No blobs returned despite V3 Payload".to_string(), + GENERIC_ERROR_CODE, + ))? + .into(), }) .unwrap() } @@ -392,6 +404,12 @@ pub async fn handle_rpc( serde_json::to_value(JsonGetPayloadResponseV6110 { execution_payload, block_value: DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI.into(), + blobs_bundle: maybe_blobs + .ok_or(( + "No blobs returned despite V6110 Payload".to_string(), + GENERIC_ERROR_CODE, + ))? + .into(), }) .unwrap() } diff --git a/beacon_node/execution_layer/src/test_utils/mock_builder.rs b/beacon_node/execution_layer/src/test_utils/mock_builder.rs index 1238bc4d050..e9fa3cdb7cc 100644 --- a/beacon_node/execution_layer/src/test_utils/mock_builder.rs +++ b/beacon_node/execution_layer/src/test_utils/mock_builder.rs @@ -442,13 +442,11 @@ impl mev_rs::BlindedBlockProvider for MockBuilder { let json_payload = serde_json::to_string(&payload).map_err(convert_err)?; let mut message = match fork { - ForkName::Capella | ForkName::Eip4844 | ForkName::Eip6110 => { - BuilderBid::Capella(BuilderBidCapella { - header: serde_json::from_str(json_payload.as_str()).map_err(convert_err)?, - value: to_ssz_rs(&Uint256::from(DEFAULT_BUILDER_PAYLOAD_VALUE_WEI))?, - public_key: self.builder_sk.public_key(), - }) - } + ForkName::Capella => BuilderBid::Capella(BuilderBidCapella { + header: serde_json::from_str(json_payload.as_str()).map_err(convert_err)?, + value: to_ssz_rs(&Uint256::from(DEFAULT_BUILDER_PAYLOAD_VALUE_WEI))?, + public_key: self.builder_sk.public_key(), + }), ForkName::Merge => BuilderBid::Bellatrix(BuilderBidBellatrix { header: serde_json::from_str(json_payload.as_str()).map_err(convert_err)?, value: to_ssz_rs(&Uint256::from(DEFAULT_BUILDER_PAYLOAD_VALUE_WEI))?, diff --git a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs index 023f8a2b8ef..571e466ba41 100644 --- a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs +++ b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs @@ -44,7 +44,6 @@ impl MockExecutionLayer { executor: TaskExecutor, terminal_block: u64, shanghai_time: Option, -<<<<<<< HEAD deneb_time: Option, eip6110_time: Option, builder_threshold: Option, @@ -64,7 +63,6 @@ impl MockExecutionLayer { spec.terminal_block_hash, shanghai_time, deneb_time, - deneb_time, eip6110_time, kzg, ); diff --git a/beacon_node/execution_layer/src/test_utils/mod.rs b/beacon_node/execution_layer/src/test_utils/mod.rs index e6b0a24e76d..3b25a7fd091 100644 --- a/beacon_node/execution_layer/src/test_utils/mod.rs +++ b/beacon_node/execution_layer/src/test_utils/mod.rs @@ -102,6 +102,7 @@ impl MockServer { None, // FIXME(capella): should this be the default? None, // FIXME(deneb): should this be the default? None, // FIXME(eip6110): should this be the default? + None, // FIXME(deneb): should this be the default? ) } @@ -129,6 +130,7 @@ impl MockServer { shanghai_time, deneb_time, eip6110_time, + kzg, ); let ctx: Arc> = Arc::new(Context { @@ -189,8 +191,8 @@ impl MockServer { terminal_block_hash: ExecutionBlockHash, shanghai_time: Option, deneb_time: Option, - kzg: Option, eip6110_time: Option, + kzg: Option, ) -> Self { Self::new_with_config( handle, diff --git a/beacon_node/http_api/src/build_block_contents.rs b/beacon_node/http_api/src/build_block_contents.rs index d6c5ada0071..69f3c282d50 100644 --- a/beacon_node/http_api/src/build_block_contents.rs +++ b/beacon_node/http_api/src/build_block_contents.rs @@ -14,7 +14,7 @@ pub fn build_block_contents { Ok(BlockContents::Block(block)) } - ForkName::Deneb => { + ForkName::Deneb | ForkName::Eip6110 => { let block_root = &block.canonical_root(); if let Some(blob_sidecars) = chain.proposal_blob_cache.pop(block_root) { let block_and_blobs = BeaconBlockAndBlobSidecars { diff --git a/beacon_node/http_api/src/publish_blocks.rs b/beacon_node/http_api/src/publish_blocks.rs index d722cf6c9b7..a58dd54931a 100644 --- a/beacon_node/http_api/src/publish_blocks.rs +++ b/beacon_node/http_api/src/publish_blocks.rs @@ -68,7 +68,7 @@ pub async fn publish_block( crate::publish_pubsub_message(network_tx, PubsubMessage::BeaconBlock(block.clone()))?; block.into() } - SignedBeaconBlock::Deneb(_) => { + SignedBeaconBlock::Deneb(_) | SignedBeaconBlock::Eip6110(_) => { crate::publish_pubsub_message(network_tx, PubsubMessage::BeaconBlock(block.clone()))?; if let Some(signed_blobs) = maybe_blobs { for (blob_index, blob) in signed_blobs.clone().into_iter().enumerate() { diff --git a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs index 7fbfadd5544..f4e8f486a7a 100644 --- a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs +++ b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs @@ -18,8 +18,8 @@ use tokio_util::codec::{Decoder, Encoder}; use types::{light_client_bootstrap::LightClientBootstrap, BlobSidecar}; use types::{ EthSpec, ForkContext, ForkName, Hash256, SignedBeaconBlock, SignedBeaconBlockAltair, - SignedBeaconBlockBase, SignedBeaconBlockCapella, SignedBeaconBlockDeneb, SignedBeaconBlockEip6110, - SignedBeaconBlockMerge, + SignedBeaconBlockBase, SignedBeaconBlockCapella, SignedBeaconBlockDeneb, + SignedBeaconBlockEip6110, SignedBeaconBlockMerge, }; use unsigned_varint::codec::Uvi; diff --git a/beacon_node/lighthouse_network/src/types/pubsub.rs b/beacon_node/lighthouse_network/src/types/pubsub.rs index eb99e6b91ea..b9b11385a7b 100644 --- a/beacon_node/lighthouse_network/src/types/pubsub.rs +++ b/beacon_node/lighthouse_network/src/types/pubsub.rs @@ -12,8 +12,9 @@ use types::{ Attestation, AttesterSlashing, EthSpec, ForkContext, ForkName, LightClientFinalityUpdate, LightClientOptimisticUpdate, ProposerSlashing, SignedAggregateAndProof, SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockBase, SignedBeaconBlockCapella, - SignedBeaconBlockDeneb, SignedBeaconBlockMerge, SignedBlobSidecar, SignedBlsToExecutionChange, - SignedContributionAndProof, SignedVoluntaryExit, SubnetId, SyncCommitteeMessage, SyncSubnetId, + SignedBeaconBlockDeneb, SignedBeaconBlockEip6110, SignedBeaconBlockMerge, SignedBlobSidecar, + SignedBlsToExecutionChange, SignedContributionAndProof, SignedVoluntaryExit, SubnetId, + SyncCommitteeMessage, SyncSubnetId, }; #[derive(Debug, Clone, PartialEq)] @@ -186,15 +187,15 @@ impl PubsubMessage { ), Some(ForkName::Capella) => SignedBeaconBlock::::Capella( SignedBeaconBlockCapella::from_ssz_bytes(data) - .map_err(|e| format!("{:?}", e))?, + .map_err(|e| format!("{:?}", e))?, ), Some(ForkName::Deneb) => SignedBeaconBlock::::Deneb( SignedBeaconBlockDeneb::from_ssz_bytes(data) - .map_err(|e| format!("{:?}", e))?, + .map_err(|e| format!("{:?}", e))?, ), Some(ForkName::Eip6110) => SignedBeaconBlock::::Eip6110( SignedBeaconBlockEip6110::from_ssz_bytes(data) - .map_err(|e| format!("{:?}", e))?, + .map_err(|e| format!("{:?}", e))?, ), None => { return Err(format!( diff --git a/beacon_node/store/src/impls/execution_payload.rs b/beacon_node/store/src/impls/execution_payload.rs index c34fb30c7d2..29c435aaa95 100644 --- a/beacon_node/store/src/impls/execution_payload.rs +++ b/beacon_node/store/src/impls/execution_payload.rs @@ -1,7 +1,7 @@ use crate::{DBColumn, Error, StoreItem}; use ssz::{Decode, Encode}; use types::{ - BlobsSidecar, EthSpec, ExecutionPayload, ExecutionPayloadCapella, ExecutionPayloadDeneb, + BlobSidecarList, EthSpec, ExecutionPayload, ExecutionPayloadCapella, ExecutionPayloadDeneb, ExecutionPayloadEip6110, ExecutionPayloadMerge, }; diff --git a/common/eth2/src/types.rs b/common/eth2/src/types.rs index 581ddadd084..810c3ae0683 100644 --- a/common/eth2/src/types.rs +++ b/common/eth2/src/types.rs @@ -1316,7 +1316,7 @@ impl> ForkVersionDeserialize D, >(value, fork_name)?)) } - ForkName::Deneb => Ok(BlockContents::BlockAndBlobSidecars( + ForkName::Deneb | ForkName::Eip6110 => Ok(BlockContents::BlockAndBlobSidecars( BeaconBlockAndBlobSidecars::deserialize_by_fork::<'de, D>(value, fork_name)?, )), } @@ -1380,6 +1380,7 @@ impl> From SignedBlockContents::Block(block), //TODO: error handling, this should be try from SignedBeaconBlock::Deneb(_block) => todo!(), + SignedBeaconBlock::Eip6110(_block) => todo!(), } } } diff --git a/consensus/state_processing/src/genesis.rs b/consensus/state_processing/src/genesis.rs index adcc3a05be0..83fe7861674 100644 --- a/consensus/state_processing/src/genesis.rs +++ b/consensus/state_processing/src/genesis.rs @@ -111,8 +111,8 @@ pub fn initialize_beacon_state_from_eth1( // Override latest execution payload header. // See https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/beacon-chain.md#testing - if let Some(ExecutionPayloadHeader::Deneb(header)) = execution_payload_header { - *state.latest_execution_payload_header_deneb_mut()? = header; + if let Some(ExecutionPayloadHeader::Deneb(ref header)) = execution_payload_header { + *state.latest_execution_payload_header_deneb_mut()? = header.clone(); } } diff --git a/consensus/state_processing/src/upgrade/eip6110.rs b/consensus/state_processing/src/upgrade/eip6110.rs index 0afe5f0e118..68b25209fc3 100644 --- a/consensus/state_processing/src/upgrade/eip6110.rs +++ b/consensus/state_processing/src/upgrade/eip6110.rs @@ -7,7 +7,7 @@ pub fn upgrade_to_eip6110( spec: &ChainSpec, ) -> Result<(), Error> { let epoch = pre_state.current_epoch(); - let pre = pre_state.as_eip4844_mut()?; + let pre = pre_state.as_deneb_mut()?; let previous_fork_version = pre.fork.current_version; diff --git a/consensus/types/src/beacon_block.rs b/consensus/types/src/beacon_block.rs index e40da335c71..68ab10aceed 100644 --- a/consensus/types/src/beacon_block.rs +++ b/consensus/types/src/beacon_block.rs @@ -129,8 +129,8 @@ impl> BeaconBlock { /// on the fork slot. pub fn any_from_ssz_bytes(bytes: &[u8]) -> Result { BeaconBlockEip6110::from_ssz_bytes(bytes) - .map(BeaconBlock::Eip6110) - .or_else(|_| BeaconBlockDeneb::from_ssz_bytes(bytes).map(BeaconBlock::Deneb)) + .map(BeaconBlock::Eip6110) + .or_else(|_| BeaconBlockDeneb::from_ssz_bytes(bytes).map(BeaconBlock::Deneb)) .or_else(|_| BeaconBlockCapella::from_ssz_bytes(bytes).map(BeaconBlock::Capella)) .or_else(|_| BeaconBlockMerge::from_ssz_bytes(bytes).map(BeaconBlock::Merge)) .or_else(|_| BeaconBlockAltair::from_ssz_bytes(bytes).map(BeaconBlock::Altair)) @@ -226,6 +226,7 @@ impl<'a, T: EthSpec, Payload: AbstractExecPayload> BeaconBlockRef<'a, T, Payl BeaconBlockRef::Merge { .. } => ForkName::Merge, BeaconBlockRef::Capella { .. } => ForkName::Capella, BeaconBlockRef::Deneb { .. } => ForkName::Deneb, + BeaconBlockRef::Eip6110 { .. } => ForkName::Eip6110, } } @@ -1000,7 +1001,7 @@ mod tests { // It's invalid to have an Eip4844 block with a epoch lower than the fork epoch. let bad_block = { let mut bad = good_block.clone(); - *bad.slot_mut() = eip4844_slot; + *bad.slot_mut() = deneb_slot; bad }; diff --git a/consensus/types/src/beacon_block_body.rs b/consensus/types/src/beacon_block_body.rs index eade993bd56..293e33a4ca8 100644 --- a/consensus/types/src/beacon_block_body.rs +++ b/consensus/types/src/beacon_block_body.rs @@ -1,5 +1,6 @@ -use crate::test_utils::TestRandom; +use crate::payload::BlindedPayloadDeneb; use crate::*; +use crate::{payload::FullPayloadDeneb, test_utils::TestRandom}; use derivative::Derivative; use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; @@ -73,7 +74,7 @@ pub struct BeaconBlockBody = FullPay #[superstruct(only(Capella, Deneb, Eip6110))] pub bls_to_execution_changes: VariableList, - #[superstruct(only(Eip4844, Eip6110))] + #[superstruct(only(Deneb, Eip6110))] pub blob_kzg_commitments: KzgCommitments, #[superstruct(only(Base, Altair))] #[ssz(skip_serializing, skip_deserializing)] diff --git a/consensus/types/src/beacon_state.rs b/consensus/types/src/beacon_state.rs index 09d7dc75c9a..53f68fdf001 100644 --- a/consensus/types/src/beacon_state.rs +++ b/consensus/types/src/beacon_state.rs @@ -297,7 +297,7 @@ where only(Deneb), partial_getter(rename = "latest_execution_payload_header_deneb") )] - pub latest_execution_payload_header: ExecutionPayloadHeaderEipDeneb, + pub latest_execution_payload_header: ExecutionPayloadHeaderDeneb, #[superstruct( only(Eip6110), partial_getter(rename = "latest_execution_payload_header_eip6110") @@ -445,6 +445,7 @@ impl BeaconState { BeaconState::Merge { .. } => ForkName::Merge, BeaconState::Capella { .. } => ForkName::Capella, BeaconState::Deneb { .. } => ForkName::Deneb, + BeaconState::Eip6110 { .. } => ForkName::Eip6110, } } @@ -1969,6 +1970,9 @@ pub mod ssz_tagged_beacon_state { body, )?)), ForkName::Deneb => Ok(BeaconState::Deneb(BeaconStateDeneb::from_ssz_bytes(body)?)), + ForkName::Eip6110 => Ok(BeaconState::Eip6110(BeaconStateEip6110::from_ssz_bytes( + body, + )?)), } } } diff --git a/consensus/types/src/execution_payload_header.rs b/consensus/types/src/execution_payload_header.rs index 1b59888f443..0fd5982b279 100644 --- a/consensus/types/src/execution_payload_header.rs +++ b/consensus/types/src/execution_payload_header.rs @@ -100,9 +100,7 @@ impl ExecutionPayloadHeader { ForkName::Capella => { ExecutionPayloadHeaderCapella::from_ssz_bytes(bytes).map(Self::Capella) } - ForkName::Deneb => { - ExecutionPayloadHeaderDeneb::from_ssz_bytes(bytes).map(Self::Deneb) - } + ForkName::Deneb => ExecutionPayloadHeaderDeneb::from_ssz_bytes(bytes).map(Self::Deneb), ForkName::Eip6110 => { ExecutionPayloadHeaderEip6110::from_ssz_bytes(bytes).map(Self::Eip6110) } @@ -165,7 +163,7 @@ impl ExecutionPayloadHeaderCapella { } } -impl ExecutionPayloadHeaderEip4844 { +impl ExecutionPayloadHeaderDeneb { pub fn upgrade_to_eip6110(&self) -> ExecutionPayloadHeaderEip6110 { ExecutionPayloadHeaderEip6110 { parent_hash: self.parent_hash, diff --git a/consensus/types/src/fork_name.rs b/consensus/types/src/fork_name.rs index 15cffe39254..b573fc37d04 100644 --- a/consensus/types/src/fork_name.rs +++ b/consensus/types/src/fork_name.rs @@ -96,7 +96,7 @@ impl ForkName { ForkName::Merge => Some(ForkName::Altair), ForkName::Capella => Some(ForkName::Merge), ForkName::Deneb => Some(ForkName::Capella), - ForkName::Eip6110 => Some(ForkName::Eip4844), + ForkName::Eip6110 => Some(ForkName::Deneb), } } diff --git a/consensus/types/src/lib.rs b/consensus/types/src/lib.rs index e27452196b1..74762eed8a1 100644 --- a/consensus/types/src/lib.rs +++ b/consensus/types/src/lib.rs @@ -110,7 +110,7 @@ pub use crate::attestation_data::AttestationData; pub use crate::attestation_duty::AttestationDuty; pub use crate::attester_slashing::AttesterSlashing; pub use crate::beacon_block::{ - BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockCapella, BeaconBlockEipDeneb, + BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockCapella, BeaconBlockDeneb, BeaconBlockEip6110, BeaconBlockMerge, BeaconBlockRef, BeaconBlockRefMut, BlindedBeaconBlock, EmptyBlock, }; @@ -163,9 +163,9 @@ pub use crate::light_client_optimistic_update::LightClientOptimisticUpdate; pub use crate::participation_flags::ParticipationFlags; pub use crate::participation_list::ParticipationList; pub use crate::payload::{ - AbstractExecPayload, BlindedPayload, BlindedPayloadCapella, BlindedPayloadEipDeneb, + AbstractExecPayload, BlindedPayload, BlindedPayloadCapella, BlindedPayloadDeneb, BlindedPayloadEip6110, BlindedPayloadMerge, BlindedPayloadRef, BlockType, ExecPayload, - FullPayload, FullPayloadCapella, FullPayloadEipDeneb, FullPayloadEip6110, FullPayloadMerge, + FullPayload, FullPayloadCapella, FullPayloadDeneb, FullPayloadEip6110, FullPayloadMerge, FullPayloadRef, OwnedExecPayload, }; pub use crate::pending_attestation::PendingAttestation; @@ -178,8 +178,9 @@ pub use crate::shuffling_id::AttestationShufflingId; pub use crate::signed_aggregate_and_proof::SignedAggregateAndProof; pub use crate::signed_beacon_block::{ ssz_tagged_signed_beacon_block, SignedBeaconBlock, SignedBeaconBlockAltair, - SignedBeaconBlockBase, SignedBeaconBlockCapella, SignedBeaconBlockDeneb, SignedBeaconBlockEip6110, SignedBeaconBlockHash, - SignedBeaconBlockMerge, SignedBlindedBeaconBlock, + SignedBeaconBlockBase, SignedBeaconBlockCapella, SignedBeaconBlockDeneb, + SignedBeaconBlockEip6110, SignedBeaconBlockHash, SignedBeaconBlockMerge, + SignedBlindedBeaconBlock, }; pub use crate::signed_beacon_block_header::SignedBeaconBlockHeader; pub use crate::signed_blob::*; diff --git a/consensus/types/src/payload.rs b/consensus/types/src/payload.rs index d7287389014..1f2ba3600eb 100644 --- a/consensus/types/src/payload.rs +++ b/consensus/types/src/payload.rs @@ -89,7 +89,7 @@ pub trait AbstractExecPayload: + Copy + From<&'a Self::Merge> + From<&'a Self::Capella> - + From<&'a Self::Deneb>; + + From<&'a Self::Deneb> + From<&'a Self::Eip6110>; type Merge: OwnedExecPayload @@ -272,7 +272,7 @@ impl ExecPayload for FullPayload { match self { FullPayload::Merge(_) => Err(Error::IncorrectStateVariant), FullPayload::Capella(_) => Err(Error::IncorrectStateVariant), - FullPayload::Eip4844(_) => Err(Error::IncorrectStateVariant), + FullPayload::Deneb(_) => Err(Error::IncorrectStateVariant), FullPayload::Eip6110(ref inner) => Ok(inner.execution_payload.deposit_receipts.clone()), } } @@ -393,7 +393,7 @@ impl<'b, T: EthSpec> ExecPayload for FullPayloadRef<'b, T> { match self { FullPayloadRef::Merge(_) => Err(Error::IncorrectStateVariant), FullPayloadRef::Capella(_) => Err(Error::IncorrectStateVariant), - FullPayloadRef::Eip4844(_) => Err(Error::IncorrectStateVariant), + FullPayloadRef::Deneb(_) => Err(Error::IncorrectStateVariant), FullPayloadRef::Eip6110(inner) => Ok(inner.execution_payload.deposit_receipts.clone()), } } @@ -568,9 +568,7 @@ impl ExecPayload for BlindedPayload { BlindedPayload::Capella(ref inner) => { Ok(inner.execution_payload_header.withdrawals_root) } - BlindedPayload::Deneb(ref inner) => { - Ok(inner.execution_payload_header.withdrawals_root) - } + BlindedPayload::Deneb(ref inner) => Ok(inner.execution_payload_header.withdrawals_root), BlindedPayload::Eip6110(ref inner) => { Ok(inner.execution_payload_header.withdrawals_root) } @@ -672,9 +670,7 @@ impl<'b, T: EthSpec> ExecPayload for BlindedPayloadRef<'b, T> { BlindedPayloadRef::Capella(inner) => { Ok(inner.execution_payload_header.withdrawals_root) } - BlindedPayloadRef::Deneb(inner) => { - Ok(inner.execution_payload_header.withdrawals_root) - } + BlindedPayloadRef::Deneb(inner) => Ok(inner.execution_payload_header.withdrawals_root), BlindedPayloadRef::Eip6110(inner) => { Ok(inner.execution_payload_header.withdrawals_root) } diff --git a/consensus/types/src/signed_beacon_block.rs b/consensus/types/src/signed_beacon_block.rs index 2e3ba670c89..3b45403a0c2 100644 --- a/consensus/types/src/signed_beacon_block.rs +++ b/consensus/types/src/signed_beacon_block.rs @@ -669,6 +669,9 @@ pub mod ssz_tagged_signed_beacon_block { ForkName::Deneb => Ok(SignedBeaconBlock::Deneb( SignedBeaconBlockDeneb::from_ssz_bytes(body)?, )), + ForkName::Eip6110 => Ok(SignedBeaconBlock::Eip6110( + SignedBeaconBlockEip6110::from_ssz_bytes(body)?, + )), } } } diff --git a/lcli/src/parse_ssz.rs b/lcli/src/parse_ssz.rs index b78dcf2a76c..191bafecd59 100644 --- a/lcli/src/parse_ssz.rs +++ b/lcli/src/parse_ssz.rs @@ -65,8 +65,8 @@ pub fn run_parse_ssz(matches: &ArgMatches) -> Result<(), String> { "state_merge" => decode_and_print::>(&bytes, format)?, "state_capella" => decode_and_print::>(&bytes, format)?, "state_deneb" => decode_and_print::>(&bytes, format)?, - "blobs_sidecar" => decode_and_print::>(&bytes, format)?, "state_eip6110" => decode_and_print::>(&bytes, format)?, + "blob_sidecar" => decode_and_print::>(&bytes, format)?, other => return Err(format!("Unknown type: {}", other)), }; diff --git a/testing/ef_tests/src/cases/operations.rs b/testing/ef_tests/src/cases/operations.rs index 2a008412dbb..77092c69c0e 100644 --- a/testing/ef_tests/src/cases/operations.rs +++ b/testing/ef_tests/src/cases/operations.rs @@ -381,7 +381,8 @@ impl Operation for DepositReceipt { && fork_name != ForkName::Altair && fork_name != ForkName::Merge && fork_name != ForkName::Capella - && fork_name != ForkName::Eip4844 + && fork_name != ForkName::Deneb + && fork_name != ForkName::Eip6110 } fn decode(path: &Path, _fork_name: ForkName, _spec: &ChainSpec) -> Result { diff --git a/testing/ef_tests/src/cases/transition.rs b/testing/ef_tests/src/cases/transition.rs index e5ab8ad10f9..b0f2d74d501 100644 --- a/testing/ef_tests/src/cases/transition.rs +++ b/testing/ef_tests/src/cases/transition.rs @@ -57,7 +57,7 @@ impl LoadCase for TransitionTest { spec.altair_fork_epoch = Some(Epoch::new(0)); spec.bellatrix_fork_epoch = Some(Epoch::new(0)); spec.capella_fork_epoch = Some(Epoch::new(0)); - spec.eip4844_fork_epoch = Some(Epoch::new(0)); + spec.deneb_fork_epoch = Some(Epoch::new(0)); spec.eip6110_fork_epoch = Some(metadata.fork_epoch); } } From 61e5be83b7017885ec8af021d7ca832281056e98 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Fri, 19 May 2023 11:22:44 +0200 Subject: [PATCH 41/52] Various bug fixes and improvements --- beacon_node/execution_layer/src/engine_api.rs | 6 +++--- .../execution_layer/src/engine_api/http.rs | 17 +++-------------- .../src/engine_api/json_structures.rs | 4 ++-- beacon_node/execution_layer/src/lib.rs | 11 ++--------- .../src/test_utils/execution_block_generator.rs | 2 +- .../execution_layer/src/test_utils/mod.rs | 2 +- .../src/common/slash_validator.rs | 6 ++---- .../per_block_processing/process_operations.rs | 6 +++++- consensus/types/src/beacon_block_body.rs | 3 +-- consensus/types/src/execution_payload_header.rs | 10 +++++----- 10 files changed, 25 insertions(+), 42 deletions(-) diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index aabe29c4827..3e0df2bc9ea 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -263,7 +263,6 @@ impl TryFrom> for ExecutionBlockWithTransactions timestamp: block.timestamp, extra_data: block.extra_data, base_fee_per_gas: block.base_fee_per_gas, - excess_data_gas: block.excess_data_gas, block_hash: block.block_hash, transactions: block .transactions @@ -274,6 +273,7 @@ impl TryFrom> for ExecutionBlockWithTransactions .into_iter() .map(|withdrawal| withdrawal.into()) .collect(), + excess_data_gas: block.excess_data_gas, }), ExecutionPayload::Eip6110(block) => { Self::Eip6110(ExecutionBlockWithTransactionsEip6110 { @@ -289,7 +289,6 @@ impl TryFrom> for ExecutionBlockWithTransactions timestamp: block.timestamp, extra_data: block.extra_data, base_fee_per_gas: block.base_fee_per_gas, - excess_data_gas: block.excess_data_gas, block_hash: block.block_hash, transactions: block .transactions @@ -304,6 +303,7 @@ impl TryFrom> for ExecutionBlockWithTransactions .into_iter() .map(|deposit_receipt| deposit_receipt.into()) .collect(), + excess_data_gas: block.excess_data_gas, }) } }; @@ -580,11 +580,11 @@ impl ExecutionPayloadBodyV1 { timestamp: header.timestamp, extra_data: header.extra_data, base_fee_per_gas: header.base_fee_per_gas, - excess_data_gas: header.excess_data_gas, block_hash: header.block_hash, transactions: self.transactions, withdrawals, deposit_receipts, + excess_data_gas: header.excess_data_gas, })) } else { Err(format!( diff --git a/beacon_node/execution_layer/src/engine_api/http.rs b/beacon_node/execution_layer/src/engine_api/http.rs index d3b37a96871..0e8486f89bb 100644 --- a/beacon_node/execution_layer/src/engine_api/http.rs +++ b/beacon_node/execution_layer/src/engine_api/http.rs @@ -929,20 +929,9 @@ impl HttpJsonRpc { .await?; Ok(JsonGetPayloadResponse::V3(response).into()) } - ForkName::Eip6110 => { - let response: JsonGetPayloadResponseV6110 = self - .rpc_request( - ENGINE_GET_PAYLOAD_V6110, - params, - ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, - ) - .await?; - Ok(JsonGetPayloadResponse::V6110(response).into()) - } - ForkName::Base | ForkName::Altair => Err(Error::UnsupportedForkVariant(format!( - "called get_payload_v3 with {}", - fork_name - ))), + ForkName::Base | ForkName::Altair | ForkName::Eip6110 => Err( + Error::UnsupportedForkVariant(format!("called get_payload_v3 with {}", fork_name)), + ), } } diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index 2753bd4d269..cfbcd3d47ec 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -196,7 +196,6 @@ impl From> for JsonExecutionPayloadV6110< timestamp: payload.timestamp, extra_data: payload.extra_data, base_fee_per_gas: payload.base_fee_per_gas, - excess_data_gas: payload.excess_data_gas, block_hash: payload.block_hash, transactions: payload.transactions, withdrawals: payload @@ -205,6 +204,7 @@ impl From> for JsonExecutionPayloadV6110< .map(Into::into) .collect::>() .into(), + excess_data_gas: payload.excess_data_gas, deposit_receipts: payload .deposit_receipts .into_iter() @@ -314,7 +314,6 @@ impl From> for ExecutionPayloadEip6110< timestamp: payload.timestamp, extra_data: payload.extra_data, base_fee_per_gas: payload.base_fee_per_gas, - excess_data_gas: payload.excess_data_gas, block_hash: payload.block_hash, transactions: payload.transactions, withdrawals: payload @@ -323,6 +322,7 @@ impl From> for ExecutionPayloadEip6110< .map(Into::into) .collect::>() .into(), + excess_data_gas: payload.excess_data_gas, deposit_receipts: payload .deposit_receipts .into_iter() diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 804f3586493..4ff902a44f1 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -245,14 +245,7 @@ impl> BlockProposalContents BlockProposalContents::PayloadAndBlobs { - payload: Payload::default_at_fork(fork_name)?, - block_value: Uint256::zero(), - blobs: VariableList::default(), - kzg_commitments: VariableList::default(), - proofs: VariableList::default(), - }, - ForkName::Eip6110 => BlockProposalContents::PayloadAndBlobs { + ForkName::Deneb | ForkName::Eip6110 => BlockProposalContents::PayloadAndBlobs { payload: Payload::default_at_fork(fork_name)?, block_value: Uint256::zero(), blobs: VariableList::default(), @@ -1904,10 +1897,10 @@ impl ExecutionLayer { timestamp: eip6110_block.timestamp, extra_data: eip6110_block.extra_data, base_fee_per_gas: eip6110_block.base_fee_per_gas, - excess_data_gas: eip6110_block.excess_data_gas, block_hash: eip6110_block.block_hash, transactions: convert_transactions(eip6110_block.transactions)?, withdrawals, + excess_data_gas: eip6110_block.excess_data_gas, deposit_receipts, }) } diff --git a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs index e225c483b14..02c5762923f 100644 --- a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs +++ b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs @@ -597,10 +597,10 @@ impl ExecutionBlockGenerator { extra_data: "block gen was here".as_bytes().to_vec().into(), base_fee_per_gas: Uint256::one(), // FIXME(4844): maybe this should be set to something? - excess_data_gas: Uint256::one(), block_hash: ExecutionBlockHash::zero(), transactions: vec![].into(), withdrawals: pa.withdrawals.clone().into(), + excess_data_gas: Uint256::one(), deposit_receipts: vec![].into(), }) } diff --git a/beacon_node/execution_layer/src/test_utils/mod.rs b/beacon_node/execution_layer/src/test_utils/mod.rs index 3b25a7fd091..3a5a6573bb7 100644 --- a/beacon_node/execution_layer/src/test_utils/mod.rs +++ b/beacon_node/execution_layer/src/test_utils/mod.rs @@ -182,7 +182,7 @@ impl MockServer { *self.ctx.engine_capabilities.write() = engine_capabilities; } - #[allow(clippy::too_many_arguments)] // FIXME: refactor + #[allow(clippy::too_many_arguments)] pub fn new( handle: &runtime::Handle, jwt_key: JwtKey, diff --git a/consensus/state_processing/src/common/slash_validator.rs b/consensus/state_processing/src/common/slash_validator.rs index 14eb40bb3c3..5674596cd94 100644 --- a/consensus/state_processing/src/common/slash_validator.rs +++ b/consensus/state_processing/src/common/slash_validator.rs @@ -53,10 +53,8 @@ pub fn slash_validator( BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) - | BeaconState::Deneb(_) => whistleblower_reward - .safe_mul(PROPOSER_WEIGHT)? - .safe_div(WEIGHT_DENOMINATOR)?, - BeaconState::Eip6110(_) => whistleblower_reward + | BeaconState::Deneb(_) + | BeaconState::Eip6110(_) => whistleblower_reward .safe_mul(PROPOSER_WEIGHT)? .safe_div(WEIGHT_DENOMINATOR)?, }; diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 060a96e06e8..94358c12bb2 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -21,9 +21,13 @@ pub fn process_operations>( .unwrap_or_else(|_| state.eth1_data().deposit_count); let expected_deposit_count = if state.eth1_deposit_index() < eth1_deposit_index_limit { + let diff = eth1_deposit_index_limit + .checked_sub(state.eth1_deposit_index()) + .ok_or(BlockProcessingError::DepositReceiptError)?; + std::cmp::min( ::MaxDeposits::to_u64() as usize, - (eth1_deposit_index_limit - state.eth1_deposit_index()) as usize, + diff as usize, ) as u64 } else { 0 diff --git a/consensus/types/src/beacon_block_body.rs b/consensus/types/src/beacon_block_body.rs index 293e33a4ca8..a99d6e20d50 100644 --- a/consensus/types/src/beacon_block_body.rs +++ b/consensus/types/src/beacon_block_body.rs @@ -1,6 +1,5 @@ -use crate::payload::BlindedPayloadDeneb; +use crate::test_utils::TestRandom; use crate::*; -use crate::{payload::FullPayloadDeneb, test_utils::TestRandom}; use derivative::Derivative; use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; diff --git a/consensus/types/src/execution_payload_header.rs b/consensus/types/src/execution_payload_header.rs index 0fd5982b279..82c6bb8a0b3 100644 --- a/consensus/types/src/execution_payload_header.rs +++ b/consensus/types/src/execution_payload_header.rs @@ -77,13 +77,13 @@ pub struct ExecutionPayloadHeader { #[superstruct(only(Capella, Deneb, Eip6110))] #[superstruct(getter(copy))] pub withdrawals_root: Hash256, - #[superstruct(only(Eip6110))] - #[superstruct(getter(copy))] - pub deposit_receipts: DepositReceipts, #[superstruct(only(Deneb, Eip6110))] #[serde(with = "eth2_serde_utils::quoted_u256")] #[superstruct(getter(copy))] pub excess_data_gas: Uint256, + #[superstruct(only(Eip6110))] + #[superstruct(getter(copy))] + pub deposit_receipts: DepositReceipts, } impl ExecutionPayloadHeader { @@ -178,10 +178,10 @@ impl ExecutionPayloadHeaderDeneb { timestamp: self.timestamp, extra_data: self.extra_data.clone(), base_fee_per_gas: self.base_fee_per_gas, - excess_data_gas: Uint256::zero(), block_hash: self.block_hash, transactions_root: self.transactions_root, withdrawals_root: self.withdrawals_root, + excess_data_gas: Uint256::zero(), deposit_receipts: DepositReceipts::::default(), } } @@ -267,10 +267,10 @@ impl<'a, T: EthSpec> From<&'a ExecutionPayloadEip6110> for ExecutionPayloadHe timestamp: payload.timestamp, extra_data: payload.extra_data.clone(), base_fee_per_gas: payload.base_fee_per_gas, - excess_data_gas: payload.excess_data_gas, block_hash: payload.block_hash, transactions_root: payload.transactions.tree_hash_root(), withdrawals_root: payload.withdrawals.tree_hash_root(), + excess_data_gas: payload.excess_data_gas, deposit_receipts: payload.deposit_receipts.clone(), } } From 197f82f7d6d5942fb0057e872e2c429be38be94b Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Thu, 25 May 2023 13:01:14 +0200 Subject: [PATCH 42/52] activate `process_deposit_receipt` at 6110 --- .../src/per_block_processing.rs | 54 ++++++++++--------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 7526bc05a0b..2dd2b2210b1 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -429,32 +429,38 @@ pub fn process_deposit_receipt( deposit_receipt: &DepositReceipt, spec: &ChainSpec, ) -> Result<(), BlockProcessingError> { - // Set deposit receipt start index - let start_index = state - .deposit_receipts_start_index() - .map_err(|_| BlockProcessingError::DepositReceiptError)?; - if start_index == UNSET_DEPOSIT_RECEIPTS_START_INDEX { - *state - .deposit_receipts_start_index_mut() - .map_err(|_| BlockProcessingError::DepositReceiptError)? = deposit_receipt.index; - } - - // Create a Deposit object from the DepositReceipt - let deposit_data = DepositData { - pubkey: deposit_receipt.pubkey, - withdrawal_credentials: deposit_receipt.withdrawal_credentials, - amount: deposit_receipt.amount, - signature: deposit_receipt.signature.clone(), - }; - let deposit = Deposit { - proof: FixedVector::from_elem(Hash256::zero()), // Set an empty proof, since it's not included in DepositReceipt - data: deposit_data, - }; + match state { + BeaconState::Eip6110(_) => { + // Set deposit receipt start index + let start_index = state + .deposit_receipts_start_index() + .map_err(|_| BlockProcessingError::DepositReceiptError)?; + if start_index == UNSET_DEPOSIT_RECEIPTS_START_INDEX { + *state + .deposit_receipts_start_index_mut() + .map_err(|_| BlockProcessingError::DepositReceiptError)? = + deposit_receipt.index; + } - // Call apply with the created Deposit object - apply_deposit(state, &deposit, spec)?; + // Create a Deposit object from the DepositReceipt + let deposit_data = DepositData { + pubkey: deposit_receipt.pubkey, + withdrawal_credentials: deposit_receipt.withdrawal_credentials, + amount: deposit_receipt.amount, + signature: deposit_receipt.signature.clone(), + }; + let deposit = Deposit { + proof: FixedVector::from_elem(Hash256::zero()), // Set an empty proof, since it's not included in DepositReceipt + data: deposit_data, + }; + + // Call apply with the created Deposit object + apply_deposit(state, &deposit, spec)?; - Ok(()) + Ok(()) + } + _ => Ok(()), // Do nothing for other states + } } /// These functions will definitely be called before the merge. Their entire purpose is to check if From 33cd27a932c5d99aa1f3065150956abceeac5256 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Mon, 29 May 2023 09:53:28 +0200 Subject: [PATCH 43/52] fix to call `newPayloadV6110` --- beacon_node/execution_layer/src/engine_api.rs | 9 ++++++++- .../execution_layer/src/engine_api/http.rs | 19 +++++++++++++++++++ .../src/test_utils/handle_rpc.rs | 5 ++++- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index 3e0df2bc9ea..1730039fa05 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -3,7 +3,8 @@ use crate::http::{ ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_V1, ENGINE_FORKCHOICE_UPDATED_V1, ENGINE_FORKCHOICE_UPDATED_V2, ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1, ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1, ENGINE_GET_PAYLOAD_V1, ENGINE_GET_PAYLOAD_V2, - ENGINE_GET_PAYLOAD_V3, ENGINE_NEW_PAYLOAD_V1, ENGINE_NEW_PAYLOAD_V2, ENGINE_NEW_PAYLOAD_V3, + ENGINE_GET_PAYLOAD_V3, ENGINE_GET_PAYLOAD_V6110, ENGINE_NEW_PAYLOAD_V1, ENGINE_NEW_PAYLOAD_V2, + ENGINE_NEW_PAYLOAD_V3, ENGINE_NEW_PAYLOAD_V6110, }; use crate::BlobTxConversionError; use eth2::types::{SsePayloadAttributes, SsePayloadAttributesV1, SsePayloadAttributesV2}; @@ -633,6 +634,9 @@ impl EngineCapabilities { if self.new_payload_v3 { response.push(ENGINE_NEW_PAYLOAD_V3); } + if self.new_payload_v6110 { + response.push(ENGINE_NEW_PAYLOAD_V6110); + } if self.forkchoice_updated_v1 { response.push(ENGINE_FORKCHOICE_UPDATED_V1); } @@ -654,6 +658,9 @@ impl EngineCapabilities { if self.get_payload_v3 { response.push(ENGINE_GET_PAYLOAD_V3); } + if self.get_payload_v6110 { + response.push(ENGINE_GET_PAYLOAD_V6110); + } if self.exchange_transition_configuration_v1 { response.push(ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_V1); } diff --git a/beacon_node/execution_layer/src/engine_api/http.rs b/beacon_node/execution_layer/src/engine_api/http.rs index 0e8486f89bb..ead82119097 100644 --- a/beacon_node/execution_layer/src/engine_api/http.rs +++ b/beacon_node/execution_layer/src/engine_api/http.rs @@ -67,9 +67,11 @@ pub static LIGHTHOUSE_CAPABILITIES: &[&str] = &[ ENGINE_NEW_PAYLOAD_V1, ENGINE_NEW_PAYLOAD_V2, ENGINE_NEW_PAYLOAD_V3, + ENGINE_NEW_PAYLOAD_V6110, ENGINE_GET_PAYLOAD_V1, ENGINE_GET_PAYLOAD_V2, ENGINE_GET_PAYLOAD_V3, + ENGINE_GET_PAYLOAD_V6110, ENGINE_FORKCHOICE_UPDATED_V1, ENGINE_FORKCHOICE_UPDATED_V2, ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1, @@ -834,6 +836,23 @@ impl HttpJsonRpc { Ok(response.into()) } + pub async fn new_payload_v6110( + &self, + execution_payload: ExecutionPayload, + ) -> Result { + let params = json!([JsonExecutionPayload::from(execution_payload)]); + + let response: JsonPayloadStatusV1 = self + .rpc_request( + ENGINE_NEW_PAYLOAD_V6110, + params, + ENGINE_NEW_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, + ) + .await?; + + Ok(response.into()) + } + pub async fn get_payload_v1( &self, payload_id: PayloadId, diff --git a/beacon_node/execution_layer/src/test_utils/handle_rpc.rs b/beacon_node/execution_layer/src/test_utils/handle_rpc.rs index 992fd104ebd..f0253aa2763 100644 --- a/beacon_node/execution_layer/src/test_utils/handle_rpc.rs +++ b/beacon_node/execution_layer/src/test_utils/handle_rpc.rs @@ -88,7 +88,10 @@ pub async fn handle_rpc( .unwrap()) } } - ENGINE_NEW_PAYLOAD_V1 | ENGINE_NEW_PAYLOAD_V2 | ENGINE_NEW_PAYLOAD_V3 => { + ENGINE_NEW_PAYLOAD_V1 + | ENGINE_NEW_PAYLOAD_V2 + | ENGINE_NEW_PAYLOAD_V3 + | ENGINE_NEW_PAYLOAD_V6110 => { let request = match method { ENGINE_NEW_PAYLOAD_V1 => JsonExecutionPayload::V1( get_param::>(params, 0) From be3f310a6081d658808a5fcfd96c2de9ea6e95af Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Thu, 1 Jun 2023 11:17:30 +0200 Subject: [PATCH 44/52] add `new_payload_v6110` --- beacon_node/execution_layer/src/engine_api.rs | 8 ++--- .../execution_layer/src/engine_api/http.rs | 8 +++-- .../src/engine_api/json_structures.rs | 4 +-- .../src/test_utils/handle_rpc.rs | 29 ++++++++++--------- consensus/types/src/execution_payload.rs | 4 +-- 5 files changed, 30 insertions(+), 23 deletions(-) diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index 1730039fa05..8a807920eff 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -193,11 +193,11 @@ pub struct ExecutionBlockWithTransactions { pub transactions: Vec, #[superstruct(only(Capella, Deneb, Eip6110))] pub withdrawals: Vec, - #[superstruct(only(Eip6110))] - pub deposit_receipts: Vec, #[superstruct(only(Deneb, Eip6110))] #[serde(with = "eth2_serde_utils::u256_hex_be")] pub excess_data_gas: Uint256, + #[superstruct(only(Eip6110))] + pub deposit_receipts: Vec, } impl TryFrom> for ExecutionBlockWithTransactions { @@ -300,11 +300,11 @@ impl TryFrom> for ExecutionBlockWithTransactions .into_iter() .map(|withdrawal| withdrawal.into()) .collect(), + excess_data_gas: block.excess_data_gas, deposit_receipts: Vec::from(block.deposit_receipts) .into_iter() .map(|deposit_receipt| deposit_receipt.into()) .collect(), - excess_data_gas: block.excess_data_gas, }) } }; @@ -584,8 +584,8 @@ impl ExecutionPayloadBodyV1 { block_hash: header.block_hash, transactions: self.transactions, withdrawals, - deposit_receipts, excess_data_gas: header.excess_data_gas, + deposit_receipts, })) } else { Err(format!( diff --git a/beacon_node/execution_layer/src/engine_api/http.rs b/beacon_node/execution_layer/src/engine_api/http.rs index ead82119097..2839fc1d4d3 100644 --- a/beacon_node/execution_layer/src/engine_api/http.rs +++ b/beacon_node/execution_layer/src/engine_api/http.rs @@ -1188,7 +1188,9 @@ impl HttpJsonRpc { execution_payload: ExecutionPayload, ) -> Result { let engine_capabilities = self.get_engine_capabilities(None).await?; - if engine_capabilities.new_payload_v3 { + if engine_capabilities.new_payload_v6110 { + self.new_payload_v6110(execution_payload).await + } else if engine_capabilities.new_payload_v3 { self.new_payload_v3(execution_payload).await } else if engine_capabilities.new_payload_v2 { self.new_payload_v2(execution_payload).await @@ -1207,7 +1209,9 @@ impl HttpJsonRpc { payload_id: PayloadId, ) -> Result, Error> { let engine_capabilities = self.get_engine_capabilities(None).await?; - if engine_capabilities.get_payload_v3 { + if engine_capabilities.get_payload_v6110 { + self.get_payload_v6110(fork_name, payload_id).await + } else if engine_capabilities.get_payload_v3 { self.get_payload_v3(fork_name, payload_id).await } else if engine_capabilities.get_payload_v2 { self.get_payload_v2(fork_name, payload_id).await diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index cfbcd3d47ec..56a53f9ca3f 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -101,11 +101,11 @@ pub struct JsonExecutionPayload { pub transactions: Transactions, #[superstruct(only(V2, V3, V6110))] pub withdrawals: VariableList, - #[superstruct(only(V6110))] - pub deposit_receipts: VariableList, #[superstruct(only(V3, V6110))] #[serde(with = "eth2_serde_utils::u256_hex_be")] pub excess_data_gas: Uint256, + #[superstruct(only(V6110))] + pub deposit_receipts: VariableList, } impl From> for JsonExecutionPayloadV1 { diff --git a/beacon_node/execution_layer/src/test_utils/handle_rpc.rs b/beacon_node/execution_layer/src/test_utils/handle_rpc.rs index f0253aa2763..37556130770 100644 --- a/beacon_node/execution_layer/src/test_utils/handle_rpc.rs +++ b/beacon_node/execution_layer/src/test_utils/handle_rpc.rs @@ -311,6 +311,21 @@ pub async fn handle_rpc( FORK_REQUEST_MISMATCH_ERROR_CODE, )); } + // validate method called correctly according to eip6110 fork time + if ctx + .execution_block_generator + .read() + .get_fork_at_timestamp(response.timestamp()) + == ForkName::Eip6110 + && (method == ENGINE_GET_PAYLOAD_V1 + || method == ENGINE_GET_PAYLOAD_V2 + || method == ENGINE_GET_PAYLOAD_V3) + { + return Err(( + format!("{} called after eip6110 fork!", method), + FORK_REQUEST_MISMATCH_ERROR_CODE, + )); + } match method { ENGINE_GET_PAYLOAD_V1 => { @@ -361,19 +376,7 @@ pub async fn handle_rpc( }) .unwrap() } - JsonExecutionPayload::V6110(execution_payload) => { - serde_json::to_value(JsonGetPayloadResponseV6110 { - execution_payload, - block_value: DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI.into(), - blobs_bundle: maybe_blobs - .ok_or(( - "No blobs returned despite V6110 Payload".to_string(), - GENERIC_ERROR_CODE, - ))? - .into(), - }) - .unwrap() - } + _ => unreachable!(), }), ENGINE_GET_PAYLOAD_V6110 => Ok(match JsonExecutionPayload::from(response) { JsonExecutionPayload::V1(execution_payload) => { diff --git a/consensus/types/src/execution_payload.rs b/consensus/types/src/execution_payload.rs index 5947b22914d..1f5d44a0716 100644 --- a/consensus/types/src/execution_payload.rs +++ b/consensus/types/src/execution_payload.rs @@ -86,12 +86,12 @@ pub struct ExecutionPayload { pub transactions: Transactions, #[superstruct(only(Capella, Deneb, Eip6110))] pub withdrawals: Withdrawals, - #[superstruct(only(Eip6110))] - pub deposit_receipts: DepositReceipts, #[superstruct(only(Deneb, Eip6110))] #[serde(with = "eth2_serde_utils::quoted_u256")] #[superstruct(getter(copy))] pub excess_data_gas: Uint256, + #[superstruct(only(Eip6110))] + pub deposit_receipts: DepositReceipts, } impl<'a, T: EthSpec> ExecutionPayloadRef<'a, T> { From 8d00baccf9b392648ed05ce9b66cbe66652a4f44 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Sat, 3 Jun 2023 12:50:55 +0200 Subject: [PATCH 45/52] Refactor: Swap quoted_u64 source --- consensus/types/src/beacon_state.rs | 2 +- consensus/types/src/chain_spec.rs | 2 +- consensus/types/src/eip6110.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/consensus/types/src/beacon_state.rs b/consensus/types/src/beacon_state.rs index e0fc8ae33de..c90037fbc4d 100644 --- a/consensus/types/src/beacon_state.rs +++ b/consensus/types/src/beacon_state.rs @@ -315,7 +315,7 @@ where #[superstruct(only(Capella, Deneb, Eip6110))] pub historical_summaries: VariableList, #[superstruct(only(Eip6110), partial_getter(copy))] - #[serde(with = "eth2_serde_utils::quoted_u64")] + #[serde(with = "serde_utils::quoted_u64")] pub deposit_receipts_start_index: u64, // Caching (not in the spec) diff --git a/consensus/types/src/chain_spec.rs b/consensus/types/src/chain_spec.rs index d7b651f09b1..91c69f1c32f 100644 --- a/consensus/types/src/chain_spec.rs +++ b/consensus/types/src/chain_spec.rs @@ -992,7 +992,7 @@ pub struct Config { pub deneb_fork_epoch: Option>, #[serde(default = "default_eip6110_fork_version")] - #[serde(with = "eth2_serde_utils::bytes_4_hex")] + #[serde(with = "serde_utils::bytes_4_hex")] eip6110_fork_version: [u8; 4], #[serde(default)] #[serde(serialize_with = "serialize_fork_epoch")] diff --git a/consensus/types/src/eip6110.rs b/consensus/types/src/eip6110.rs index 926e62d251a..c7749d5cc12 100644 --- a/consensus/types/src/eip6110.rs +++ b/consensus/types/src/eip6110.rs @@ -12,10 +12,10 @@ use tree_hash_derive::TreeHash; pub struct DepositReceipt { pub pubkey: PublicKeyBytes, pub withdrawal_credentials: Hash256, - #[serde(with = "eth2_serde_utils::quoted_u64")] + #[serde(with = "serde_utils::quoted_u64")] pub amount: u64, pub signature: SignatureBytes, - #[serde(with = "eth2_serde_utils::quoted_u64")] + #[serde(with = "serde_utils::quoted_u64")] pub index: u64, } From 9e26fd7ea89e0c353a264f5e260c028ce5b6dffb Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Sat, 3 Jun 2023 13:48:36 +0200 Subject: [PATCH 46/52] more refactoring --- beacon_node/execution_layer/src/engine_api/json_structures.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index 10acd83e34e..d0fa89f262f 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -442,10 +442,10 @@ impl From for Withdrawal { pub struct JsonDepositReceipt { pub pubkey: PublicKeyBytes, pub withdrawal_credentials: Hash256, - #[serde(with = "eth2_serde_utils::u64_hex_be")] + #[serde(with = "serde_utils::u64_hex_be")] pub amount: u64, pub signature: SignatureBytes, - #[serde(with = "eth2_serde_utils::u64_hex_be")] + #[serde(with = "serde_utils::u64_hex_be")] pub index: u64, } From 9b99c9eab07c09109b5e0c2e7e465930b83c47ab Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Sat, 3 Jun 2023 15:13:37 +0200 Subject: [PATCH 47/52] clippy --- lcli/src/new_testnet.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lcli/src/new_testnet.rs b/lcli/src/new_testnet.rs index 8d2eca6afca..5329a6aa8de 100644 --- a/lcli/src/new_testnet.rs +++ b/lcli/src/new_testnet.rs @@ -332,6 +332,9 @@ fn initialize_state_with_validators( ExecutionPayloadHeaderRefMut::Deneb(_) => { return Err("Cannot start genesis from a deneb state".to_string()) } + ExecutionPayloadHeaderRefMut::Eip6110(_) => { + return Err("Cannot start genesis from an eip6110 state".to_string()) + } } } From 40dc77dc5e424873390bb1ad9df5f0f1a54927a8 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Mon, 5 Jun 2023 11:14:28 +0200 Subject: [PATCH 48/52] add 6110 to topics, remove `apply_deposit` --- .../src/service/gossip_cache.rs | 1 + .../lighthouse_network/src/types/pubsub.rs | 7 +++ .../lighthouse_network/src/types/topics.rs | 6 +- .../src/per_block_processing.rs | 4 +- .../process_operations.rs | 59 +++---------------- 5 files changed, 22 insertions(+), 55 deletions(-) diff --git a/beacon_node/lighthouse_network/src/service/gossip_cache.rs b/beacon_node/lighthouse_network/src/service/gossip_cache.rs index a6e003934cd..449f78b467c 100644 --- a/beacon_node/lighthouse_network/src/service/gossip_cache.rs +++ b/beacon_node/lighthouse_network/src/service/gossip_cache.rs @@ -204,6 +204,7 @@ impl GossipCache { GossipKind::BlsToExecutionChange => self.bls_to_execution_change, GossipKind::LightClientFinalityUpdate => self.light_client_finality_update, GossipKind::LightClientOptimisticUpdate => self.light_client_optimistic_update, + GossipKind::Eip6110 => None, }; let expire_timeout = match expire_timeout { Some(expire_timeout) => expire_timeout, diff --git a/beacon_node/lighthouse_network/src/types/pubsub.rs b/beacon_node/lighthouse_network/src/types/pubsub.rs index b9b11385a7b..a579da7e423 100644 --- a/beacon_node/lighthouse_network/src/types/pubsub.rs +++ b/beacon_node/lighthouse_network/src/types/pubsub.rs @@ -282,6 +282,13 @@ impl PubsubMessage { light_client_optimistic_update, ))) } + GossipKind::Eip6110 => { + let eip6110 = SignedBeaconBlockEip6110::from_ssz_bytes(data) + .map_err(|e| format!("{:?}", e))?; + Ok(PubsubMessage::BeaconBlock(Arc::new( + SignedBeaconBlock::Eip6110(eip6110), + ))) + } } } } diff --git a/beacon_node/lighthouse_network/src/types/topics.rs b/beacon_node/lighthouse_network/src/types/topics.rs index 50af4a56ad4..913b7b76c09 100644 --- a/beacon_node/lighthouse_network/src/types/topics.rs +++ b/beacon_node/lighthouse_network/src/types/topics.rs @@ -22,6 +22,7 @@ pub const SYNC_COMMITTEE_PREFIX_TOPIC: &str = "sync_committee_"; pub const BLS_TO_EXECUTION_CHANGE_TOPIC: &str = "bls_to_execution_change"; pub const LIGHT_CLIENT_FINALITY_UPDATE: &str = "light_client_finality_update"; pub const LIGHT_CLIENT_OPTIMISTIC_UPDATE: &str = "light_client_optimistic_update"; +pub const EIP_6110_TOPIC: &str = "eip_6110"; pub const BASE_CORE_TOPICS: [GossipKind; 5] = [ GossipKind::BeaconBlock, @@ -59,7 +60,7 @@ pub fn fork_core_topics(fork_name: &ForkName) -> Vec { deneb_topics.append(&mut deneb_blob_topics); deneb_topics } - ForkName::Eip6110 => vec![], + ForkName::Eip6110 => vec![GossipKind::Eip6110], } } @@ -118,6 +119,8 @@ pub enum GossipKind { LightClientFinalityUpdate, /// Topic for publishing optimistic updates for light clients. LightClientOptimisticUpdate, + /// Topic for publishing EIP-6110 messages. + Eip6110, } impl std::fmt::Display for GossipKind { @@ -258,6 +261,7 @@ impl std::fmt::Display for GossipTopic { GossipKind::BlsToExecutionChange => BLS_TO_EXECUTION_CHANGE_TOPIC.into(), GossipKind::LightClientFinalityUpdate => LIGHT_CLIENT_FINALITY_UPDATE.into(), GossipKind::LightClientOptimisticUpdate => LIGHT_CLIENT_OPTIMISTIC_UPDATE.into(), + GossipKind::Eip6110 => EIP_6110_TOPIC.into(), }; write!( f, diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 4f80b57a52d..4376a65bea9 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -7,7 +7,7 @@ use std::borrow::Cow; use tree_hash::TreeHash; use types::*; -use self::process_operations::apply_deposit; +use self::process_operations::process_deposit; pub use self::verify_attester_slashing::{ get_slashable_indices, get_slashable_indices_modular, verify_attester_slashing, }; @@ -459,7 +459,7 @@ pub fn process_deposit_receipt( }; // Call apply with the created Deposit object - apply_deposit(state, &deposit, spec)?; + process_deposit(state, &deposit, spec, false)?; Ok(()) } diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 94358c12bb2..f6650ae6c1d 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -16,9 +16,12 @@ pub fn process_operations>( ctxt: &mut ConsensusContext, spec: &ChainSpec, ) -> Result<(), BlockProcessingError> { - let eth1_deposit_index_limit = state - .deposit_receipts_start_index() - .unwrap_or_else(|_| state.eth1_data().deposit_count); + let eth1_deposit_index_limit = std::cmp::min( + state.eth1_data().deposit_count, + state + .deposit_receipts_start_index() + .unwrap_or_else(|_| state.eth1_data().deposit_count), + ); let expected_deposit_count = if state.eth1_deposit_index() < eth1_deposit_index_limit { let diff = eth1_deposit_index_limit @@ -52,8 +55,8 @@ pub fn process_operations>( spec, )?; process_attestations(state, block_body, verify_signatures, ctxt, spec)?; - process_deposits(state, block_body.deposits(), spec)?; process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?; + process_deposits(state, block_body.deposits(), spec)?; if let Ok(bls_to_execution_changes) = block_body.bls_to_execution_changes() { process_bls_to_execution_changes(state, bls_to_execution_changes, verify_signatures, spec)?; @@ -453,51 +456,3 @@ pub fn process_deposit( Ok(()) } - -pub fn apply_deposit( - state: &mut BeaconState, - deposit: &Deposit, - spec: &ChainSpec, -) -> Result<(), BlockProcessingError> { - let amount = deposit.data.amount; - - if let Ok(Some(index)) = get_existing_validator_index(state, &deposit.data.pubkey) { - // Update the existing validator balance. - increase_balance(state, index as usize, amount)?; - } else { - // The signature should be checked for new validators. Return early for a bad signature. - if verify_deposit_signature(&deposit.data, spec).is_err() { - return Ok(()); - } - - // Create a new validator. - let validator = Validator { - pubkey: deposit.data.pubkey, - withdrawal_credentials: deposit.data.withdrawal_credentials, - activation_eligibility_epoch: spec.far_future_epoch, - activation_epoch: spec.far_future_epoch, - exit_epoch: spec.far_future_epoch, - withdrawable_epoch: spec.far_future_epoch, - effective_balance: std::cmp::min( - amount.safe_sub(amount.safe_rem(spec.effective_balance_increment)?)?, - spec.max_effective_balance, - ), - slashed: false, - }; - state.validators_mut().push(validator)?; - state.balances_mut().push(deposit.data.amount)?; - - // Altair or later initializations. - if let Ok(previous_epoch_participation) = state.previous_epoch_participation_mut() { - previous_epoch_participation.push(ParticipationFlags::default())?; - } - if let Ok(current_epoch_participation) = state.current_epoch_participation_mut() { - current_epoch_participation.push(ParticipationFlags::default())?; - } - if let Ok(inactivity_scores) = state.inactivity_scores_mut() { - inactivity_scores.push(0)?; - } - } - - Ok(()) -} From 701e534879c9d72cadfbaafd567a1e409156f5e7 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Wed, 7 Jun 2023 12:12:34 +0200 Subject: [PATCH 49/52] Fixed `process_operations` for EIP-6110 --- .../per_block_processing/process_operations.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index f6650ae6c1d..ece677dd9ea 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -55,18 +55,25 @@ pub fn process_operations>( spec, )?; process_attestations(state, block_body, verify_signatures, ctxt, spec)?; - process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?; process_deposits(state, block_body.deposits(), spec)?; + process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?; if let Ok(bls_to_execution_changes) = block_body.bls_to_execution_changes() { process_bls_to_execution_changes(state, bls_to_execution_changes, verify_signatures, spec)?; } if let Ok(payload) = block_body.execution_payload() { - if is_execution_enabled(state, block_body) { - let deposit_receipts = payload.deposit_receipts()?; - for deposit_receipt in deposit_receipts.iter() { - process_deposit_receipt(state, deposit_receipt, spec)?; + match payload.deposit_receipts() { + Ok(deposit_receipts) => { + // Check if there are any deposit receipts + if !deposit_receipts.is_empty() { + for deposit_receipt in deposit_receipts.iter() { + process_deposit_receipt(state, deposit_receipt, spec)?; + } + } + } + Err(_) => { + // No deposit receipts, do nothing } } } From 886df787d209491d0aa1d7546499244cddff5c05 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Thu, 22 Jun 2023 10:39:59 +0200 Subject: [PATCH 50/52] fix clippy --- .../src/per_block_processing.rs | 17 ++++++++++------- .../per_block_processing/process_operations.rs | 14 +++----------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 4376a65bea9..0aa28ae8c1d 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -435,10 +435,10 @@ pub fn process_deposit_receipt( ) -> Result<(), BlockProcessingError> { match state { BeaconState::Eip6110(_) => { - // Set deposit receipt start index let start_index = state .deposit_receipts_start_index() .map_err(|_| BlockProcessingError::DepositReceiptError)?; + if start_index == UNSET_DEPOSIT_RECEIPTS_START_INDEX { *state .deposit_receipts_start_index_mut() @@ -446,25 +446,28 @@ pub fn process_deposit_receipt( deposit_receipt.index; } - // Create a Deposit object from the DepositReceipt let deposit_data = DepositData { pubkey: deposit_receipt.pubkey, withdrawal_credentials: deposit_receipt.withdrawal_credentials, amount: deposit_receipt.amount, signature: deposit_receipt.signature.clone(), }; + let deposit = Deposit { - proof: FixedVector::from_elem(Hash256::zero()), // Set an empty proof, since it's not included in DepositReceipt + proof: FixedVector::from_elem(Hash256::zero()), data: deposit_data, }; - // Call apply with the created Deposit object process_deposit(state, &deposit, spec, false)?; - - Ok(()) } - _ => Ok(()), // Do nothing for other states + BeaconState::Base(_) + | BeaconState::Altair(_) + | BeaconState::Merge(_) + | BeaconState::Capella(_) + | BeaconState::Deneb(_) => {} } + + Ok(()) } /// These functions will definitely be called before the merge. Their entire purpose is to check if diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index ece677dd9ea..031f30a0dab 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -63,17 +63,9 @@ pub fn process_operations>( } if let Ok(payload) = block_body.execution_payload() { - match payload.deposit_receipts() { - Ok(deposit_receipts) => { - // Check if there are any deposit receipts - if !deposit_receipts.is_empty() { - for deposit_receipt in deposit_receipts.iter() { - process_deposit_receipt(state, deposit_receipt, spec)?; - } - } - } - Err(_) => { - // No deposit receipts, do nothing + if let Ok(deposit_receipts) = payload.deposit_receipts() { + for deposit_receipt in deposit_receipts.iter() { + process_deposit_receipt(state, deposit_receipt, spec)?; } } } From 2c8984a19adf927e73e9b2d0a38d59612591dff4 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Fri, 23 Jun 2023 21:12:36 +0200 Subject: [PATCH 51/52] fix `apply_deposit` --- .../src/per_block_processing.rs | 76 +++++++++++++------ .../process_operations.rs | 6 +- 2 files changed, 58 insertions(+), 24 deletions(-) diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 0aa28ae8c1d..ec2bdee4faa 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -1,22 +1,20 @@ -use crate::consensus_context::ConsensusContext; -use errors::{BlockOperationError, BlockProcessingError, HeaderInvalid}; -use rayon::prelude::*; -use safe_arith::{ArithError, SafeArith}; -use signature_sets::{block_proposal_signature_set, get_pubkey_from_state, randao_signature_set}; -use std::borrow::Cow; -use tree_hash::TreeHash; -use types::*; - -use self::process_operations::process_deposit; pub use self::verify_attester_slashing::{ get_slashable_indices, get_slashable_indices_modular, verify_attester_slashing, }; pub use self::verify_proposer_slashing::verify_proposer_slashing; +use crate::consensus_context::ConsensusContext; pub use altair::sync_committee::process_sync_aggregate; pub use block_signature_verifier::{BlockSignatureVerifier, ParallelSignatureSets}; pub use deneb::deneb::process_blob_kzg_commitments; +use errors::{BlockOperationError, BlockProcessingError, HeaderInvalid}; pub use is_valid_indexed_attestation::is_valid_indexed_attestation; pub use process_operations::process_operations; +use rayon::prelude::*; +use safe_arith::{ArithError, SafeArith}; +use signature_sets::{block_proposal_signature_set, get_pubkey_from_state, randao_signature_set}; +use std::borrow::Cow; +use tree_hash::TreeHash; +use types::*; pub use verify_attestation::{ verify_attestation_for_block_inclusion, verify_attestation_for_state, }; @@ -41,7 +39,7 @@ mod verify_deposit; mod verify_exit; mod verify_proposer_slashing; -use crate::common::decrease_balance; +use crate::common::{decrease_balance, increase_balance}; use crate::StateProcessingStrategy; #[cfg(feature = "arbitrary-fuzz")] @@ -446,20 +444,52 @@ pub fn process_deposit_receipt( deposit_receipt.index; } - let deposit_data = DepositData { - pubkey: deposit_receipt.pubkey, - withdrawal_credentials: deposit_receipt.withdrawal_credentials, - amount: deposit_receipt.amount, - signature: deposit_receipt.signature.clone(), - }; - - let deposit = Deposit { - proof: FixedVector::from_elem(Hash256::zero()), - data: deposit_data, - }; + // `apply_deposit` logic from `process_deposit` function: + let amount = deposit_receipt.amount; + + if let Ok(Some(index)) = get_existing_validator_index(state, &deposit_receipt.pubkey) { + increase_balance(state, index as usize, amount)?; + } else { + let deposit_data = DepositData { + pubkey: deposit_receipt.pubkey, + withdrawal_credentials: deposit_receipt.withdrawal_credentials, + amount: deposit_receipt.amount, + signature: deposit_receipt.signature.clone(), + }; + + if verify_deposit_signature(&deposit_data, spec).is_err() { + return Ok(()); + } - process_deposit(state, &deposit, spec, false)?; + let remainder = amount.safe_rem(spec.effective_balance_increment)?; + let effective_balance = + std::cmp::min(amount.safe_sub(remainder)?, spec.max_effective_balance); + + let validator = Validator { + pubkey: deposit_receipt.pubkey, + withdrawal_credentials: deposit_receipt.withdrawal_credentials, + activation_eligibility_epoch: spec.far_future_epoch, + activation_epoch: spec.far_future_epoch, + exit_epoch: spec.far_future_epoch, + withdrawable_epoch: spec.far_future_epoch, + effective_balance, + slashed: false, + }; + state.validators_mut().push(validator)?; + state.balances_mut().push(deposit_receipt.amount)?; + + if let Ok(previous_epoch_participation) = state.previous_epoch_participation_mut() { + previous_epoch_participation.push(ParticipationFlags::default())?; + } + if let Ok(current_epoch_participation) = state.current_epoch_participation_mut() { + current_epoch_participation.push(ParticipationFlags::default())?; + } + if let Ok(inactivity_scores) = state.inactivity_scores_mut() { + inactivity_scores.push(0)?; + } + } } + BeaconState::Base(_) | BeaconState::Altair(_) | BeaconState::Merge(_) diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 031f30a0dab..9480be7ef8e 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -55,7 +55,6 @@ pub fn process_operations>( spec, )?; process_attestations(state, block_body, verify_signatures, ctxt, spec)?; - process_deposits(state, block_body.deposits(), spec)?; process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?; if let Ok(bls_to_execution_changes) = block_body.bls_to_execution_changes() { @@ -70,6 +69,11 @@ pub fn process_operations>( } } + // Only process deposits if expected_deposit_count is not zero. + if expected_deposit_count > 0 { + process_deposits(state, block_body.deposits(), spec)?; + } + Ok(()) } From 35fa50e60489dd6cd5deaa088aa6204746e5469b Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Mon, 3 Jul 2023 14:35:45 +0200 Subject: [PATCH 52/52] fix `single_block_lookup_request` disable Eth1Data --- .../network/src/sync/network_context.rs | 36 ++++++------------- lcli/src/new_testnet.rs | 9 ++--- 2 files changed, 14 insertions(+), 31 deletions(-) diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index ced6aeb52ed..82d564873bc 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -409,40 +409,26 @@ impl SyncNetworkContext { } } - /// Sends a blocks by root request for a single block lookup. + /// Sends a blocks by root request for a parent request. pub fn single_block_lookup_request( &mut self, peer_id: PeerId, request: BlocksByRootRequest, ) -> Result { - let request = if self - .chain - .is_data_availability_check_required() - .map_err(|_| "Unable to read slot clock")? - { - trace!( - self.log, - "Sending BlobsByRoot Request"; - "method" => "BlobsByRoot", - "count" => request.block_roots.len(), - "peer" => %peer_id - ); - unimplemented!("There is no longer such thing as a single block lookup, since we nede to ask for blobs and blocks separetely"); - } else { - trace!( - self.log, - "Sending BlocksByRoot Request"; - "method" => "BlocksByRoot", - "count" => request.block_roots.len(), - "peer" => %peer_id - ); - Request::BlocksByRoot(request) - }; let id = self.next_id(); let request_id = RequestId::Sync(SyncRequestId::SingleBlock { id }); + + trace!( + self.log, + "Sending BlocksByRoot Request"; + "method" => "BlocksByRoot", + "count" => request.block_roots.len(), + "peer" => %peer_id + ); + self.send_network_msg(NetworkMessage::SendRequest { peer_id, - request, + request: Request::BlocksByRoot(request), request_id, })?; Ok(id) diff --git a/lcli/src/new_testnet.rs b/lcli/src/new_testnet.rs index 5329a6aa8de..82843a232cb 100644 --- a/lcli/src/new_testnet.rs +++ b/lcli/src/new_testnet.rs @@ -14,7 +14,6 @@ use state_processing::upgrade::{upgrade_to_altair, upgrade_to_bellatrix}; use std::fs::File; use std::io::Read; use std::path::PathBuf; -use std::str::FromStr; use std::time::{SystemTime, UNIX_EPOCH}; use types::ExecutionBlockHash; use types::{ @@ -252,13 +251,11 @@ fn initialize_state_with_validators( }); let execution_payload_header = execution_payload_header.unwrap_or(default_header); // Empty eth1 data + // EIP-6110 disable Eth1Data voting by zeroing out the deposit root and block hash let eth1_data = Eth1Data { - block_hash: eth1_block_hash, + block_hash: Hash256::zero(), deposit_count: 0, - deposit_root: Hash256::from_str( - "0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e", - ) - .unwrap(), // empty deposit tree root + deposit_root: Hash256::zero(), }; let mut state = BeaconState::new(genesis_time, eth1_data, spec);