diff --git a/beacon_node/beacon_chain/src/block_verification.rs b/beacon_node/beacon_chain/src/block_verification.rs index e2ddb4e7b..de807a6a4 100644 --- a/beacon_node/beacon_chain/src/block_verification.rs +++ b/beacon_node/beacon_chain/src/block_verification.rs @@ -278,18 +278,6 @@ pub enum ExecutionPayloadError { /// /// The block is invalid and the peer is faulty InvalidPayloadTimestamp { expected: u64, found: u64 }, - /// The gas used in the block exceeds the gas limit - /// - /// ## Peer scoring - /// - /// The block is invalid and the peer is faulty - GasUsedExceedsLimit, - /// The payload block hash equals the parent hash - /// - /// ## Peer scoring - /// - /// The block is invalid and the peer is faulty - BlockHashEqualsParentHash, /// The execution payload transaction list data exceeds size limits /// /// ## Peer scoring @@ -1353,18 +1341,6 @@ fn validate_execution_payload( }, )); } - // Gas used is less than the gas limit - if execution_payload.gas_used > execution_payload.gas_limit { - return Err(BlockError::ExecutionPayloadError( - ExecutionPayloadError::GasUsedExceedsLimit, - )); - } - // The execution payload block hash is not equal to the parent hash - if execution_payload.block_hash == execution_payload.parent_hash { - return Err(BlockError::ExecutionPayloadError( - ExecutionPayloadError::BlockHashEqualsParentHash, - )); - } // The execution payload transaction list data is within expected size limits if execution_payload.transactions.len() > T::EthSpec::max_transactions_per_payload() { return Err(BlockError::ExecutionPayloadError( diff --git a/beacon_node/client/src/builder.rs b/beacon_node/client/src/builder.rs index d1ea77234..186bc9ed1 100644 --- a/beacon_node/client/src/builder.rs +++ b/beacon_node/client/src/builder.rs @@ -152,7 +152,7 @@ where .terminal_total_difficulty_override .unwrap_or(spec.terminal_total_difficulty); let terminal_block_hash = config - .terminal_block_hash + .terminal_block_hash_override .unwrap_or(spec.terminal_block_hash); let execution_layer = if let Some(execution_endpoints) = config.execution_endpoints { diff --git a/beacon_node/client/src/config.rs b/beacon_node/client/src/config.rs index f65b024ce..53d307966 100644 --- a/beacon_node/client/src/config.rs +++ b/beacon_node/client/src/config.rs @@ -1,3 +1,4 @@ +use beacon_chain::types::Epoch; use directory::DEFAULT_ROOT_DIR; use network::NetworkConfig; use sensitive_url::SensitiveUrl; @@ -76,7 +77,8 @@ pub struct Config { pub eth1: eth1::Config, pub execution_endpoints: Option>, pub terminal_total_difficulty_override: Option, - pub terminal_block_hash: Option, + pub terminal_block_hash_override: Option, + pub terminal_block_hash_epoch_override: Option, pub fee_recipient: Option
, pub http_api: http_api::Config, pub http_metrics: http_metrics::Config, @@ -100,7 +102,8 @@ impl Default for Config { eth1: <_>::default(), execution_endpoints: None, terminal_total_difficulty_override: None, - terminal_block_hash: None, + terminal_block_hash_override: None, + terminal_block_hash_epoch_override: None, fee_recipient: None, disabled_forks: Vec::new(), graffiti: Graffiti::default(), diff --git a/beacon_node/execution_layer/src/engine_api/http.rs b/beacon_node/execution_layer/src/engine_api/http.rs index a4ec9232e..8b393d93a 100644 --- a/beacon_node/execution_layer/src/engine_api/http.rs +++ b/beacon_node/execution_layer/src/engine_api/http.rs @@ -308,7 +308,8 @@ pub struct JsonExecutionPayload { pub base_fee_per_gas: Uint256, pub block_hash: Hash256, #[serde(with = "serde_transactions")] - pub transactions: VariableList, T::MaxTransactionsPerPayload>, + pub transactions: + VariableList, T::MaxTransactionsPerPayload>, } impl From> for JsonExecutionPayload { @@ -410,16 +411,16 @@ pub mod serde_transactions { use serde::{de, Deserializer, Serializer}; use std::marker::PhantomData; - type Value = VariableList, N>; + type Value = VariableList, N>; #[derive(Default)] - pub struct ListOfBytesListVisitor { - _phantom_t: PhantomData, + pub struct ListOfBytesListVisitor { + _phantom_m: PhantomData, _phantom_n: PhantomData, } - impl<'a, T: EthSpec, N: Unsigned> serde::de::Visitor<'a> for ListOfBytesListVisitor { - type Value = Value; + impl<'a, M: Unsigned, N: Unsigned> serde::de::Visitor<'a> for ListOfBytesListVisitor { + type Value = Value; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { write!(formatter, "a list of 0x-prefixed byte lists") @@ -433,10 +434,9 @@ pub mod serde_transactions { while let Some(val) = seq.next_element::()? { let inner_vec = hex::decode(&val).map_err(de::Error::custom)?; - let opaque_transaction = VariableList::new(inner_vec).map_err(|e| { + let transaction = VariableList::new(inner_vec).map_err(|e| { serde::de::Error::custom(format!("transaction too large: {:?}", e)) })?; - let transaction = Transaction::OpaqueTransaction(opaque_transaction); outer.push(transaction).map_err(|e| { serde::de::Error::custom(format!("too many transactions: {:?}", e)) })?; @@ -446,8 +446,8 @@ pub mod serde_transactions { } } - pub fn serialize( - value: &Value, + pub fn serialize( + value: &Value, serializer: S, ) -> Result where @@ -458,21 +458,19 @@ pub mod serde_transactions { // It's important to match on the inner values of the transaction. Serializing the // entire `Transaction` will result in appending the SSZ union prefix byte. The // execution node does not want that. - let hex = match transaction { - Transaction::OpaqueTransaction(val) => hex::encode(&val[..]), - }; + let hex = hex::encode(&transaction[..]); seq.serialize_element(&hex)?; } seq.end() } - pub fn deserialize<'de, D, T: EthSpec, N: Unsigned>( + pub fn deserialize<'de, D, M: Unsigned, N: Unsigned>( deserializer: D, - ) -> Result, D::Error> + ) -> Result, D::Error> where D: Deserializer<'de>, { - let visitor: ListOfBytesListVisitor = <_>::default(); + let visitor: ListOfBytesListVisitor = <_>::default(); deserializer.deserialize_any(visitor) } } @@ -558,7 +556,10 @@ mod test { const LOGS_BLOOM_01: &str = "0x01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"; fn encode_transactions( - transactions: VariableList, E::MaxTransactionsPerPayload>, + transactions: VariableList< + Transaction, + E::MaxTransactionsPerPayload, + >, ) -> Result { let ep: JsonExecutionPayload = JsonExecutionPayload { transactions, @@ -570,7 +571,10 @@ mod test { fn decode_transactions( transactions: serde_json::Value, - ) -> Result, E::MaxTransactionsPerPayload>, serde_json::Error> { + ) -> Result< + VariableList, E::MaxTransactionsPerPayload>, + serde_json::Error, + > { let json = json!({ "parentHash": HASH_00, "coinbase": ADDRESS_01, @@ -593,17 +597,17 @@ mod test { fn assert_transactions_serde( name: &str, - as_obj: VariableList, E::MaxTransactionsPerPayload>, + as_obj: VariableList, E::MaxTransactionsPerPayload>, as_json: serde_json::Value, ) { assert_eq!( - encode_transactions(as_obj.clone()).unwrap(), + encode_transactions::(as_obj.clone()).unwrap(), as_json, "encoding for {}", name ); assert_eq!( - decode_transactions(as_json).unwrap(), + decode_transactions::(as_json).unwrap(), as_obj, "decoding for {}", name @@ -611,9 +615,9 @@ mod test { } /// Example: if `spec == &[1, 1]`, then two one-byte transactions will be created. - fn generate_opaque_transactions( + fn generate_transactions( spec: &[usize], - ) -> VariableList, E::MaxTransactionsPerPayload> { + ) -> VariableList, E::MaxTransactionsPerPayload> { let mut txs = VariableList::default(); for &num_bytes in spec { @@ -621,7 +625,7 @@ mod test { for _ in 0..num_bytes { tx.push(0).unwrap(); } - txs.push(Transaction::OpaqueTransaction(tx)).unwrap(); + txs.push(tx).unwrap(); } txs @@ -631,32 +635,32 @@ mod test { fn transaction_serde() { assert_transactions_serde::( "empty", - generate_opaque_transactions(&[]), + generate_transactions::(&[]), json!([]), ); assert_transactions_serde::( "one empty tx", - generate_opaque_transactions(&[0]), + generate_transactions::(&[0]), json!(["0x"]), ); assert_transactions_serde::( "two empty txs", - generate_opaque_transactions(&[0, 0]), + generate_transactions::(&[0, 0]), json!(["0x", "0x"]), ); assert_transactions_serde::( "one one-byte tx", - generate_opaque_transactions(&[1]), + generate_transactions::(&[1]), json!(["0x00"]), ); assert_transactions_serde::( "two one-byte txs", - generate_opaque_transactions(&[1, 1]), + generate_transactions::(&[1, 1]), json!(["0x00", "0x00"]), ); assert_transactions_serde::( "mixed bag", - generate_opaque_transactions(&[0, 1, 3, 0]), + generate_transactions::(&[0, 1, 3, 0]), json!(["0x", "0x00", "0x000000", "0x"]), ); @@ -680,7 +684,7 @@ mod test { use eth2_serde_utils::hex; - let num_max_bytes = ::MaxBytesPerOpaqueTransaction::to_usize(); + let num_max_bytes = ::MaxBytesPerTransaction::to_usize(); let max_bytes = (0..num_max_bytes).map(|_| 0_u8).collect::>(); let too_many_bytes = (0..=num_max_bytes).map(|_| 0_u8).collect::>(); decode_transactions::( diff --git a/beacon_node/src/cli.rs b/beacon_node/src/cli.rs index 7e38ee7a7..d083e8181 100644 --- a/beacon_node/src/cli.rs +++ b/beacon_node/src/cli.rs @@ -420,6 +420,19 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { the broad Ethereum community has elected to override the terminal PoW block. \ Incorrect use of this flag will cause your node to experience a consensus failure. Be extremely careful with this flag.") + .requires("terminal-block-hash-epoch-override") + .takes_value(true) + ) + .arg( + Arg::with_name("terminal-block-hash-epoch-override") + .long("terminal-block-hash-epoch-override") + .value_name("EPOCH") + .help("Used to coordinate manual overrides to the TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH \ + parameter. This flag should only be used if the user has a clear understanding \ + that the broad Ethereum community has elected to override the terminal PoW block. \ + Incorrect use of this flag will cause your node to experience a consensus + failure. Be extremely careful with this flag.") + .requires("terminal-block-hash-override") .takes_value(true) ) .arg( diff --git a/beacon_node/src/config.rs b/beacon_node/src/config.rs index a1eef1a06..fc3ca2cc0 100644 --- a/beacon_node/src/config.rs +++ b/beacon_node/src/config.rs @@ -264,8 +264,10 @@ pub fn get_config( } client_config.fee_recipient = clap_utils::parse_optional(cli_args, "fee-recipient")?; - client_config.terminal_block_hash = - clap_utils::parse_optional(cli_args, "terminal-block-hash")?; + client_config.terminal_block_hash_override = + clap_utils::parse_optional(cli_args, "terminal-block-hash-override")?; + client_config.terminal_block_hash_epoch_override = + clap_utils::parse_optional(cli_args, "terminal-block-hash-epoch-override")?; if let Some(freezer_dir) = cli_args.value_of("freezer-dir") { client_config.freezer_db_path = Some(PathBuf::from(freezer_dir)); diff --git a/consensus/ssz_types/src/serde_utils/list_of_hex_var_list.rs b/consensus/ssz_types/src/serde_utils/list_of_hex_var_list.rs new file mode 100644 index 000000000..e2fd8ddf3 --- /dev/null +++ b/consensus/ssz_types/src/serde_utils/list_of_hex_var_list.rs @@ -0,0 +1,77 @@ +//! Serialize `VaraibleList, N>` as list of 0x-prefixed hex string. +use crate::VariableList; +use serde::{ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer}; +use std::marker::PhantomData; +use typenum::Unsigned; + +#[derive(Deserialize)] +#[serde(transparent)] +pub struct WrappedListOwned( + #[serde(with = "crate::serde_utils::hex_var_list")] VariableList, +); + +#[derive(Serialize)] +#[serde(transparent)] +pub struct WrappedListRef<'a, N: Unsigned>( + #[serde(with = "crate::serde_utils::hex_var_list")] &'a VariableList, +); + +pub fn serialize( + list: &VariableList, N>, + serializer: S, +) -> Result +where + S: Serializer, + M: Unsigned, + N: Unsigned, +{ + let mut seq = serializer.serialize_seq(Some(list.len()))?; + for bytes in list { + seq.serialize_element(&WrappedListRef(bytes))?; + } + seq.end() +} + +#[derive(Default)] +pub struct Visitor { + _phantom_m: PhantomData, + _phantom_n: PhantomData, +} + +impl<'a, M, N> serde::de::Visitor<'a> for Visitor +where + M: Unsigned, + N: Unsigned, +{ + type Value = VariableList, N>; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(formatter, "a list of 0x-prefixed hex bytes") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: serde::de::SeqAccess<'a>, + { + let mut list: VariableList, N> = <_>::default(); + + while let Some(val) = seq.next_element::>()? { + list.push(val.0).map_err(|e| { + serde::de::Error::custom(format!("failed to push value to list: {:?}.", e)) + })?; + } + + Ok(list) + } +} + +pub fn deserialize<'de, D, M, N>( + deserializer: D, +) -> Result, N>, D::Error> +where + D: Deserializer<'de>, + M: Unsigned, + N: Unsigned, +{ + deserializer.deserialize_seq(Visitor::default()) +} diff --git a/consensus/ssz_types/src/serde_utils/mod.rs b/consensus/ssz_types/src/serde_utils/mod.rs index 8c2dd8a03..cd6d49cc8 100644 --- a/consensus/ssz_types/src/serde_utils/mod.rs +++ b/consensus/ssz_types/src/serde_utils/mod.rs @@ -1,4 +1,5 @@ pub mod hex_fixed_vec; pub mod hex_var_list; +pub mod list_of_hex_var_list; pub mod quoted_u64_fixed_vec; pub mod quoted_u64_var_list; diff --git a/consensus/state_processing/src/common/slash_validator.rs b/consensus/state_processing/src/common/slash_validator.rs index 237905a30..e9d94a106 100644 --- a/consensus/state_processing/src/common/slash_validator.rs +++ b/consensus/state_processing/src/common/slash_validator.rs @@ -31,14 +31,11 @@ pub fn slash_validator( .safe_add(validator_effective_balance)?, )?; - let min_slashing_penalty_quotient = match state { - BeaconState::Base(_) => spec.min_slashing_penalty_quotient, - BeaconState::Altair(_) | BeaconState::Merge(_) => spec.min_slashing_penalty_quotient_altair, - }; decrease_balance( state, slashed_index, - validator_effective_balance.safe_div(min_slashing_penalty_quotient)?, + validator_effective_balance + .safe_div(spec.min_slashing_penalty_quotient_for_state(state))?, )?; // Apply proposer and whistleblower rewards diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index b2c489c28..01b79b9d2 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -295,50 +295,6 @@ pub fn get_new_eth1_data( } } -/// https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/beacon-chain.md#is_valid_gas_limit -pub fn verify_is_valid_gas_limit( - payload: &ExecutionPayload, - parent: &ExecutionPayloadHeader, -) -> Result<(), BlockProcessingError> { - // check if payload used too much gas - if payload.gas_used > payload.gas_limit { - return Err(BlockProcessingError::ExecutionInvalidGasLimit { - used: payload.gas_used, - limit: payload.gas_limit, - }); - } - // check if payload changed the gas limit too much - if payload.gas_limit - >= parent - .gas_limit - .safe_add(parent.gas_limit.safe_div(T::gas_limit_denominator())?)? - { - return Err(BlockProcessingError::ExecutionInvalidGasLimitIncrease { - limit: payload.gas_limit, - parent_limit: parent.gas_limit, - }); - } - if payload.gas_limit - <= parent - .gas_limit - .safe_sub(parent.gas_limit.safe_div(T::gas_limit_denominator())?)? - { - return Err(BlockProcessingError::ExecutionInvalidGasLimitDecrease { - limit: payload.gas_limit, - parent_limit: parent.gas_limit, - }); - } - // check if the gas limit is at least the minimum gas limit - if payload.gas_limit < T::min_gas_limit() { - return Err(BlockProcessingError::ExecutionInvalidGasLimitTooSmall { - limit: payload.gas_limit, - min: T::min_gas_limit(), - }); - } - - Ok(()) -} - /// https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/beacon-chain.md#process_execution_payload pub fn process_execution_payload( state: &mut BeaconState, @@ -353,21 +309,6 @@ pub fn process_execution_payload( found: payload.parent_hash, } ); - block_verify!( - payload.block_number - == state - .latest_execution_payload_header()? - .block_number - .safe_add(1)?, - BlockProcessingError::ExecutionBlockNumberIncontiguous { - expected: state - .latest_execution_payload_header()? - .block_number - .safe_add(1)?, - found: payload.block_number, - } - ); - verify_is_valid_gas_limit(payload, state.latest_execution_payload_header()?)?; } block_verify!( payload.random == *state.get_randao_mix(state.current_epoch())?, diff --git a/consensus/state_processing/src/per_block_processing/errors.rs b/consensus/state_processing/src/per_block_processing/errors.rs index c06f3d20e..abfbb621d 100644 --- a/consensus/state_processing/src/per_block_processing/errors.rs +++ b/consensus/state_processing/src/per_block_processing/errors.rs @@ -61,30 +61,10 @@ pub enum BlockProcessingError { expected: Hash256, found: Hash256, }, - ExecutionBlockNumberIncontiguous { - expected: u64, - found: u64, - }, ExecutionRandaoMismatch { expected: Hash256, found: Hash256, }, - ExecutionInvalidGasLimit { - used: u64, - limit: u64, - }, - ExecutionInvalidGasLimitIncrease { - limit: u64, - parent_limit: u64, - }, - ExecutionInvalidGasLimitDecrease { - limit: u64, - parent_limit: u64, - }, - ExecutionInvalidGasLimitTooSmall { - limit: u64, - min: u64, - }, ExecutionInvalidTimestamp { expected: u64, found: u64, diff --git a/consensus/state_processing/src/per_epoch_processing/altair.rs b/consensus/state_processing/src/per_epoch_processing/altair.rs index 3acece267..1011abe28 100644 --- a/consensus/state_processing/src/per_epoch_processing/altair.rs +++ b/consensus/state_processing/src/per_epoch_processing/altair.rs @@ -47,7 +47,6 @@ pub fn process_epoch( process_slashings( state, participation_cache.current_epoch_total_active_balance(), - spec.proportional_slashing_multiplier_altair, spec, )?; diff --git a/consensus/state_processing/src/per_epoch_processing/altair/rewards_and_penalties.rs b/consensus/state_processing/src/per_epoch_processing/altair/rewards_and_penalties.rs index 5906e0f8d..b1c17851d 100644 --- a/consensus/state_processing/src/per_epoch_processing/altair/rewards_and_penalties.rs +++ b/consensus/state_processing/src/per_epoch_processing/altair/rewards_and_penalties.rs @@ -119,7 +119,7 @@ pub fn get_inactivity_penalty_deltas( .safe_mul(state.get_inactivity_score(index)?)?; let penalty_denominator = spec .inactivity_score_bias - .safe_mul(spec.inactivity_penalty_quotient_altair)?; + .safe_mul(spec.inactivity_penalty_quotient_for_state(state))?; delta.penalize(penalty_numerator.safe_div(penalty_denominator)?)?; } deltas diff --git a/consensus/state_processing/src/per_epoch_processing/base.rs b/consensus/state_processing/src/per_epoch_processing/base.rs index 40eff3b40..4ae2207ff 100644 --- a/consensus/state_processing/src/per_epoch_processing/base.rs +++ b/consensus/state_processing/src/per_epoch_processing/base.rs @@ -43,7 +43,6 @@ pub fn process_epoch( process_slashings( state, validator_statuses.total_balances.current_epoch(), - spec.proportional_slashing_multiplier, spec, )?; diff --git a/consensus/state_processing/src/per_epoch_processing/slashings.rs b/consensus/state_processing/src/per_epoch_processing/slashings.rs index ed77018e2..6d5342cd3 100644 --- a/consensus/state_processing/src/per_epoch_processing/slashings.rs +++ b/consensus/state_processing/src/per_epoch_processing/slashings.rs @@ -6,14 +6,15 @@ use types::{BeaconState, BeaconStateError, ChainSpec, EthSpec, Unsigned}; pub fn process_slashings( state: &mut BeaconState, total_balance: u64, - slashing_multiplier: u64, spec: &ChainSpec, ) -> Result<(), Error> { let epoch = state.current_epoch(); let sum_slashings = state.get_all_slashings().iter().copied().safe_sum()?; - let adjusted_total_slashing_balance = - std::cmp::min(sum_slashings.safe_mul(slashing_multiplier)?, total_balance); + let adjusted_total_slashing_balance = std::cmp::min( + sum_slashings.safe_mul(spec.proportional_slashing_multiplier_for_state(state))?, + total_balance, + ); let (validators, balances) = state.validators_and_balances_mut(); for (index, validator) in validators.iter().enumerate() { diff --git a/consensus/types/src/chain_spec.rs b/consensus/types/src/chain_spec.rs index ddf1e0cb8..fbc3739f6 100644 --- a/consensus/types/src/chain_spec.rs +++ b/consensus/types/src/chain_spec.rs @@ -127,11 +127,19 @@ pub struct ChainSpec { pub altair_fork_version: [u8; 4], /// The Altair fork epoch is optional, with `None` representing "Altair never happens". pub altair_fork_epoch: Option, + + /* + * Merge hard fork params + */ + pub inactivity_penalty_quotient_merge: u64, + pub min_slashing_penalty_quotient_merge: u64, + pub proportional_slashing_multiplier_merge: u64, pub merge_fork_version: [u8; 4], /// The Merge fork epoch is optional, with `None` representing "Merge never happens". pub merge_fork_epoch: Option, pub terminal_total_difficulty: Uint256, pub terminal_block_hash: Hash256, + pub terminal_block_hash_activation_epoch: Epoch, /* * Networking @@ -235,6 +243,39 @@ impl ChainSpec { } } + /// For a given `BeaconState`, return the inactivity penalty quotient associated with its variant. + pub fn inactivity_penalty_quotient_for_state(&self, state: &BeaconState) -> u64 { + match state { + BeaconState::Base(_) => self.inactivity_penalty_quotient, + BeaconState::Altair(_) => self.inactivity_penalty_quotient_altair, + BeaconState::Merge(_) => self.inactivity_penalty_quotient_merge, + } + } + + /// For a given `BeaconState`, return the proportional slashing multiplier associated with its variant. + pub fn proportional_slashing_multiplier_for_state( + &self, + state: &BeaconState, + ) -> u64 { + match state { + BeaconState::Base(_) => self.proportional_slashing_multiplier, + BeaconState::Altair(_) => self.proportional_slashing_multiplier_altair, + BeaconState::Merge(_) => self.proportional_slashing_multiplier_merge, + } + } + + /// For a given `BeaconState`, return the minimum slashing penalty quotient associated with its variant. + pub fn min_slashing_penalty_quotient_for_state( + &self, + state: &BeaconState, + ) -> u64 { + match state { + BeaconState::Base(_) => self.min_slashing_penalty_quotient, + BeaconState::Altair(_) => self.min_slashing_penalty_quotient_altair, + BeaconState::Merge(_) => self.min_slashing_penalty_quotient_merge, + } + } + /// Returns a full `Fork` struct for a given epoch. pub fn fork_at_epoch(&self, epoch: Epoch) -> Fork { let current_fork_name = self.fork_name_at_epoch(epoch); @@ -367,7 +408,7 @@ impl ChainSpec { * Constants */ genesis_slot: Slot::new(0), - far_future_epoch: Epoch::new(u64::max_value()), + far_future_epoch: Epoch::new(u64::MAX), base_rewards_per_epoch: 4, deposit_contract_tree_depth: 32, @@ -479,12 +520,22 @@ impl ChainSpec { domain_contribution_and_proof: 9, altair_fork_version: [0x01, 0x00, 0x00, 0x00], altair_fork_epoch: Some(Epoch::new(74240)), + + /* + * Merge hard fork params + */ + inactivity_penalty_quotient_merge: u64::checked_pow(2, 24) + .expect("pow does not overflow"), + min_slashing_penalty_quotient_merge: u64::checked_pow(2, 5) + .expect("pow does not overflow"), + proportional_slashing_multiplier_merge: 3, merge_fork_version: [0x02, 0x00, 0x00, 0x00], merge_fork_epoch: None, terminal_total_difficulty: Uint256::MAX .checked_sub(Uint256::from(2u64.pow(10))) .expect("calculation does not overflow"), terminal_block_hash: Hash256::zero(), + terminal_block_hash_activation_epoch: Epoch::new(u64::MAX), /* * Network specific diff --git a/consensus/types/src/eth_spec.rs b/consensus/types/src/eth_spec.rs index f57aa48af..98b3c4db7 100644 --- a/consensus/types/src/eth_spec.rs +++ b/consensus/types/src/eth_spec.rs @@ -3,13 +3,13 @@ use crate::*; use safe_arith::SafeArith; use serde_derive::{Deserialize, Serialize}; use ssz_types::typenum::{ - Unsigned, U0, U1024, U1099511627776, U128, U16, U16777216, U2, U2048, U32, U4, U4096, U512, - U64, U65536, U8, U8192, + Unsigned, U0, U1024, U1073741824, U1099511627776, U128, U16, U16777216, U2, U2048, U32, U4, + U4096, U512, U64, U65536, U8, U8192, }; use std::fmt::{self, Debug}; use std::str::FromStr; -use ssz_types::typenum::{bit::B0, UInt, U1048576, U16384, U256, U625}; +use ssz_types::typenum::{bit::B0, UInt, U1048576, U256, U625}; pub type U5000 = UInt, B0>, B0>; // 625 * 8 = 5000 const MAINNET: &str = "mainnet"; @@ -86,7 +86,7 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq + /* * New in Merge */ - type MaxBytesPerOpaqueTransaction: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type MaxBytesPerTransaction: Unsigned + Clone + Sync + Send + Debug + PartialEq; type MaxTransactionsPerPayload: Unsigned + Clone + Sync + Send + Debug + PartialEq; type BytesPerLogsBloom: Unsigned + Clone + Sync + Send + Debug + PartialEq; type GasLimitDenominator: Unsigned + Clone + Sync + Send + Debug + PartialEq; @@ -200,9 +200,9 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq + Self::SyncSubcommitteeSize::to_usize() } - /// Returns the `MAX_BYTES_PER_OPAQUE_TRANSACTION` constant for this specification. - fn max_bytes_per_opaque_transaction() -> usize { - Self::MaxBytesPerOpaqueTransaction::to_usize() + /// Returns the `MAX_BYTES_PER_TRANSACTION` constant for this specification. + fn max_bytes_per_transaction() -> usize { + Self::MaxBytesPerTransaction::to_usize() } /// Returns the `MAX_TRANSACTIONS_PER_PAYLOAD` constant for this specification. @@ -214,16 +214,6 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq + fn bytes_per_logs_bloom() -> usize { Self::BytesPerLogsBloom::to_usize() } - - /// Returns the `GAS_LIMIT_DENOMINATOR` constant for this specification. - fn gas_limit_denominator() -> u64 { - Self::GasLimitDenominator::to_u64() - } - - /// Returns the `MIN_GAS_LIMIT` constant for this specification. - fn min_gas_limit() -> u64 { - Self::MinGasLimit::to_u64() - } } /// Macro to inherit some type values from another EthSpec. @@ -258,8 +248,8 @@ impl EthSpec for MainnetEthSpec { type MaxVoluntaryExits = U16; type SyncCommitteeSize = U512; type SyncCommitteeSubnetCount = U4; - type MaxBytesPerOpaqueTransaction = U1048576; - type MaxTransactionsPerPayload = U16384; + type MaxBytesPerTransaction = U1073741824; // 1,073,741,824 + type MaxTransactionsPerPayload = U1048576; // 1,048,576 type BytesPerLogsBloom = U256; type GasLimitDenominator = U1024; type MinGasLimit = U5000; @@ -306,7 +296,7 @@ impl EthSpec for MinimalEthSpec { MaxAttestations, MaxDeposits, MaxVoluntaryExits, - MaxBytesPerOpaqueTransaction, + MaxBytesPerTransaction, MaxTransactionsPerPayload, BytesPerLogsBloom, GasLimitDenominator, diff --git a/consensus/types/src/execution_payload.rs b/consensus/types/src/execution_payload.rs index 44aab5e51..8f16893ac 100644 --- a/consensus/types/src/execution_payload.rs +++ b/consensus/types/src/execution_payload.rs @@ -1,41 +1,10 @@ use crate::{test_utils::TestRandom, *}; use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; -use std::{ops::Index, slice::SliceIndex}; use test_random_derive::TestRandom; use tree_hash_derive::TreeHash; -#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TreeHash)] -#[ssz(enum_behaviour = "union")] -#[tree_hash(enum_behaviour = "union")] -#[serde(tag = "selector", content = "value")] -#[serde(bound = "T: EthSpec")] -pub enum Transaction { - // FIXME(merge): renaming this enum variant to 0 is a bit of a hack... - #[serde(rename = "0")] - OpaqueTransaction( - #[serde(with = "ssz_types::serde_utils::hex_var_list")] - VariableList, - ), -} - -impl> Index for Transaction { - type Output = I::Output; - - #[inline] - fn index(&self, index: I) -> &Self::Output { - match self { - Self::OpaqueTransaction(v) => Index::index(v, index), - } - } -} - -impl From> for Transaction { - fn from(list: VariableList::MaxBytesPerOpaqueTransaction>) -> Self { - Self::OpaqueTransaction(list) - } -} +pub type Transaction = VariableList; #[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] #[derive( @@ -62,8 +31,9 @@ pub struct ExecutionPayload { pub extra_data: VariableList, pub base_fee_per_gas: Hash256, pub block_hash: Hash256, - #[test_random(default)] - pub transactions: VariableList, T::MaxTransactionsPerPayload>, + #[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")] + pub transactions: + VariableList, T::MaxTransactionsPerPayload>, } impl ExecutionPayload { diff --git a/testing/ef_tests/Makefile b/testing/ef_tests/Makefile index 5a4385fd1..dfb9f27a8 100644 --- a/testing/ef_tests/Makefile +++ b/testing/ef_tests/Makefile @@ -1,4 +1,4 @@ -TESTS_TAG := v1.1.3 +TESTS_TAG := v1.1.5 TESTS = general minimal mainnet TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS)) diff --git a/testing/ef_tests/src/cases/epoch_processing.rs b/testing/ef_tests/src/cases/epoch_processing.rs index fa27a94ce..b187d46fe 100644 --- a/testing/ef_tests/src/cases/epoch_processing.rs +++ b/testing/ef_tests/src/cases/epoch_processing.rs @@ -138,7 +138,6 @@ impl EpochTransition for Slashings { process_slashings( state, validator_statuses.total_balances.current_epoch(), - spec.proportional_slashing_multiplier, spec, )?; } @@ -148,7 +147,6 @@ impl EpochTransition for Slashings { altair::ParticipationCache::new(state, spec) .unwrap() .current_epoch_total_active_balance(), - spec.proportional_slashing_multiplier_altair, spec, )?; }