From 84e54bff14b0c3713de11df7dfca7bba50987858 Mon Sep 17 00:00:00 2001 From: dapplion <35266934+dapplion@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:50:08 +0900 Subject: [PATCH] Revert Arced pubkey optimization --- account_manager/src/validator/exit.rs | 8 +- .../beacon_chain/src/attestation_rewards.rs | 4 +- .../beacon_chain/src/beacon_block_reward.rs | 4 +- beacon_node/beacon_chain/src/beacon_chain.rs | 2 +- beacon_node/beacon_chain/src/metrics.rs | 2 +- .../beacon_chain/src/validator_monitor.rs | 16 +- .../src/validator_pubkey_cache.rs | 2 +- beacon_node/genesis/src/interop.rs | 6 +- beacon_node/http_api/src/validator.rs | 2 +- .../http_api/src/validator_inclusion.rs | 4 +- beacon_node/http_api/src/validators.rs | 4 +- beacon_node/operation_pool/src/lib.rs | 8 +- common/eth2/src/types.rs | 12 +- .../proto_array/src/justified_balances.rs | 6 +- .../src/common/initiate_validator_exit.rs | 6 +- .../src/common/slash_validator.rs | 8 +- .../update_progressive_balances_cache.rs | 4 +- consensus/state_processing/src/epoch_cache.rs | 2 +- consensus/state_processing/src/genesis.rs | 8 +- .../src/per_block_processing.rs | 2 +- .../process_operations.rs | 25 +- .../per_block_processing/signature_sets.rs | 2 +- .../verify_bls_to_execution_change.rs | 4 +- .../src/per_block_processing/verify_exit.rs | 4 +- .../base/validator_statuses.rs | 4 +- .../effective_balance_updates.rs | 10 +- .../epoch_processing_summary.rs | 2 +- .../per_epoch_processing/registry_updates.rs | 6 +- .../src/per_epoch_processing/single_pass.rs | 37 +- .../src/per_epoch_processing/slashings.rs | 4 +- consensus/types/benches/benches.rs | 20 +- consensus/types/src/activation_queue.rs | 2 +- consensus/types/src/beacon_state.rs | 28 +- .../types/src/beacon_state/compact_state.rs | 316 ------------------ .../types/src/beacon_state/exit_cache.rs | 4 +- .../types/src/beacon_state/slashings_cache.rs | 2 +- consensus/types/src/beacon_state/tests.rs | 1 - consensus/types/src/lib.rs | 4 +- consensus/types/src/validator.rs | 214 ++---------- lcli/src/new_testnet.rs | 27 +- lcli/src/replace_state_pubkeys.rs | 7 +- testing/state_transition_vectors/src/exit.rs | 11 +- watch/src/updater/mod.rs | 10 +- 43 files changed, 186 insertions(+), 668 deletions(-) delete mode 100644 consensus/types/src/beacon_state/compact_state.rs diff --git a/account_manager/src/validator/exit.rs b/account_manager/src/validator/exit.rs index f5cdd635188..bc9e0ee1dd6 100644 --- a/account_manager/src/validator/exit.rs +++ b/account_manager/src/validator/exit.rs @@ -203,8 +203,8 @@ async fn publish_voluntary_exit( let validator_data = get_validator_data(client, &keypair.pk).await?; match validator_data.status { ValidatorStatus::ActiveExiting => { - let exit_epoch = validator_data.validator.exit_epoch(); - let withdrawal_epoch = validator_data.validator.withdrawable_epoch(); + let exit_epoch = validator_data.validator.exit_epoch; + let withdrawal_epoch = validator_data.validator.withdrawable_epoch; let current_epoch = get_current_epoch::(genesis_data.genesis_time, spec) .ok_or("Failed to get current epoch. Please check your system time")?; eprintln!("Voluntary exit has been accepted into the beacon chain, but not yet finalized. \ @@ -224,7 +224,7 @@ async fn publish_voluntary_exit( ValidatorStatus::ExitedSlashed | ValidatorStatus::ExitedUnslashed => { eprintln!( "Validator has exited on epoch: {}", - validator_data.validator.exit_epoch() + validator_data.validator.exit_epoch ); break; } @@ -250,7 +250,7 @@ async fn get_validator_index_for_exit( ValidatorStatus::ActiveOngoing => { let eligible_epoch = validator_data .validator - .activation_epoch() + .activation_epoch .safe_add(spec.shard_committee_period) .map_err(|e| format!("Failed to calculate eligible epoch, validator activation epoch too high: {:?}", e))?; diff --git a/beacon_node/beacon_chain/src/attestation_rewards.rs b/beacon_node/beacon_chain/src/attestation_rewards.rs index 45b690dc8f3..491b7ef7da9 100644 --- a/beacon_node/beacon_chain/src/attestation_rewards.rs +++ b/beacon_node/beacon_chain/src/attestation_rewards.rs @@ -230,13 +230,13 @@ impl BeaconChain { let mut inactivity_penalty = 0i64; if eligible { - let effective_balance = validator.effective_balance(); + let effective_balance = validator.effective_balance; for flag_index in 0..PARTICIPATION_FLAG_WEIGHTS.len() { let (ideal_reward, penalty) = ideal_rewards_hashmap .get(&(flag_index, effective_balance)) .ok_or(BeaconChainError::AttestationRewardsError)?; - let voted_correctly = !validator.slashed() + let voted_correctly = !validator.slashed && previous_epoch_participation_flags.has_flag(flag_index)?; if voted_correctly { if flag_index == TIMELY_HEAD_FLAG_INDEX { diff --git a/beacon_node/beacon_chain/src/beacon_block_reward.rs b/beacon_node/beacon_chain/src/beacon_block_reward.rs index 9ee5ec41eed..5b70215d225 100644 --- a/beacon_node/beacon_chain/src/beacon_block_reward.rs +++ b/beacon_node/beacon_chain/src/beacon_block_reward.rs @@ -135,7 +135,7 @@ impl BeaconChain { proposer_slashing_reward.safe_add_assign( state .get_validator(proposer_slashing.proposer_index() as usize)? - .effective_balance() + .effective_balance .safe_div(self.spec.whistleblower_reward_quotient)?, )?; } @@ -157,7 +157,7 @@ impl BeaconChain { attester_slashing_reward.safe_add_assign( state .get_validator(attester_index as usize)? - .effective_balance() + .effective_balance .safe_div(self.spec.whistleblower_reward_quotient)?, )?; } diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 3b26de02468..d79157d7515 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -4809,7 +4809,7 @@ impl BeaconChain { let pubkey = state .validators() .get(proposer_index as usize) - .map(|v| *v.pubkey()) + .map(|v| v.pubkey) .ok_or(BlockProductionError::BeaconChain( BeaconChainError::ValidatorIndexUnknown(proposer_index as usize), ))?; diff --git a/beacon_node/beacon_chain/src/metrics.rs b/beacon_node/beacon_chain/src/metrics.rs index 39a6ae344ff..58fe14f3d0d 100644 --- a/beacon_node/beacon_chain/src/metrics.rs +++ b/beacon_node/beacon_chain/src/metrics.rs @@ -1315,7 +1315,7 @@ fn scrape_head_state(state: &BeaconState, state_root: Hash256) { num_active += 1; } - if v.slashed() { + if v.slashed { num_slashed += 1; } diff --git a/beacon_node/beacon_chain/src/validator_monitor.rs b/beacon_node/beacon_chain/src/validator_monitor.rs index e9993fcd397..a63940074b4 100644 --- a/beacon_node/beacon_chain/src/validator_monitor.rs +++ b/beacon_node/beacon_chain/src/validator_monitor.rs @@ -493,10 +493,10 @@ impl ValidatorMonitor { .skip(self.indices.len()) .for_each(|(i, validator)| { let i = i as u64; - if let Some(validator) = self.validators.get_mut(validator.pubkey()) { + if let Some(validator) = self.validators.get_mut(&validator.pubkey) { validator.set_index(i) } - self.indices.insert(i, *validator.pubkey()); + self.indices.insert(i, validator.pubkey); }); // Add missed non-finalized blocks for the monitored validators @@ -536,12 +536,12 @@ impl ValidatorMonitor { metrics::set_int_gauge( &metrics::VALIDATOR_MONITOR_EFFECTIVE_BALANCE_GWEI, &[id], - u64_to_i64(validator.effective_balance()), + u64_to_i64(validator.effective_balance), ); metrics::set_int_gauge( &metrics::VALIDATOR_MONITOR_SLASHED, &[id], - i64::from(validator.slashed()), + i64::from(validator.slashed), ); metrics::set_int_gauge( &metrics::VALIDATOR_MONITOR_ACTIVE, @@ -561,22 +561,22 @@ impl ValidatorMonitor { metrics::set_int_gauge( &metrics::VALIDATOR_ACTIVATION_ELIGIBILITY_EPOCH, &[id], - u64_to_i64(validator.activation_eligibility_epoch()), + u64_to_i64(validator.activation_eligibility_epoch), ); metrics::set_int_gauge( &metrics::VALIDATOR_ACTIVATION_EPOCH, &[id], - u64_to_i64(validator.activation_epoch()), + u64_to_i64(validator.activation_epoch), ); metrics::set_int_gauge( &metrics::VALIDATOR_EXIT_EPOCH, &[id], - u64_to_i64(validator.exit_epoch()), + u64_to_i64(validator.exit_epoch), ); metrics::set_int_gauge( &metrics::VALIDATOR_WITHDRAWABLE_EPOCH, &[id], - u64_to_i64(validator.withdrawable_epoch()), + u64_to_i64(validator.withdrawable_epoch), ); } } diff --git a/beacon_node/beacon_chain/src/validator_pubkey_cache.rs b/beacon_node/beacon_chain/src/validator_pubkey_cache.rs index 7e605733951..e1b50706286 100644 --- a/beacon_node/beacon_chain/src/validator_pubkey_cache.rs +++ b/beacon_node/beacon_chain/src/validator_pubkey_cache.rs @@ -84,7 +84,7 @@ impl ValidatorPubkeyCache { state .validators() .iter_from(self.pubkeys.len())? - .map(|v| *v.pubkey), + .map(|v| v.pubkey), ) } else { Ok(vec![]) diff --git a/beacon_node/genesis/src/interop.rs b/beacon_node/genesis/src/interop.rs index f11eeeac09a..4c78b8efd8f 100644 --- a/beacon_node/genesis/src/interop.rs +++ b/beacon_node/genesis/src/interop.rs @@ -178,7 +178,7 @@ mod test { } for v in state.validators() { - let creds = v.withdrawal_credentials(); + let creds = v.withdrawal_credentials; assert_eq!( creds.as_bytes()[0], spec.bls_withdrawal_prefix_byte, @@ -186,7 +186,7 @@ mod test { ); assert_eq!( &creds.as_bytes()[1..], - &hash(&v.pubkey().as_ssz_bytes())[1..], + &hash(&v.pubkey.as_ssz_bytes())[1..], "rest of withdrawal creds should be pubkey hash" ) } @@ -241,7 +241,7 @@ mod test { } for (index, v) in state.validators().iter().enumerate() { - let withdrawal_credientials = v.withdrawal_credentials(); + let withdrawal_credientials = v.withdrawal_credentials; let creds = withdrawal_credientials.as_bytes(); if index % 2 == 0 { assert_eq!( diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index f54c6424313..7f11ddd8f43 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -14,7 +14,7 @@ pub fn pubkey_to_validator_index( state .validators() .get(index) - .map_or(false, |v| *v.pubkey == *pubkey) + .map_or(false, |v| v.pubkey == *pubkey) }) .map(Result::Ok) .transpose() diff --git a/beacon_node/http_api/src/validator_inclusion.rs b/beacon_node/http_api/src/validator_inclusion.rs index 0a257725741..dd4e137ce66 100644 --- a/beacon_node/http_api/src/validator_inclusion.rs +++ b/beacon_node/http_api/src/validator_inclusion.rs @@ -95,13 +95,13 @@ pub fn validator_inclusion_data( let summary = get_epoch_processing_summary(&mut state, &chain.spec)?; Ok(Some(ValidatorInclusionData { - is_slashed: validator.slashed(), + is_slashed: validator.slashed, is_withdrawable_in_current_epoch: validator.is_withdrawable_at(epoch), is_active_unslashed_in_current_epoch: summary .is_active_unslashed_in_current_epoch(validator_index), is_active_unslashed_in_previous_epoch: summary .is_active_unslashed_in_previous_epoch(validator_index), - current_epoch_effective_balance_gwei: validator.effective_balance(), + current_epoch_effective_balance_gwei: validator.effective_balance, is_current_epoch_target_attester: summary .is_current_epoch_target_attester(validator_index) .map_err(convert_cache_error)?, diff --git a/beacon_node/http_api/src/validators.rs b/beacon_node/http_api/src/validators.rs index 69765d79199..20af7a680df 100644 --- a/beacon_node/http_api/src/validators.rs +++ b/beacon_node/http_api/src/validators.rs @@ -29,7 +29,7 @@ pub fn get_beacon_state_validators( .filter(|(index, (validator, _))| { query_ids.as_ref().map_or(true, |ids| { ids.iter().any(|id| match id { - ValidatorId::PublicKey(pubkey) => validator.pubkey() == pubkey, + ValidatorId::PublicKey(pubkey) => &validator.pubkey == pubkey, ValidatorId::Index(param_index) => { *param_index == *index as u64 } @@ -93,7 +93,7 @@ pub fn get_beacon_state_validator_balances( .filter(|(index, (validator, _))| { optional_ids.map_or(true, |ids| { ids.iter().any(|id| match id { - ValidatorId::PublicKey(pubkey) => validator.pubkey() == pubkey, + ValidatorId::PublicKey(pubkey) => &validator.pubkey == pubkey, ValidatorId::Index(param_index) => { *param_index == *index as u64 } diff --git a/beacon_node/operation_pool/src/lib.rs b/beacon_node/operation_pool/src/lib.rs index fee8a49c51d..91cd17e3c84 100644 --- a/beacon_node/operation_pool/src/lib.rs +++ b/beacon_node/operation_pool/src/lib.rs @@ -392,7 +392,7 @@ impl OperationPool { && state .validators() .get(slashing.as_inner().signed_header_1.message.proposer_index as usize) - .map_or(false, |validator| !validator.slashed()) + .map_or(false, |validator| !validator.slashed) }, |slashing| slashing.as_inner().clone(), E::MaxProposerSlashings::to_usize(), @@ -451,7 +451,7 @@ impl OperationPool { pub fn prune_proposer_slashings(&self, head_state: &BeaconState) { prune_validator_hash_map( &mut self.proposer_slashings.write(), - |_, validator| validator.exit_epoch() <= head_state.finalized_checkpoint().epoch, + |_, validator| validator.exit_epoch <= head_state.finalized_checkpoint().epoch, head_state, ); } @@ -470,7 +470,7 @@ impl OperationPool { // // We cannot check the `slashed` field since the `head` is not finalized and // a fork could un-slash someone. - validator.exit_epoch() > head_state.finalized_checkpoint().epoch + validator.exit_epoch > head_state.finalized_checkpoint().epoch }) .map_or(false, |indices| !indices.is_empty()); @@ -527,7 +527,7 @@ impl OperationPool { // // We choose simplicity over the gain of pruning more exits since they are small and // should not be seen frequently. - |_, validator| validator.exit_epoch() <= head_state.finalized_checkpoint().epoch, + |_, validator| validator.exit_epoch <= head_state.finalized_checkpoint().epoch, head_state, ); } diff --git a/common/eth2/src/types.rs b/common/eth2/src/types.rs index 04e37ed1935..5f85d777957 100644 --- a/common/eth2/src/types.rs +++ b/common/eth2/src/types.rs @@ -375,20 +375,20 @@ pub enum ValidatorStatus { impl ValidatorStatus { pub fn from_validator(validator: &Validator, epoch: Epoch, far_future_epoch: Epoch) -> Self { if validator.is_withdrawable_at(epoch) { - if validator.effective_balance() == 0 { + if validator.effective_balance == 0 { ValidatorStatus::WithdrawalDone } else { ValidatorStatus::WithdrawalPossible } - } else if validator.is_exited_at(epoch) && epoch < validator.withdrawable_epoch() { - if validator.slashed() { + } else if validator.is_exited_at(epoch) && epoch < validator.withdrawable_epoch { + if validator.slashed { ValidatorStatus::ExitedSlashed } else { ValidatorStatus::ExitedUnslashed } } else if validator.is_active_at(epoch) { - if validator.exit_epoch() < far_future_epoch { - if validator.slashed() { + if validator.exit_epoch < far_future_epoch { + if validator.slashed { ValidatorStatus::ActiveSlashed } else { ValidatorStatus::ActiveExiting @@ -399,7 +399,7 @@ impl ValidatorStatus { // `pending` statuses are specified as validators where `validator.activation_epoch > current_epoch`. // If this code is reached, this criteria must have been met because `validator.is_active_at(epoch)`, // `validator.is_exited_at(epoch)`, and `validator.is_withdrawable_at(epoch)` all returned false. - } else if validator.activation_eligibility_epoch() == far_future_epoch { + } else if validator.activation_eligibility_epoch == far_future_epoch { ValidatorStatus::PendingInitialized } else { ValidatorStatus::PendingQueued diff --git a/consensus/proto_array/src/justified_balances.rs b/consensus/proto_array/src/justified_balances.rs index daff362209a..e08c8443eef 100644 --- a/consensus/proto_array/src/justified_balances.rs +++ b/consensus/proto_array/src/justified_balances.rs @@ -24,11 +24,11 @@ impl JustifiedBalances { .validators() .iter() .map(|validator| { - if !validator.slashed() && validator.is_active_at(current_epoch) { - total_effective_balance.safe_add_assign(validator.effective_balance())?; + if !validator.slashed && validator.is_active_at(current_epoch) { + total_effective_balance.safe_add_assign(validator.effective_balance)?; num_active_validators.safe_add_assign(1)?; - Ok(validator.effective_balance()) + Ok(validator.effective_balance) } else { Ok(0) } diff --git a/consensus/state_processing/src/common/initiate_validator_exit.rs b/consensus/state_processing/src/common/initiate_validator_exit.rs index 4abe326cb1c..c6565a76b0a 100644 --- a/consensus/state_processing/src/common/initiate_validator_exit.rs +++ b/consensus/state_processing/src/common/initiate_validator_exit.rs @@ -33,13 +33,13 @@ pub fn initiate_validator_exit( let validator = state.get_validator_cow(index)?; // Return if the validator already initiated exit - if validator.exit_epoch() != spec.far_future_epoch { + if validator.exit_epoch != spec.far_future_epoch { return Ok(()); } let validator = validator.into_mut()?; - validator.mutable.exit_epoch = exit_queue_epoch; - validator.mutable.withdrawable_epoch = + validator.exit_epoch = exit_queue_epoch; + validator.withdrawable_epoch = exit_queue_epoch.safe_add(spec.min_validator_withdrawability_delay)?; state diff --git a/consensus/state_processing/src/common/slash_validator.rs b/consensus/state_processing/src/common/slash_validator.rs index da84b0af135..16b4e74ece9 100644 --- a/consensus/state_processing/src/common/slash_validator.rs +++ b/consensus/state_processing/src/common/slash_validator.rs @@ -25,12 +25,12 @@ pub fn slash_validator( initiate_validator_exit(state, slashed_index, spec)?; let validator = state.get_validator_mut(slashed_index)?; - validator.mutable.slashed = true; - validator.mutable.withdrawable_epoch = cmp::max( - validator.withdrawable_epoch(), + validator.slashed = true; + validator.withdrawable_epoch = cmp::max( + validator.withdrawable_epoch, epoch.safe_add(E::EpochsPerSlashingsVector::to_u64())?, ); - let validator_effective_balance = validator.effective_balance(); + let validator_effective_balance = validator.effective_balance; state.set_slashings( epoch, state diff --git a/consensus/state_processing/src/common/update_progressive_balances_cache.rs b/consensus/state_processing/src/common/update_progressive_balances_cache.rs index 280b5377ab9..af843b3acbc 100644 --- a/consensus/state_processing/src/common/update_progressive_balances_cache.rs +++ b/consensus/state_processing/src/common/update_progressive_balances_cache.rs @@ -35,7 +35,7 @@ pub fn initialize_progressive_balances_cache( .zip(state.previous_epoch_participation()?) { // Exclude slashed validators. We are calculating *unslashed* participating totals. - if validator.slashed() { + if validator.slashed { continue; } @@ -78,7 +78,7 @@ fn update_flag_total_balances( ) -> Result<(), BeaconStateError> { for (flag, balance) in total_balances.total_flag_balances.iter_mut().enumerate() { if participation_flags.has_flag(flag)? { - balance.safe_add_assign(validator.effective_balance())?; + balance.safe_add_assign(validator.effective_balance)?; } } Ok(()) diff --git a/consensus/state_processing/src/epoch_cache.rs b/consensus/state_processing/src/epoch_cache.rs index 1d7473d7350..b2f2d85407e 100644 --- a/consensus/state_processing/src/epoch_cache.rs +++ b/consensus/state_processing/src/epoch_cache.rs @@ -117,7 +117,7 @@ pub fn initialize_epoch_cache( let mut activation_queue = ActivationQueue::default(); for (index, validator) in state.validators().iter().enumerate() { - effective_balances.push(validator.effective_balance()); + effective_balances.push(validator.effective_balance); // Add to speculative activation queue. activation_queue diff --git a/consensus/state_processing/src/genesis.rs b/consensus/state_processing/src/genesis.rs index 88dd94186ae..80c0e6fdc33 100644 --- a/consensus/state_processing/src/genesis.rs +++ b/consensus/state_processing/src/genesis.rs @@ -159,13 +159,13 @@ pub fn process_activations( .get(index) .copied() .ok_or(Error::BalancesOutOfBounds(index))?; - validator.mutable.effective_balance = std::cmp::min( + validator.effective_balance = std::cmp::min( balance.safe_sub(balance.safe_rem(spec.effective_balance_increment)?)?, spec.max_effective_balance, ); - if validator.effective_balance() == spec.max_effective_balance { - validator.mutable.activation_eligibility_epoch = E::genesis_epoch(); - validator.mutable.activation_epoch = E::genesis_epoch(); + if validator.effective_balance == spec.max_effective_balance { + validator.activation_eligibility_epoch = E::genesis_epoch(); + validator.activation_epoch = E::genesis_epoch(); } } Ok(()) diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 5d26cd22664..b370ec6216b 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -251,7 +251,7 @@ pub fn process_block_header( // Verify proposer is not slashed verify!( - !state.get_validator(proposer_index as usize)?.slashed(), + !state.get_validator(proposer_index as usize)?.slashed, HeaderInvalid::ProposerSlashed(proposer_index) ); 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 7e114c71c6e..441ce699430 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -5,7 +5,6 @@ use crate::common::{ }; use crate::per_block_processing::errors::{BlockProcessingError, IntoWithIndex}; use crate::VerifySignatures; -use std::sync::Arc; use types::consts::altair::{PARTICIPATION_FLAG_WEIGHTS, PROPOSER_WEIGHT, WEIGHT_DENOMINATOR}; pub fn process_operations>( @@ -413,19 +412,17 @@ pub fn process_deposit( // Create a new validator. let validator = Validator { - pubkey: Arc::new(deposit.data.pubkey), - mutable: ValidatorMutable { - 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, - }, + 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)?; diff --git a/consensus/state_processing/src/per_block_processing/signature_sets.rs b/consensus/state_processing/src/per_block_processing/signature_sets.rs index d3d3af096db..163b2cff7a9 100644 --- a/consensus/state_processing/src/per_block_processing/signature_sets.rs +++ b/consensus/state_processing/src/per_block_processing/signature_sets.rs @@ -64,7 +64,7 @@ where .validators() .get(validator_index) .and_then(|v| { - let pk: Option = v.pubkey().decompress().ok(); + let pk: Option = v.pubkey.decompress().ok(); pk }) .map(Cow::Owned) diff --git a/consensus/state_processing/src/per_block_processing/verify_bls_to_execution_change.rs b/consensus/state_processing/src/per_block_processing/verify_bls_to_execution_change.rs index 500355c7543..1e8f25ed10b 100644 --- a/consensus/state_processing/src/per_block_processing/verify_bls_to_execution_change.rs +++ b/consensus/state_processing/src/per_block_processing/verify_bls_to_execution_change.rs @@ -29,7 +29,7 @@ pub fn verify_bls_to_execution_change( verify!( validator - .withdrawal_credentials() + .withdrawal_credentials .as_bytes() .first() .map(|byte| *byte == spec.bls_withdrawal_prefix_byte) @@ -41,7 +41,7 @@ pub fn verify_bls_to_execution_change( // future. let pubkey_hash = hash(address_change.from_bls_pubkey.as_serialized()); verify!( - validator.withdrawal_credentials().as_bytes().get(1..) == pubkey_hash.get(1..), + validator.withdrawal_credentials.as_bytes().get(1..) == pubkey_hash.get(1..), Invalid::WithdrawalCredentialsMismatch ); diff --git a/consensus/state_processing/src/per_block_processing/verify_exit.rs b/consensus/state_processing/src/per_block_processing/verify_exit.rs index 3619feaf857..fc258d38298 100644 --- a/consensus/state_processing/src/per_block_processing/verify_exit.rs +++ b/consensus/state_processing/src/per_block_processing/verify_exit.rs @@ -41,7 +41,7 @@ pub fn verify_exit( // Verify that the validator has not yet exited. verify!( - validator.exit_epoch() == spec.far_future_epoch, + validator.exit_epoch == spec.far_future_epoch, ExitInvalid::AlreadyExited(exit.validator_index) ); @@ -56,7 +56,7 @@ pub fn verify_exit( // Verify the validator has been active long enough. let earliest_exit_epoch = validator - .activation_epoch() + .activation_epoch .safe_add(spec.shard_committee_period)?; verify!( current_epoch >= earliest_exit_epoch, diff --git a/consensus/state_processing/src/per_epoch_processing/base/validator_statuses.rs b/consensus/state_processing/src/per_epoch_processing/base/validator_statuses.rs index fe8db7d2dee..7e244058038 100644 --- a/consensus/state_processing/src/per_epoch_processing/base/validator_statuses.rs +++ b/consensus/state_processing/src/per_epoch_processing/base/validator_statuses.rs @@ -202,9 +202,9 @@ impl ValidatorStatuses { let previous_epoch = state.previous_epoch(); for validator in state.validators().iter() { - let effective_balance = validator.effective_balance(); + let effective_balance = validator.effective_balance; let mut status = ValidatorStatus { - is_slashed: validator.slashed(), + is_slashed: validator.slashed, is_eligible: state.is_eligible_validator(previous_epoch, validator)?, is_withdrawable_in_current_epoch: validator.is_withdrawable_at(current_epoch), current_epoch_effective_balance: effective_balance, diff --git a/consensus/state_processing/src/per_epoch_processing/effective_balance_updates.rs b/consensus/state_processing/src/per_epoch_processing/effective_balance_updates.rs index 146e4a3a8e3..73881e932b7 100644 --- a/consensus/state_processing/src/per_epoch_processing/effective_balance_updates.rs +++ b/consensus/state_processing/src/per_epoch_processing/effective_balance_updates.rs @@ -30,23 +30,23 @@ pub fn process_effective_balance_updates( .ok_or(BeaconStateError::BalancesOutOfBounds(index))?; let new_effective_balance = if balance.safe_add(downward_threshold)? - < validator.effective_balance() - || validator.effective_balance().safe_add(upward_threshold)? < balance + < validator.effective_balance + || validator.effective_balance.safe_add(upward_threshold)? < balance { std::cmp::min( balance.safe_sub(balance.safe_rem(spec.effective_balance_increment)?)?, spec.max_effective_balance, ) } else { - validator.effective_balance() + validator.effective_balance }; if validator.is_active_at(next_epoch) { new_total_active_balance.safe_add_assign(new_effective_balance)?; } - if new_effective_balance != validator.effective_balance() { - validator.into_mut()?.mutable.effective_balance = new_effective_balance; + if new_effective_balance != validator.effective_balance { + validator.into_mut()?.effective_balance = new_effective_balance; } } diff --git a/consensus/state_processing/src/per_epoch_processing/epoch_processing_summary.rs b/consensus/state_processing/src/per_epoch_processing/epoch_processing_summary.rs index 508426af18c..6f48050e161 100644 --- a/consensus/state_processing/src/per_epoch_processing/epoch_processing_summary.rs +++ b/consensus/state_processing/src/per_epoch_processing/epoch_processing_summary.rs @@ -54,7 +54,7 @@ impl ParticipationEpochSummary { pub fn is_active_and_unslashed(&self, val_index: usize, epoch: Epoch) -> bool { self.validators .get(val_index) - .map(|validator| !validator.slashed() && validator.is_active_at(epoch)) + .map(|validator| !validator.slashed && validator.is_active_at(epoch)) .unwrap_or(false) } diff --git a/consensus/state_processing/src/per_epoch_processing/registry_updates.rs b/consensus/state_processing/src/per_epoch_processing/registry_updates.rs index c978a76d059..6b86f9c1e76 100644 --- a/consensus/state_processing/src/per_epoch_processing/registry_updates.rs +++ b/consensus/state_processing/src/per_epoch_processing/registry_updates.rs @@ -17,7 +17,7 @@ pub fn process_registry_updates( let current_epoch = state.current_epoch(); let is_ejectable = |validator: &Validator| { validator.is_active_at(current_epoch) - && validator.effective_balance() <= spec.ejection_balance + && validator.effective_balance <= spec.ejection_balance }; let indices_to_update: Vec<_> = state .validators() @@ -32,7 +32,7 @@ pub fn process_registry_updates( for index in indices_to_update { let validator = state.get_validator_mut(index)?; if validator.is_eligible_for_activation_queue(spec) { - validator.mutable.activation_eligibility_epoch = current_epoch.safe_add(1)?; + validator.activation_eligibility_epoch = current_epoch.safe_add(1)?; } if is_ejectable(validator) { initiate_validator_exit(state, index, spec)?; @@ -50,7 +50,7 @@ pub fn process_registry_updates( let delayed_activation_epoch = state.compute_activation_exit_epoch(current_epoch, spec)?; for index in activation_queue { - state.get_validator_mut(index)?.mutable.activation_epoch = delayed_activation_epoch; + state.get_validator_mut(index)?.activation_epoch = delayed_activation_epoch; } Ok(()) diff --git a/consensus/state_processing/src/per_epoch_processing/single_pass.rs b/consensus/state_processing/src/per_epoch_processing/single_pass.rs index 513fc26b6ff..64ce3f04ea5 100644 --- a/consensus/state_processing/src/per_epoch_processing/single_pass.rs +++ b/consensus/state_processing/src/per_epoch_processing/single_pass.rs @@ -200,8 +200,7 @@ pub fn process_epoch_single_pass( let is_active_current_epoch = validator.is_active_at(current_epoch); let is_active_previous_epoch = validator.is_active_at(previous_epoch); let is_eligible = is_active_previous_epoch - || (validator.slashed() - && previous_epoch.safe_add(1)? < validator.withdrawable_epoch()); + || (validator.slashed && previous_epoch.safe_add(1)? < validator.withdrawable_epoch); let base_reward = if is_eligible { epoch_cache.get_base_reward(index)? @@ -211,10 +210,10 @@ pub fn process_epoch_single_pass( let validator_info = &ValidatorInfo { index, - effective_balance: validator.effective_balance(), + effective_balance: validator.effective_balance, base_reward, is_eligible, - is_slashed: validator.slashed(), + is_slashed: validator.slashed, is_active_current_epoch, is_active_previous_epoch, previous_epoch_participation, @@ -468,17 +467,16 @@ fn process_single_registry_update( let current_epoch = state_ctxt.current_epoch; if validator.is_eligible_for_activation_queue(spec) { - validator.make_mut()?.mutable.activation_eligibility_epoch = current_epoch.safe_add(1)?; + validator.make_mut()?.activation_eligibility_epoch = current_epoch.safe_add(1)?; } - if validator.is_active_at(current_epoch) - && validator.effective_balance() <= spec.ejection_balance + if validator.is_active_at(current_epoch) && validator.effective_balance <= spec.ejection_balance { initiate_validator_exit(validator, exit_cache, state_ctxt, spec)?; } if activation_queue.contains(&validator_info.index) { - validator.make_mut()?.mutable.activation_epoch = + validator.make_mut()?.activation_epoch = spec.compute_activation_exit_epoch(current_epoch)?; } @@ -500,7 +498,7 @@ fn initiate_validator_exit( spec: &ChainSpec, ) -> Result<(), Error> { // Return if the validator already initiated exit - if validator.exit_epoch() != spec.far_future_epoch { + if validator.exit_epoch != spec.far_future_epoch { return Ok(()); } @@ -516,8 +514,8 @@ fn initiate_validator_exit( } let validator = validator.make_mut()?; - validator.mutable.exit_epoch = exit_queue_epoch; - validator.mutable.withdrawable_epoch = + validator.exit_epoch = exit_queue_epoch; + validator.withdrawable_epoch = exit_queue_epoch.safe_add(spec.min_validator_withdrawability_delay)?; exit_cache.record_validator_exit(exit_queue_epoch)?; @@ -554,12 +552,11 @@ fn process_single_slashing( state_ctxt: &StateContext, spec: &ChainSpec, ) -> Result<(), Error> { - if validator.slashed() - && slashings_ctxt.target_withdrawable_epoch == validator.withdrawable_epoch() + if validator.slashed && slashings_ctxt.target_withdrawable_epoch == validator.withdrawable_epoch { let increment = spec.effective_balance_increment; let penalty_numerator = validator - .effective_balance() + .effective_balance .safe_div(increment)? .safe_mul(slashings_ctxt.adjusted_total_slashing_balance)?; let penalty = penalty_numerator @@ -599,11 +596,11 @@ fn process_single_effective_balance_update( state_ctxt: &StateContext, spec: &ChainSpec, ) -> Result<(), Error> { - let old_effective_balance = validator.effective_balance(); + let old_effective_balance = validator.effective_balance; let new_effective_balance = if balance.safe_add(eb_ctxt.downward_threshold)? - < validator.effective_balance() + < validator.effective_balance || validator - .effective_balance() + .effective_balance .safe_add(eb_ctxt.upward_threshold)? < balance { @@ -612,7 +609,7 @@ fn process_single_effective_balance_update( spec.max_effective_balance, ) } else { - validator.effective_balance() + validator.effective_balance }; if validator.is_active_at(state_ctxt.next_epoch) { @@ -620,12 +617,12 @@ fn process_single_effective_balance_update( } if new_effective_balance != old_effective_balance { - validator.make_mut()?.mutable.effective_balance = new_effective_balance; + validator.make_mut()?.effective_balance = new_effective_balance; // Update progressive balances cache for the *current* epoch, which will soon become the // previous epoch once the epoch transition completes. progressive_balances.on_effective_balance_change( - validator.slashed(), + validator.slashed, validator_info.current_epoch_participation, old_effective_balance, new_effective_balance, diff --git a/consensus/state_processing/src/per_epoch_processing/slashings.rs b/consensus/state_processing/src/per_epoch_processing/slashings.rs index 7618c9b6367..a1770478008 100644 --- a/consensus/state_processing/src/per_epoch_processing/slashings.rs +++ b/consensus/state_processing/src/per_epoch_processing/slashings.rs @@ -27,9 +27,9 @@ pub fn process_slashings( .iter() .enumerate() .filter(|(_, validator)| { - validator.slashed() && target_withdrawable_epoch == validator.withdrawable_epoch() + validator.slashed && target_withdrawable_epoch == validator.withdrawable_epoch }) - .map(|(index, validator)| (index, validator.effective_balance())) + .map(|(index, validator)| (index, validator.effective_balance)) .collect::>(); for (index, validator_effective_balance) in indices { diff --git a/consensus/types/benches/benches.rs b/consensus/types/benches/benches.rs index 17d266a56e5..5c1036a4c5a 100644 --- a/consensus/types/benches/benches.rs +++ b/consensus/types/benches/benches.rs @@ -8,7 +8,7 @@ use ssz::Encode; use std::sync::Arc; use types::{ test_utils::generate_deterministic_keypair, BeaconState, Epoch, Eth1Data, EthSpec, Hash256, - MainnetEthSpec, Validator, ValidatorMutable, + MainnetEthSpec, Validator, }; fn get_state(validator_count: usize) -> BeaconState { @@ -33,16 +33,14 @@ fn get_state(validator_count: usize) -> BeaconState { .collect::>() .par_iter() .map(|&i| Validator { - pubkey: Arc::new(generate_deterministic_keypair(i).pk.compress()), - mutable: ValidatorMutable { - withdrawal_credentials: Hash256::from_low_u64_le(i as u64), - effective_balance: spec.max_effective_balance, - slashed: false, - activation_eligibility_epoch: Epoch::new(0), - activation_epoch: Epoch::new(0), - exit_epoch: Epoch::from(u64::max_value()), - withdrawable_epoch: Epoch::from(u64::max_value()), - }, + pubkey: generate_deterministic_keypair(i).pk.compress(), + withdrawal_credentials: Hash256::from_low_u64_le(i as u64), + effective_balance: spec.max_effective_balance, + slashed: false, + activation_eligibility_epoch: Epoch::new(0), + activation_epoch: Epoch::new(0), + exit_epoch: Epoch::from(u64::max_value()), + withdrawable_epoch: Epoch::from(u64::max_value()), }) .collect(), ) diff --git a/consensus/types/src/activation_queue.rs b/consensus/types/src/activation_queue.rs index acbb276a61a..09ffa5b85e7 100644 --- a/consensus/types/src/activation_queue.rs +++ b/consensus/types/src/activation_queue.rs @@ -23,7 +23,7 @@ impl ActivationQueue { ) { if validator.could_be_eligible_for_activation_at(next_epoch, spec) { self.queue - .insert((validator.activation_eligibility_epoch(), index)); + .insert((validator.activation_eligibility_epoch, index)); } } diff --git a/consensus/types/src/beacon_state.rs b/consensus/types/src/beacon_state.rs index cae5d51cdff..e6ad8211b55 100644 --- a/consensus/types/src/beacon_state.rs +++ b/consensus/types/src/beacon_state.rs @@ -1,7 +1,6 @@ use self::committee_cache::get_active_validator_indices; use crate::historical_summary::HistoricalSummary; use crate::test_utils::TestRandom; -use crate::validator::ValidatorTrait; use crate::*; use compare_fields::CompareFields; use compare_fields_derive::CompareFields; @@ -37,7 +36,6 @@ pub use milhouse::{interface::Interface, List, Vector}; #[macro_use] mod committee_cache; mod balance; -pub mod compact_state; mod exit_cache; mod iter; mod progressive_balances_cache; @@ -224,7 +222,7 @@ impl From for Hash256 { arbitrary::Arbitrary, ), serde(bound = "E: EthSpec", deny_unknown_fields), - arbitrary(bound = "E: EthSpec, GenericValidator: ValidatorTrait"), + arbitrary(bound = "E: EthSpec"), derivative(Clone), ), specific_variant_attributes( @@ -316,10 +314,10 @@ impl From for Hash256 { )] #[serde(untagged)] #[serde(bound = "E: EthSpec")] -#[arbitrary(bound = "E: EthSpec, GenericValidator: ValidatorTrait")] +#[arbitrary(bound = "E: EthSpec")] #[tree_hash(enum_behaviour = "transparent")] #[ssz(enum_behaviour = "transparent")] -pub struct BeaconState +pub struct BeaconState where E: EthSpec, { @@ -364,7 +362,7 @@ where // Registry #[test_random(default)] - pub validators: List, + pub validators: List, #[serde(with = "ssz_types::serde_utils::quoted_u64_var_list")] #[compare_fields(as_iter)] #[test_random(default)] @@ -1066,7 +1064,7 @@ impl BeaconState { .get(shuffled_index) .ok_or(Error::ShuffleIndexOutOfBounds(shuffled_index))?; let random_byte = Self::shuffling_random_byte(i, seed.as_bytes())?; - let effective_balance = self.get_validator(candidate_index)?.effective_balance(); + let effective_balance = self.get_validator(candidate_index)?.effective_balance; if effective_balance.safe_mul(MAX_RANDOM_BYTE)? >= spec .max_effective_balance @@ -1088,7 +1086,7 @@ impl BeaconState { .map(|&index| { self.validators() .get(index) - .map(|v| *v.pubkey()) + .map(|v| v.pubkey) .ok_or(Error::UnknownValidator(index)) }) .collect::, _>>()?; @@ -1119,7 +1117,7 @@ impl BeaconState { Ok(validator_indices .iter() .map(|&validator_index| { - let pubkey = *self.get_validator(validator_index as usize)?.pubkey(); + let pubkey = self.get_validator(validator_index as usize)?.pubkey; Ok(SyncDuty::from_sync_committee( validator_index, @@ -1513,7 +1511,7 @@ impl BeaconState { /// Return the effective balance for a validator with the given `validator_index`. pub fn get_effective_balance(&self, validator_index: usize) -> Result { self.get_validator(validator_index) - .map(|v| v.effective_balance()) + .map(|v| v.effective_balance) } /// Get the inactivity score for a single validator. @@ -1602,7 +1600,7 @@ impl BeaconState { for validator in self.validators() { if validator.is_active_at(current_epoch) { - total_active_balance.safe_add_assign(validator.effective_balance())?; + total_active_balance.safe_add_assign(validator.effective_balance)?; } } Ok(std::cmp::max( @@ -1907,7 +1905,7 @@ impl BeaconState { for (i, validator) in self.validators().iter_from(start_index)?.enumerate() { let index = start_index.safe_add(i)?; - let success = pubkey_cache.insert(*validator.pubkey(), index); + let success = pubkey_cache.insert(validator.pubkey, index); if !success { return Err(Error::PubkeyCacheInconsistent); } @@ -1977,8 +1975,7 @@ impl BeaconState { val: &Validator, ) -> Result { Ok(val.is_active_at(previous_epoch) - || (val.slashed() - && previous_epoch.safe_add(Epoch::new(1))? < val.withdrawable_epoch())) + || (val.slashed && previous_epoch.safe_add(Epoch::new(1))? < val.withdrawable_epoch)) } /// Passing `previous_epoch` to this function rather than computing it internally provides @@ -2026,7 +2023,6 @@ impl BeaconState { #[allow(clippy::arithmetic_side_effects)] pub fn rebase_on(&mut self, base: &Self, spec: &ChainSpec) -> Result<(), Error> { // Required for macros (which use type-hints internally). - type GenericValidator = Validator; match (&mut *self, base) { (Self::Base(self_inner), Self::Base(base_inner)) => { @@ -2136,7 +2132,7 @@ impl BeaconState { } } -impl BeaconState { +impl BeaconState { /// The number of fields of the `BeaconState` rounded up to the nearest power of two. /// /// This is relevant to tree-hashing of the `BeaconState`. diff --git a/consensus/types/src/beacon_state/compact_state.rs b/consensus/types/src/beacon_state/compact_state.rs deleted file mode 100644 index 3f8f47c8541..00000000000 --- a/consensus/types/src/beacon_state/compact_state.rs +++ /dev/null @@ -1,316 +0,0 @@ -use crate::{ - BeaconState, BeaconStateAltair, BeaconStateBase, BeaconStateCapella, BeaconStateDeneb, - BeaconStateElectra, BeaconStateError as Error, BeaconStateMerge, EthSpec, List, PublicKeyBytes, - Validator, ValidatorMutable, -}; -use itertools::process_results; -use std::sync::Arc; - -pub type CompactBeaconState = BeaconState; - -/// Implement the conversion function from BeaconState -> CompactBeaconState. -macro_rules! full_to_compact { - ($s:ident, $outer:ident, $variant_name:ident, $struct_name:ident, [$($extra_fields:ident),*]) => { - BeaconState::$variant_name($struct_name { - // Versioning - genesis_time: $s.genesis_time, - genesis_validators_root: $s.genesis_validators_root, - slot: $s.slot, - fork: $s.fork, - - // History - latest_block_header: $s.latest_block_header.clone(), - block_roots: $s.block_roots.clone(), - state_roots: $s.state_roots.clone(), - historical_roots: $s.historical_roots.clone(), - - // Eth1 - eth1_data: $s.eth1_data.clone(), - eth1_data_votes: $s.eth1_data_votes.clone(), - eth1_deposit_index: $s.eth1_deposit_index, - - // Validator registry - validators: List::try_from_iter( - $s.validators.into_iter().map(|validator| validator.mutable.clone()) - ).expect("fix this"), - balances: $s.balances.clone(), - - // Shuffling - randao_mixes: $s.randao_mixes.clone(), - - // Slashings - slashings: $s.slashings.clone(), - - // Finality - justification_bits: $s.justification_bits.clone(), - previous_justified_checkpoint: $s.previous_justified_checkpoint, - current_justified_checkpoint: $s.current_justified_checkpoint, - finalized_checkpoint: $s.finalized_checkpoint, - - // Caches. - total_active_balance: $s.total_active_balance.clone(), - committee_caches: $s.committee_caches.clone(), - progressive_balances_cache: $s.progressive_balances_cache.clone(), - pubkey_cache: $s.pubkey_cache.clone(), - exit_cache: $s.exit_cache.clone(), - slashings_cache: $s.slashings_cache.clone(), - epoch_cache: $s.epoch_cache.clone(), - - // Variant-specific fields - $( - $extra_fields: $s.$extra_fields.clone() - ),* - }) - } -} - -/// Implement the conversion from CompactBeaconState -> BeaconState. -macro_rules! compact_to_full { - ($inner:ident, $variant_name:ident, $struct_name:ident, $immutable_validators:ident, [$($extra_fields:ident),*]) => { - BeaconState::$variant_name($struct_name { - // Versioning - genesis_time: $inner.genesis_time, - genesis_validators_root: $inner.genesis_validators_root, - slot: $inner.slot, - fork: $inner.fork, - - // History - latest_block_header: $inner.latest_block_header, - block_roots: $inner.block_roots, - state_roots: $inner.state_roots, - historical_roots: $inner.historical_roots, - - // Eth1 - eth1_data: $inner.eth1_data, - eth1_data_votes: $inner.eth1_data_votes, - eth1_deposit_index: $inner.eth1_deposit_index, - - // Validator registry - validators: process_results($inner.validators.into_iter().enumerate().map(|(i, mutable)| { - $immutable_validators(i) - .ok_or(Error::MissingImmutableValidator(i)) - .map(move |pubkey| { - Validator { - pubkey, - mutable: mutable.clone(), - } - }) - }), |iter| List::try_from_iter(iter))??, - balances: $inner.balances, - - // Shuffling - randao_mixes: $inner.randao_mixes, - - // Slashings - slashings: $inner.slashings, - - // Finality - justification_bits: $inner.justification_bits, - previous_justified_checkpoint: $inner.previous_justified_checkpoint, - current_justified_checkpoint: $inner.current_justified_checkpoint, - finalized_checkpoint: $inner.finalized_checkpoint, - - // Caching - total_active_balance: $inner.total_active_balance, - committee_caches: $inner.committee_caches, - progressive_balances_cache: $inner.progressive_balances_cache, - pubkey_cache: $inner.pubkey_cache, - exit_cache: $inner.exit_cache, - slashings_cache: $inner.slashings_cache, - epoch_cache: $inner.epoch_cache, - - // Variant-specific fields - $( - $extra_fields: $inner.$extra_fields - ),* - }) - } -} - -impl BeaconState { - pub fn into_compact_state(self) -> CompactBeaconState { - match self { - BeaconState::Base(s) => full_to_compact!( - s, - self, - Base, - BeaconStateBase, - [previous_epoch_attestations, current_epoch_attestations] - ), - BeaconState::Altair(s) => full_to_compact!( - s, - self, - Altair, - BeaconStateAltair, - [ - previous_epoch_participation, - current_epoch_participation, - current_sync_committee, - next_sync_committee, - inactivity_scores - ] - ), - BeaconState::Merge(s) => full_to_compact!( - s, - self, - Merge, - BeaconStateMerge, - [ - previous_epoch_participation, - current_epoch_participation, - current_sync_committee, - next_sync_committee, - inactivity_scores, - latest_execution_payload_header - ] - ), - BeaconState::Capella(s) => full_to_compact!( - s, - self, - Capella, - BeaconStateCapella, - [ - previous_epoch_participation, - current_epoch_participation, - current_sync_committee, - next_sync_committee, - inactivity_scores, - latest_execution_payload_header, - historical_summaries, - next_withdrawal_index, - next_withdrawal_validator_index - ] - ), - BeaconState::Deneb(s) => full_to_compact!( - s, - self, - Deneb, - BeaconStateDeneb, - [ - previous_epoch_participation, - current_epoch_participation, - current_sync_committee, - next_sync_committee, - inactivity_scores, - latest_execution_payload_header, - historical_summaries, - next_withdrawal_index, - next_withdrawal_validator_index - ] - ), - BeaconState::Electra(s) => full_to_compact!( - s, - self, - Electra, - BeaconStateElectra, - [ - previous_epoch_participation, - current_epoch_participation, - current_sync_committee, - next_sync_committee, - inactivity_scores, - latest_execution_payload_header, - historical_summaries, - next_withdrawal_index, - next_withdrawal_validator_index - ] - ), - } - } -} - -impl CompactBeaconState { - pub fn try_into_full_state(self, immutable_validators: F) -> Result, Error> - where - F: Fn(usize) -> Option>, - { - let state = match self { - BeaconState::Base(inner) => compact_to_full!( - inner, - Base, - BeaconStateBase, - immutable_validators, - [previous_epoch_attestations, current_epoch_attestations] - ), - BeaconState::Altair(inner) => compact_to_full!( - inner, - Altair, - BeaconStateAltair, - immutable_validators, - [ - previous_epoch_participation, - current_epoch_participation, - current_sync_committee, - next_sync_committee, - inactivity_scores - ] - ), - BeaconState::Merge(inner) => compact_to_full!( - inner, - Merge, - BeaconStateMerge, - immutable_validators, - [ - previous_epoch_participation, - current_epoch_participation, - current_sync_committee, - next_sync_committee, - inactivity_scores, - latest_execution_payload_header - ] - ), - BeaconState::Capella(inner) => compact_to_full!( - inner, - Capella, - BeaconStateCapella, - immutable_validators, - [ - previous_epoch_participation, - current_epoch_participation, - current_sync_committee, - next_sync_committee, - inactivity_scores, - latest_execution_payload_header, - historical_summaries, - next_withdrawal_index, - next_withdrawal_validator_index - ] - ), - BeaconState::Deneb(inner) => compact_to_full!( - inner, - Deneb, - BeaconStateDeneb, - immutable_validators, - [ - previous_epoch_participation, - current_epoch_participation, - current_sync_committee, - next_sync_committee, - inactivity_scores, - latest_execution_payload_header, - historical_summaries, - next_withdrawal_index, - next_withdrawal_validator_index - ] - ), - BeaconState::Electra(inner) => compact_to_full!( - inner, - Electra, - BeaconStateElectra, - immutable_validators, - [ - previous_epoch_participation, - current_epoch_participation, - current_sync_committee, - next_sync_committee, - inactivity_scores, - latest_execution_payload_header, - historical_summaries, - next_withdrawal_index, - next_withdrawal_validator_index - ] - ), - }; - Ok(state) - } -} diff --git a/consensus/types/src/beacon_state/exit_cache.rs b/consensus/types/src/beacon_state/exit_cache.rs index 1a570549957..0bb984b6676 100644 --- a/consensus/types/src/beacon_state/exit_cache.rs +++ b/consensus/types/src/beacon_state/exit_cache.rs @@ -28,8 +28,8 @@ impl ExitCache { // Add all validators with a non-default exit epoch to the cache. validators .into_iter() - .filter(|validator| validator.exit_epoch() != spec.far_future_epoch) - .try_for_each(|validator| exit_cache.record_validator_exit(validator.exit_epoch()))?; + .filter(|validator| validator.exit_epoch != spec.far_future_epoch) + .try_for_each(|validator| exit_cache.record_validator_exit(validator.exit_epoch))?; Ok(exit_cache) } diff --git a/consensus/types/src/beacon_state/slashings_cache.rs b/consensus/types/src/beacon_state/slashings_cache.rs index 19813ebbfe1..45d8f7e2129 100644 --- a/consensus/types/src/beacon_state/slashings_cache.rs +++ b/consensus/types/src/beacon_state/slashings_cache.rs @@ -20,7 +20,7 @@ impl SlashingsCache { let slashed_validators = validators .into_iter() .enumerate() - .filter_map(|(i, validator)| validator.slashed().then_some(i)) + .filter_map(|(i, validator)| validator.slashed.then_some(i)) .collect(); Self { latest_block_slot: Some(latest_block_slot), diff --git a/consensus/types/src/beacon_state/tests.rs b/consensus/types/src/beacon_state/tests.rs index 226eb9099a0..012c063afef 100644 --- a/consensus/types/src/beacon_state/tests.rs +++ b/consensus/types/src/beacon_state/tests.rs @@ -99,7 +99,6 @@ async fn test_beacon_proposer_index() { .validators_mut() .get_mut(slot0_candidate0) .unwrap() - .mutable .effective_balance = 0; test(&state, Slot::new(0), 1); for i in 1..E::slots_per_epoch() { diff --git a/consensus/types/src/lib.rs b/consensus/types/src/lib.rs index 82524e069b1..3d2f94fa04e 100644 --- a/consensus/types/src/lib.rs +++ b/consensus/types/src/lib.rs @@ -124,7 +124,7 @@ pub use crate::beacon_block_body::{ }; pub use crate::beacon_block_header::BeaconBlockHeader; pub use crate::beacon_committee::{BeaconCommittee, OwnedBeaconCommittee}; -pub use crate::beacon_state::{compact_state::CompactBeaconState, Error as BeaconStateError, *}; +pub use crate::beacon_state::{Error as BeaconStateError, *}; pub use crate::blob_sidecar::{BlobSidecar, BlobSidecarList, BlobsList}; pub use crate::bls_to_execution_change::BlsToExecutionChange; pub use crate::chain_spec::{ChainSpec, Config, Domain}; @@ -220,7 +220,7 @@ pub use crate::sync_committee_subscription::SyncCommitteeSubscription; pub use crate::sync_duty::SyncDuty; pub use crate::sync_selection_proof::SyncSelectionProof; pub use crate::sync_subnet_id::SyncSubnetId; -pub use crate::validator::{Validator, ValidatorMutable}; +pub use crate::validator::Validator; pub use crate::validator_registration_data::*; pub use crate::validator_subscription::ValidatorSubscription; pub use crate::voluntary_exit::VoluntaryExit; diff --git a/consensus/types/src/validator.rs b/consensus/types/src/validator.rs index 349f4a9b16f..98567cd1e6c 100644 --- a/consensus/types/src/validator.rs +++ b/consensus/types/src/validator.rs @@ -2,34 +2,28 @@ use crate::{ test_utils::TestRandom, Address, BeaconState, ChainSpec, Epoch, EthSpec, Hash256, PublicKeyBytes, }; -use arbitrary::Arbitrary; use serde::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; -use std::sync::Arc; use test_random_derive::TestRandom; -use tree_hash::TreeHash; use tree_hash_derive::TreeHash; -const NUM_FIELDS: usize = 8; - /// Information about a `BeaconChain` validator. /// /// Spec v0.12.1 #[derive( - Arbitrary, Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TestRandom, + arbitrary::Arbitrary, + Debug, + Clone, + PartialEq, + Serialize, + Deserialize, + Encode, + Decode, + TestRandom, + TreeHash, )] -#[serde(deny_unknown_fields)] pub struct Validator { - pub pubkey: Arc, - #[serde(flatten)] - pub mutable: ValidatorMutable, -} - -/// The mutable fields of a validator. -#[derive( - Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, Arbitrary, -)] -pub struct ValidatorMutable { + pub pubkey: PublicKeyBytes, pub withdrawal_credentials: Hash256, #[serde(with = "serde_utils::quoted_u64")] pub effective_balance: u64, @@ -40,148 +34,47 @@ pub struct ValidatorMutable { pub withdrawable_epoch: Epoch, } -pub trait ValidatorTrait: - std::fmt::Debug - + PartialEq - + Clone - + serde::Serialize - + Send - + Sync - + serde::de::DeserializeOwned - + ssz::Encode - + ssz::Decode - + TreeHash - + TestRandom - + for<'a> arbitrary::Arbitrary<'a> -{ -} - -impl ValidatorTrait for Validator {} -impl ValidatorTrait for ValidatorMutable {} - impl Validator { - pub fn pubkey(&self) -> &PublicKeyBytes { - &self.pubkey - } - - pub fn pubkey_clone(&self) -> Arc { - self.pubkey.clone() - } - - /// Replace the validator's pubkey (should only be used during testing). - pub fn replace_pubkey(&mut self, pubkey: PublicKeyBytes) { - self.pubkey = Arc::new(pubkey); - } - - #[inline] - pub fn withdrawal_credentials(&self) -> Hash256 { - self.mutable.withdrawal_credentials - } - - #[inline] - pub fn effective_balance(&self) -> u64 { - self.mutable.effective_balance - } - - #[inline] - pub fn slashed(&self) -> bool { - self.mutable.slashed - } - - #[inline] - pub fn activation_eligibility_epoch(&self) -> Epoch { - self.mutable.activation_eligibility_epoch - } - - #[inline] - pub fn activation_epoch(&self) -> Epoch { - self.mutable.activation_epoch - } - - #[inline] - pub fn activation_epoch_mut(&mut self) -> &mut Epoch { - &mut self.mutable.activation_epoch - } - - #[inline] - pub fn exit_epoch(&self) -> Epoch { - self.mutable.exit_epoch - } - - pub fn exit_epoch_mut(&mut self) -> &mut Epoch { - &mut self.mutable.exit_epoch - } - - #[inline] - pub fn withdrawable_epoch(&self) -> Epoch { - self.mutable.withdrawable_epoch - } - /// Returns `true` if the validator is considered active at some epoch. - #[inline] pub fn is_active_at(&self, epoch: Epoch) -> bool { - self.activation_epoch() <= epoch && epoch < self.exit_epoch() + self.activation_epoch <= epoch && epoch < self.exit_epoch } /// Returns `true` if the validator is slashable at some epoch. - #[inline] pub fn is_slashable_at(&self, epoch: Epoch) -> bool { - !self.slashed() && self.activation_epoch() <= epoch && epoch < self.withdrawable_epoch() + !self.slashed && self.activation_epoch <= epoch && epoch < self.withdrawable_epoch } /// Returns `true` if the validator is considered exited at some epoch. - #[inline] pub fn is_exited_at(&self, epoch: Epoch) -> bool { - self.exit_epoch() <= epoch + self.exit_epoch <= epoch } /// Returns `true` if the validator is able to withdraw at some epoch. - #[inline] pub fn is_withdrawable_at(&self, epoch: Epoch) -> bool { - epoch >= self.withdrawable_epoch() + epoch >= self.withdrawable_epoch } /// Returns `true` if the validator is eligible to join the activation queue. /// /// Spec v0.12.1 - #[inline] pub fn is_eligible_for_activation_queue(&self, spec: &ChainSpec) -> bool { - self.activation_eligibility_epoch() == spec.far_future_epoch - && self.effective_balance() == spec.max_effective_balance + self.activation_eligibility_epoch == spec.far_future_epoch + && self.effective_balance == spec.max_effective_balance } /// Returns `true` if the validator is eligible to be activated. /// /// Spec v0.12.1 - #[inline] pub fn is_eligible_for_activation( &self, state: &BeaconState, spec: &ChainSpec, ) -> bool { - // Has not yet been activated - self.activation_epoch() == spec.far_future_epoch && // Placement in queue is finalized - self.activation_eligibility_epoch() <= state.finalized_checkpoint().epoch - } - - fn tree_hash_root_internal(&self) -> Result { - let mut hasher = tree_hash::MerkleHasher::with_leaves(NUM_FIELDS); - - hasher.write(self.pubkey().tree_hash_root().as_bytes())?; - hasher.write(self.withdrawal_credentials().tree_hash_root().as_bytes())?; - hasher.write(self.effective_balance().tree_hash_root().as_bytes())?; - hasher.write(self.slashed().tree_hash_root().as_bytes())?; - hasher.write( - self.activation_eligibility_epoch() - .tree_hash_root() - .as_bytes(), - )?; - hasher.write(self.activation_epoch().tree_hash_root().as_bytes())?; - hasher.write(self.exit_epoch().tree_hash_root().as_bytes())?; - hasher.write(self.withdrawable_epoch().tree_hash_root().as_bytes())?; - - hasher.finish() + self.activation_eligibility_epoch <= state.finalized_checkpoint().epoch + // Has not yet been activated + && self.activation_epoch == spec.far_future_epoch } /// Returns `true` if the validator *could* be eligible for activation at `epoch`. @@ -191,18 +84,18 @@ impl Validator { /// the epoch transition at the end of `epoch`. pub fn could_be_eligible_for_activation_at(&self, epoch: Epoch, spec: &ChainSpec) -> bool { // Has not yet been activated - self.activation_epoch() == spec.far_future_epoch + self.activation_epoch == spec.far_future_epoch // Placement in queue could be finalized. // // NOTE: the epoch distance is 1 rather than 2 because we consider the activations that // occur at the *end* of `epoch`, after `process_justification_and_finalization` has already // updated the state's checkpoint. - && self.activation_eligibility_epoch() < epoch + && self.activation_eligibility_epoch < epoch } /// Returns `true` if the validator has eth1 withdrawal credential. pub fn has_eth1_withdrawal_credential(&self, spec: &ChainSpec) -> bool { - self.withdrawal_credentials() + self.withdrawal_credentials .as_bytes() .first() .map(|byte| *byte == spec.eth1_address_withdrawal_prefix_byte) @@ -213,7 +106,7 @@ impl Validator { pub fn get_eth1_withdrawal_address(&self, spec: &ChainSpec) -> Option
{ self.has_eth1_withdrawal_credential(spec) .then(|| { - self.withdrawal_credentials() + self.withdrawal_credentials .as_bytes() .get(12..) .map(Address::from_slice) @@ -228,37 +121,28 @@ impl Validator { let mut bytes = [0u8; 32]; bytes[0] = spec.eth1_address_withdrawal_prefix_byte; bytes[12..].copy_from_slice(execution_address.as_bytes()); - self.mutable.withdrawal_credentials = Hash256::from(bytes); + self.withdrawal_credentials = Hash256::from(bytes); } /// Returns `true` if the validator is fully withdrawable at some epoch. pub fn is_fully_withdrawable_at(&self, balance: u64, epoch: Epoch, spec: &ChainSpec) -> bool { - self.has_eth1_withdrawal_credential(spec) - && self.withdrawable_epoch() <= epoch - && balance > 0 + self.has_eth1_withdrawal_credential(spec) && self.withdrawable_epoch <= epoch && balance > 0 } /// Returns `true` if the validator is partially withdrawable. pub fn is_partially_withdrawable_validator(&self, balance: u64, spec: &ChainSpec) -> bool { self.has_eth1_withdrawal_credential(spec) - && self.effective_balance() == spec.max_effective_balance + && self.effective_balance == spec.max_effective_balance && balance > spec.max_effective_balance } } impl Default for Validator { + /// Yields a "default" `Validator`. Primarily used for testing. fn default() -> Self { - Validator { - pubkey: Arc::new(PublicKeyBytes::empty()), - mutable: <_>::default(), - } - } -} - -impl Default for ValidatorMutable { - fn default() -> Self { - ValidatorMutable { - withdrawal_credentials: Hash256::zero(), + Self { + pubkey: PublicKeyBytes::empty(), + withdrawal_credentials: Hash256::default(), activation_eligibility_epoch: Epoch::from(std::u64::MAX), activation_epoch: Epoch::from(std::u64::MAX), exit_epoch: Epoch::from(std::u64::MAX), @@ -269,25 +153,6 @@ impl Default for ValidatorMutable { } } -impl TreeHash for Validator { - fn tree_hash_type() -> tree_hash::TreeHashType { - tree_hash::TreeHashType::Container - } - - fn tree_hash_packed_encoding(&self) -> tree_hash::PackedEncoding { - unreachable!("Struct should never be packed.") - } - - fn tree_hash_packing_factor() -> usize { - unreachable!("Struct should never be packed.") - } - - fn tree_hash_root(&self) -> Hash256 { - self.tree_hash_root_internal() - .expect("Validator tree_hash_root should not fail") - } -} - #[cfg(test)] mod tests { use super::*; @@ -301,7 +166,7 @@ mod tests { assert!(!v.is_active_at(epoch)); assert!(!v.is_exited_at(epoch)); assert!(!v.is_withdrawable_at(epoch)); - assert!(!v.slashed()); + assert!(!v.slashed); } #[test] @@ -309,10 +174,7 @@ mod tests { let epoch = Epoch::new(10); let v = Validator { - mutable: ValidatorMutable { - activation_epoch: epoch, - ..Default::default() - }, + activation_epoch: epoch, ..Validator::default() }; @@ -326,10 +188,7 @@ mod tests { let epoch = Epoch::new(10); let v = Validator { - mutable: ValidatorMutable { - exit_epoch: epoch, - ..ValidatorMutable::default() - }, + exit_epoch: epoch, ..Validator::default() }; @@ -343,10 +202,7 @@ mod tests { let epoch = Epoch::new(10); let v = Validator { - mutable: ValidatorMutable { - withdrawable_epoch: epoch, - ..ValidatorMutable::default() - }, + withdrawable_epoch: epoch, ..Validator::default() }; diff --git a/lcli/src/new_testnet.rs b/lcli/src/new_testnet.rs index 4ea04fd15f4..edba4249966 100644 --- a/lcli/src/new_testnet.rs +++ b/lcli/src/new_testnet.rs @@ -17,14 +17,13 @@ use std::fs::File; use std::io::Read; use std::path::PathBuf; use std::str::FromStr; -use std::sync::Arc; use std::time::{SystemTime, UNIX_EPOCH}; use types::ExecutionBlockHash; use types::{ test_utils::generate_deterministic_keypairs, Address, BeaconState, ChainSpec, Config, Epoch, Eth1Data, EthSpec, ExecutionPayloadHeader, ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderMerge, - ForkName, Hash256, Keypair, PublicKey, Validator, ValidatorMutable, + ForkName, Hash256, Keypair, PublicKey, Validator, }; pub fn run(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Result<(), String> { @@ -276,19 +275,17 @@ fn initialize_state_with_validators( let amount = spec.max_effective_balance; // Create a new validator. let validator = Validator { - pubkey: Arc::new(keypair.0.pk.clone().into()), - mutable: ValidatorMutable { - withdrawal_credentials: withdrawal_credentials(&keypair.1.pk), - 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 - amount % (spec.effective_balance_increment), - spec.max_effective_balance, - ), - slashed: false, - }, + pubkey: keypair.0.pk.clone().into(), + withdrawal_credentials: withdrawal_credentials(&keypair.1.pk), + 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 - amount % (spec.effective_balance_increment), + spec.max_effective_balance, + ), + slashed: false, }; state.validators_mut().push(validator).unwrap(); state.balances_mut().push(amount).unwrap(); diff --git a/lcli/src/replace_state_pubkeys.rs b/lcli/src/replace_state_pubkeys.rs index 5d8421d6f6e..e8d012b16ec 100644 --- a/lcli/src/replace_state_pubkeys.rs +++ b/lcli/src/replace_state_pubkeys.rs @@ -53,14 +53,11 @@ pub fn run(testnet_dir: PathBuf, matches: &ArgMatches) -> Result<(), eprintln!("{}: {}", index, keypair.pk); - validators - .get_mut(index) - .unwrap() - .replace_pubkey(keypair.pk.into()); + validators.get_mut(index).unwrap().pubkey = keypair.pk.into(); // Update the deposit tree. let mut deposit_data = DepositData { - pubkey: *validators.get(index).unwrap().pubkey(), + pubkey: validators.get(index).unwrap().pubkey, // Set this to a junk value since it's very time consuming to generate the withdrawal // keys and it's not useful for the time being. withdrawal_credentials: Hash256::zero(), diff --git a/testing/state_transition_vectors/src/exit.rs b/testing/state_transition_vectors/src/exit.rs index 4c3b0c4f44a..277b64eebec 100644 --- a/testing/state_transition_vectors/src/exit.rs +++ b/testing/state_transition_vectors/src/exit.rs @@ -170,7 +170,7 @@ vectors_and_tests!( invalid_exit_already_initiated, ExitTest { state_modifier: Box::new(|state| { - *state.validators_mut().get_mut(0).unwrap().exit_epoch_mut() = STATE_EPOCH + 1; + state.validators_mut().get_mut(0).unwrap().exit_epoch = STATE_EPOCH + 1; }), expected: Err(BlockProcessingError::ExitInvalid { index: 0, @@ -189,11 +189,8 @@ vectors_and_tests!( invalid_not_active_before_activation_epoch, ExitTest { state_modifier: Box::new(|state| { - *state - .validators_mut() - .get_mut(0) - .unwrap() - .activation_epoch_mut() = E::default_spec().far_future_epoch; + state.validators_mut().get_mut(0).unwrap().activation_epoch = + E::default_spec().far_future_epoch; }), expected: Err(BlockProcessingError::ExitInvalid { index: 0, @@ -212,7 +209,7 @@ vectors_and_tests!( invalid_not_active_after_exit_epoch, ExitTest { state_modifier: Box::new(|state| { - *state.validators_mut().get_mut(0).unwrap().exit_epoch_mut() = STATE_EPOCH; + state.validators_mut().get_mut(0).unwrap().exit_epoch = STATE_EPOCH; }), expected: Err(BlockProcessingError::ExitInvalid { index: 0, diff --git a/watch/src/updater/mod.rs b/watch/src/updater/mod.rs index c3c8c94cdd7..65e0a90a2b4 100644 --- a/watch/src/updater/mod.rs +++ b/watch/src/updater/mod.rs @@ -211,20 +211,20 @@ pub async fn get_validators(bn: &BeaconNodeHttpClient) -> Result