use safe_arith::SafeArith; use std::mem; use types::{ BeaconState, BeaconStateError as Error, BeaconStateFulu, ChainSpec, EthSpec, Fork, Vector, }; /// Transform a `Electra` state into an `Fulu` state. pub fn upgrade_to_fulu( pre_state: &mut BeaconState, spec: &ChainSpec, ) -> Result<(), Error> { let _epoch = pre_state.current_epoch(); let post = upgrade_state_to_fulu(pre_state, spec)?; *pre_state = post; Ok(()) } fn initialize_proposer_lookahead( state: &BeaconState, spec: &ChainSpec, ) -> Result, Error> { let current_epoch = state.current_epoch(); let mut lookahead = Vec::with_capacity(E::proposer_lookahead_slots()); for i in 0..(spec.min_seed_lookahead.safe_add(1)?.as_u64()) { let target_epoch = current_epoch.safe_add(i)?; lookahead.extend( state .get_beacon_proposer_indices(target_epoch, spec) .map(|vec| vec.into_iter().map(|x| x as u64))?, ); } Vector::new(lookahead).map_err(|e| e.into()) } pub fn upgrade_state_to_fulu( pre_state: &mut BeaconState, spec: &ChainSpec, ) -> Result, Error> { let epoch = pre_state.current_epoch(); let proposer_lookahead = initialize_proposer_lookahead(pre_state, spec)?; let pre = pre_state.as_electra_mut()?; // Where possible, use something like `mem::take` to move fields from behind the &mut // reference. For other fields that don't have a good default value, use `clone`. // // Fixed size vectors get cloned because replacing them would require the same size // allocation as cloning. let post = BeaconState::Fulu(BeaconStateFulu { // Versioning genesis_time: pre.genesis_time, genesis_validators_root: pre.genesis_validators_root, slot: pre.slot, fork: Fork { previous_version: pre.fork.current_version, current_version: spec.fulu_fork_version, epoch, }, // History latest_block_header: pre.latest_block_header.clone(), block_roots: pre.block_roots.clone(), state_roots: pre.state_roots.clone(), historical_roots: mem::take(&mut pre.historical_roots), // Eth1 eth1_data: pre.eth1_data.clone(), eth1_data_votes: mem::take(&mut pre.eth1_data_votes), eth1_deposit_index: pre.eth1_deposit_index, // Registry validators: mem::take(&mut pre.validators), balances: mem::take(&mut pre.balances), // Randomness randao_mixes: pre.randao_mixes.clone(), // Slashings slashings: pre.slashings.clone(), // `Participation previous_epoch_participation: mem::take(&mut pre.previous_epoch_participation), current_epoch_participation: mem::take(&mut pre.current_epoch_participation), // Finality justification_bits: pre.justification_bits.clone(), previous_justified_checkpoint: pre.previous_justified_checkpoint, current_justified_checkpoint: pre.current_justified_checkpoint, finalized_checkpoint: pre.finalized_checkpoint, // Inactivity inactivity_scores: mem::take(&mut pre.inactivity_scores), // Sync committees current_sync_committee: pre.current_sync_committee.clone(), next_sync_committee: pre.next_sync_committee.clone(), // Execution latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_fulu(), // Capella next_withdrawal_index: pre.next_withdrawal_index, next_withdrawal_validator_index: pre.next_withdrawal_validator_index, historical_summaries: pre.historical_summaries.clone(), // Electra deposit_requests_start_index: pre.deposit_requests_start_index, deposit_balance_to_consume: pre.deposit_balance_to_consume, exit_balance_to_consume: pre.exit_balance_to_consume, earliest_exit_epoch: pre.earliest_exit_epoch, consolidation_balance_to_consume: pre.consolidation_balance_to_consume, earliest_consolidation_epoch: pre.earliest_consolidation_epoch, pending_deposits: pre.pending_deposits.clone(), pending_partial_withdrawals: pre.pending_partial_withdrawals.clone(), pending_consolidations: pre.pending_consolidations.clone(), // Caches total_active_balance: pre.total_active_balance, progressive_balances_cache: mem::take(&mut pre.progressive_balances_cache), committee_caches: mem::take(&mut pre.committee_caches), pubkey_cache: mem::take(&mut pre.pubkey_cache), exit_cache: mem::take(&mut pre.exit_cache), slashings_cache: mem::take(&mut pre.slashings_cache), epoch_cache: mem::take(&mut pre.epoch_cache), proposer_lookahead, }); Ok(post) }