mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-19 12:56:12 +00:00
Merge branch 'unstable' into max-blobs-preset
This commit is contained in:
@@ -147,6 +147,8 @@ impl<E: EthSpec> ConsensusContext<E> {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unknown_lints)]
|
||||
#[allow(elided_named_lifetimes)]
|
||||
pub fn get_indexed_attestation<'a>(
|
||||
&'a mut self,
|
||||
state: &BeaconState<E>,
|
||||
|
||||
@@ -581,8 +581,7 @@ pub fn get_expected_withdrawals<E: EthSpec>(
|
||||
.get_execution_withdrawal_address(spec)
|
||||
.ok_or(BlockProcessingError::WithdrawalCredentialsInvalid)?,
|
||||
amount: balance.safe_sub(
|
||||
validator
|
||||
.get_validator_max_effective_balance(spec, state.fork_name_unchecked()),
|
||||
validator.get_max_effective_balance(spec, state.fork_name_unchecked()),
|
||||
)?,
|
||||
});
|
||||
withdrawal_index.safe_add_assign(1)?;
|
||||
|
||||
@@ -40,15 +40,13 @@ pub fn process_operations<E: EthSpec, Payload: AbstractExecPayload<E>>(
|
||||
|
||||
if state.fork_name_unchecked().electra_enabled() {
|
||||
state.update_pubkey_cache()?;
|
||||
if let Some(deposit_requests) = block_body.execution_payload()?.deposit_requests()? {
|
||||
process_deposit_requests(state, &deposit_requests, spec)?;
|
||||
}
|
||||
if let Some(withdrawal_requests) = block_body.execution_payload()?.withdrawal_requests()? {
|
||||
process_withdrawal_requests(state, &withdrawal_requests, spec)?;
|
||||
}
|
||||
if let Some(consolidations) = block_body.execution_payload()?.consolidation_requests()? {
|
||||
process_consolidation_requests(state, &consolidations, spec)?;
|
||||
}
|
||||
process_deposit_requests(state, &block_body.execution_requests()?.deposits, spec)?;
|
||||
process_withdrawal_requests(state, &block_body.execution_requests()?.withdrawals, spec)?;
|
||||
process_consolidation_requests(
|
||||
state,
|
||||
&block_body.execution_requests()?.consolidations,
|
||||
spec,
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -477,50 +475,13 @@ pub fn apply_deposit<E: EthSpec>(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let new_validator_index = state.validators().len();
|
||||
|
||||
// [Modified in Electra:EIP7251]
|
||||
let (effective_balance, state_balance) = if state.fork_name_unchecked() >= ForkName::Electra
|
||||
{
|
||||
(0, 0)
|
||||
} else {
|
||||
(
|
||||
std::cmp::min(
|
||||
amount.safe_sub(amount.safe_rem(spec.effective_balance_increment)?)?,
|
||||
spec.max_effective_balance,
|
||||
),
|
||||
amount,
|
||||
)
|
||||
};
|
||||
// Create a new validator.
|
||||
let validator = Validator {
|
||||
pubkey: deposit_data.pubkey,
|
||||
withdrawal_credentials: deposit_data.withdrawal_credentials,
|
||||
activation_eligibility_epoch: spec.far_future_epoch,
|
||||
activation_epoch: spec.far_future_epoch,
|
||||
exit_epoch: spec.far_future_epoch,
|
||||
withdrawable_epoch: spec.far_future_epoch,
|
||||
effective_balance,
|
||||
slashed: false,
|
||||
};
|
||||
state.validators_mut().push(validator)?;
|
||||
state.balances_mut().push(state_balance)?;
|
||||
|
||||
// Altair or later initializations.
|
||||
if let Ok(previous_epoch_participation) = state.previous_epoch_participation_mut() {
|
||||
previous_epoch_participation.push(ParticipationFlags::default())?;
|
||||
}
|
||||
if let Ok(current_epoch_participation) = state.current_epoch_participation_mut() {
|
||||
current_epoch_participation.push(ParticipationFlags::default())?;
|
||||
}
|
||||
if let Ok(inactivity_scores) = state.inactivity_scores_mut() {
|
||||
inactivity_scores.push(0)?;
|
||||
}
|
||||
state.add_validator_to_registry(&deposit_data, spec)?;
|
||||
let new_validator_index = state.validators().len().safe_sub(1)? as u64;
|
||||
|
||||
// [New in Electra:EIP7251]
|
||||
if let Ok(pending_balance_deposits) = state.pending_balance_deposits_mut() {
|
||||
pending_balance_deposits.push(PendingBalanceDeposit {
|
||||
index: new_validator_index as u64,
|
||||
index: new_validator_index,
|
||||
amount,
|
||||
})?;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::{
|
||||
};
|
||||
use beacon_chain::test_utils::{BeaconChainHarness, EphemeralHarnessType};
|
||||
use ssz_types::Bitfield;
|
||||
use std::sync::LazyLock;
|
||||
use std::sync::{Arc, LazyLock};
|
||||
use test_utils::generate_deterministic_keypairs;
|
||||
use types::*;
|
||||
|
||||
@@ -1017,6 +1017,7 @@ async fn fork_spanning_exit() {
|
||||
spec.altair_fork_epoch = Some(Epoch::new(2));
|
||||
spec.bellatrix_fork_epoch = Some(Epoch::new(4));
|
||||
spec.shard_committee_period = 0;
|
||||
let spec = Arc::new(spec);
|
||||
|
||||
let harness = BeaconChainHarness::builder(MainnetEthSpec)
|
||||
.spec(spec.clone())
|
||||
|
||||
@@ -45,6 +45,12 @@ impl AttestationDelta {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ProposerRewardCalculation {
|
||||
Include,
|
||||
Exclude,
|
||||
}
|
||||
|
||||
/// Apply attester and proposer rewards.
|
||||
pub fn process_rewards_and_penalties<E: EthSpec>(
|
||||
state: &mut BeaconState<E>,
|
||||
@@ -62,7 +68,12 @@ pub fn process_rewards_and_penalties<E: EthSpec>(
|
||||
return Err(Error::ValidatorStatusesInconsistent);
|
||||
}
|
||||
|
||||
let deltas = get_attestation_deltas_all(state, validator_statuses, spec)?;
|
||||
let deltas = get_attestation_deltas_all(
|
||||
state,
|
||||
validator_statuses,
|
||||
ProposerRewardCalculation::Include,
|
||||
spec,
|
||||
)?;
|
||||
|
||||
// Apply the deltas, erroring on overflow above but not on overflow below (saturating at 0
|
||||
// instead).
|
||||
@@ -79,9 +90,10 @@ pub fn process_rewards_and_penalties<E: EthSpec>(
|
||||
pub fn get_attestation_deltas_all<E: EthSpec>(
|
||||
state: &BeaconState<E>,
|
||||
validator_statuses: &ValidatorStatuses,
|
||||
proposer_reward: ProposerRewardCalculation,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Vec<AttestationDelta>, Error> {
|
||||
get_attestation_deltas(state, validator_statuses, None, spec)
|
||||
get_attestation_deltas(state, validator_statuses, proposer_reward, None, spec)
|
||||
}
|
||||
|
||||
/// Apply rewards for participation in attestations during the previous epoch, and only compute
|
||||
@@ -89,10 +101,18 @@ pub fn get_attestation_deltas_all<E: EthSpec>(
|
||||
pub fn get_attestation_deltas_subset<E: EthSpec>(
|
||||
state: &BeaconState<E>,
|
||||
validator_statuses: &ValidatorStatuses,
|
||||
proposer_reward: ProposerRewardCalculation,
|
||||
validators_subset: &Vec<usize>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Vec<(usize, AttestationDelta)>, Error> {
|
||||
get_attestation_deltas(state, validator_statuses, Some(validators_subset), spec).map(|deltas| {
|
||||
get_attestation_deltas(
|
||||
state,
|
||||
validator_statuses,
|
||||
proposer_reward,
|
||||
Some(validators_subset),
|
||||
spec,
|
||||
)
|
||||
.map(|deltas| {
|
||||
deltas
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
@@ -109,6 +129,7 @@ pub fn get_attestation_deltas_subset<E: EthSpec>(
|
||||
fn get_attestation_deltas<E: EthSpec>(
|
||||
state: &BeaconState<E>,
|
||||
validator_statuses: &ValidatorStatuses,
|
||||
proposer_reward: ProposerRewardCalculation,
|
||||
maybe_validators_subset: Option<&Vec<usize>>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Vec<AttestationDelta>, Error> {
|
||||
@@ -169,13 +190,15 @@ fn get_attestation_deltas<E: EthSpec>(
|
||||
.combine(inactivity_penalty_delta)?;
|
||||
}
|
||||
|
||||
if let Some((proposer_index, proposer_delta)) = proposer_delta {
|
||||
if include_validator_delta(proposer_index) {
|
||||
deltas
|
||||
.get_mut(proposer_index)
|
||||
.ok_or(Error::ValidatorStatusesInconsistent)?
|
||||
.inclusion_delay_delta
|
||||
.combine(proposer_delta)?;
|
||||
if let ProposerRewardCalculation::Include = proposer_reward {
|
||||
if let Some((proposer_index, proposer_delta)) = proposer_delta {
|
||||
if include_validator_delta(proposer_index) {
|
||||
deltas
|
||||
.get_mut(proposer_index)
|
||||
.ok_or(Error::ValidatorStatusesInconsistent)?
|
||||
.inclusion_delay_delta
|
||||
.combine(proposer_delta)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ struct RewardsAndPenaltiesContext {
|
||||
struct SlashingsContext {
|
||||
adjusted_total_slashing_balance: u64,
|
||||
target_withdrawable_epoch: Epoch,
|
||||
penalty_per_effective_balance_increment: u64,
|
||||
}
|
||||
|
||||
struct PendingBalanceDepositsContext {
|
||||
@@ -775,9 +776,16 @@ impl SlashingsContext {
|
||||
.current_epoch
|
||||
.safe_add(E::EpochsPerSlashingsVector::to_u64().safe_div(2)?)?;
|
||||
|
||||
let penalty_per_effective_balance_increment = adjusted_total_slashing_balance.safe_div(
|
||||
state_ctxt
|
||||
.total_active_balance
|
||||
.safe_div(spec.effective_balance_increment)?,
|
||||
)?;
|
||||
|
||||
Ok(Self {
|
||||
adjusted_total_slashing_balance,
|
||||
target_withdrawable_epoch,
|
||||
penalty_per_effective_balance_increment,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -792,14 +800,20 @@ fn process_single_slashing(
|
||||
if validator.slashed && slashings_ctxt.target_withdrawable_epoch == validator.withdrawable_epoch
|
||||
{
|
||||
let increment = spec.effective_balance_increment;
|
||||
let penalty_numerator = validator
|
||||
.effective_balance
|
||||
.safe_div(increment)?
|
||||
.safe_mul(slashings_ctxt.adjusted_total_slashing_balance)?;
|
||||
let penalty = penalty_numerator
|
||||
.safe_div(state_ctxt.total_active_balance)?
|
||||
.safe_mul(increment)?;
|
||||
|
||||
let penalty = if state_ctxt.fork_name.electra_enabled() {
|
||||
let effective_balance_increments = validator.effective_balance.safe_div(increment)?;
|
||||
slashings_ctxt
|
||||
.penalty_per_effective_balance_increment
|
||||
.safe_mul(effective_balance_increments)?
|
||||
} else {
|
||||
let penalty_numerator = validator
|
||||
.effective_balance
|
||||
.safe_div(increment)?
|
||||
.safe_mul(slashings_ctxt.adjusted_total_slashing_balance)?;
|
||||
penalty_numerator
|
||||
.safe_div(state_ctxt.total_active_balance)?
|
||||
.safe_mul(increment)?
|
||||
};
|
||||
*balance.make_mut()? = balance.saturating_sub(penalty);
|
||||
}
|
||||
Ok(())
|
||||
@@ -1022,8 +1036,7 @@ fn process_single_effective_balance_update(
|
||||
) -> Result<(), Error> {
|
||||
// Use the higher effective balance limit if post-Electra and compounding withdrawal credentials
|
||||
// are set.
|
||||
let effective_balance_limit =
|
||||
validator.get_validator_max_effective_balance(spec, state_ctxt.fork_name);
|
||||
let effective_balance_limit = validator.get_max_effective_balance(spec, state_ctxt.fork_name);
|
||||
|
||||
let old_effective_balance = validator.effective_balance;
|
||||
let new_effective_balance = if balance.safe_add(eb_ctxt.downward_threshold)?
|
||||
|
||||
@@ -45,6 +45,7 @@ mod release_tests {
|
||||
per_slot_processing::per_slot_processing, EpochProcessingError, SlotProcessingError,
|
||||
};
|
||||
use beacon_chain::test_utils::{AttestationStrategy, BlockStrategy};
|
||||
use std::sync::Arc;
|
||||
use types::{Epoch, ForkName, InconsistentFork, MainnetEthSpec};
|
||||
|
||||
#[tokio::test]
|
||||
@@ -56,7 +57,7 @@ mod release_tests {
|
||||
|
||||
let altair_state = {
|
||||
let harness = BeaconChainHarness::builder(MainnetEthSpec)
|
||||
.spec(spec.clone())
|
||||
.spec(Arc::new(spec.clone()))
|
||||
.deterministic_keypairs(8)
|
||||
.fresh_ephemeral_store()
|
||||
.build();
|
||||
@@ -116,7 +117,7 @@ mod release_tests {
|
||||
|
||||
let base_state = {
|
||||
let harness = BeaconChainHarness::builder(MainnetEthSpec)
|
||||
.spec(spec.clone())
|
||||
.spec(Arc::new(spec.clone()))
|
||||
.deterministic_keypairs(8)
|
||||
.fresh_ephemeral_store()
|
||||
.build();
|
||||
|
||||
Reference in New Issue
Block a user