Single-pass epoch processing and optimised block processing (#5279)

* Single-pass epoch processing (#4483, #4573)

Co-authored-by: Michael Sproul <michael@sigmaprime.io>

* Delete unused epoch processing code (#5170)

* Delete unused epoch processing code

* Compare total deltas

* Remove unnecessary apply_pending

* cargo fmt

* Remove newline

* Use epoch cache in block packing (#5223)

* Remove progressive balances mode (#5224)

* inline inactivity_penalty_quotient_for_state

* drop previous_epoch_total_active_balance

* fc lint

* spec compliant process_sync_aggregate (#15)

* spec compliant process_sync_aggregate

* Update consensus/state_processing/src/per_block_processing/altair/sync_committee.rs

Co-authored-by: Michael Sproul <micsproul@gmail.com>

---------

Co-authored-by: Michael Sproul <micsproul@gmail.com>

* Delete the participation cache (#16)

* update help

* Fix op_pool tests

* Fix fork choice tests

* Merge remote-tracking branch 'sigp/unstable' into epoch-single-pass

* Simplify exit cache (#5280)

* Fix clippy on exit cache

* Clean up single-pass a bit (#5282)

* Address Mark's review of single-pass (#5386)

* Merge remote-tracking branch 'origin/unstable' into epoch-single-pass

* Address Sean's review comments (#5414)

* Address most of Sean's review comments

* Simplify total balance cache building

* Clean up unused junk

* Merge remote-tracking branch 'origin/unstable' into epoch-single-pass

* More self-review

* Merge remote-tracking branch 'origin/unstable' into epoch-single-pass

* Merge branch 'unstable' into epoch-single-pass

* Fix imports for beta compiler

* Fix tests, probably
This commit is contained in:
Michael Sproul
2024-04-05 00:14:36 +11:00
committed by GitHub
parent f4cdcea7b1
commit feb531f85b
81 changed files with 2545 additions and 1316 deletions

View File

@@ -1,4 +1,7 @@
use crate::common::{base::get_base_reward, decrease_balance, increase_balance};
use crate::common::{
base::{get_base_reward, SqrtTotalActiveBalance},
decrease_balance, increase_balance,
};
use crate::per_epoch_processing::{
base::{TotalBalances, ValidatorStatus, ValidatorStatuses},
Delta, Error,
@@ -109,7 +112,6 @@ fn get_attestation_deltas<E: EthSpec>(
maybe_validators_subset: Option<&Vec<usize>>,
spec: &ChainSpec,
) -> Result<Vec<AttestationDelta>, Error> {
let previous_epoch = state.previous_epoch();
let finality_delay = state
.previous_epoch()
.safe_sub(state.finalized_checkpoint().epoch)?
@@ -118,6 +120,7 @@ fn get_attestation_deltas<E: EthSpec>(
let mut deltas = vec![AttestationDelta::default(); state.validators().len()];
let total_balances = &validator_statuses.total_balances;
let sqrt_total_active_balance = SqrtTotalActiveBalance::new(total_balances.current_epoch());
// Ignore validator if a subset is specified and validator is not in the subset
let include_validator_delta = |idx| match maybe_validators_subset.as_ref() {
@@ -131,11 +134,15 @@ fn get_attestation_deltas<E: EthSpec>(
// `get_inclusion_delay_deltas`. It's safe to do so here because any validator that is in
// the unslashed indices of the matching source attestations is active, and therefore
// eligible.
if !state.is_eligible_validator(previous_epoch, index)? {
if !validator.is_eligible {
continue;
}
let base_reward = get_base_reward(state, index, total_balances.current_epoch(), spec)?;
let base_reward = get_base_reward(
validator.current_epoch_effective_balance,
sqrt_total_active_balance,
spec,
)?;
let (inclusion_delay_delta, proposer_delta) =
get_inclusion_delay_delta(validator, base_reward, spec)?;

View File

@@ -53,6 +53,8 @@ impl InclusionInfo {
pub struct ValidatorStatus {
/// True if the validator has been slashed, ever.
pub is_slashed: bool,
/// True if the validator is eligible.
pub is_eligible: bool,
/// True if the validator can withdraw in the current epoch.
pub is_withdrawable_in_current_epoch: bool,
/// True if the validator was active in the state's _current_ epoch.
@@ -92,6 +94,7 @@ impl ValidatorStatus {
// Update all the bool fields, only updating `self` if `other` is true (never setting
// `self` to false).
set_self_if_other_is_true!(self, other, is_slashed);
set_self_if_other_is_true!(self, other, is_eligible);
set_self_if_other_is_true!(self, other, is_withdrawable_in_current_epoch);
set_self_if_other_is_true!(self, other, is_active_in_current_epoch);
set_self_if_other_is_true!(self, other, is_active_in_previous_epoch);
@@ -195,24 +198,27 @@ impl ValidatorStatuses {
let mut statuses = Vec::with_capacity(state.validators().len());
let mut total_balances = TotalBalances::new(spec);
for (i, validator) in state.validators().iter().enumerate() {
let effective_balance = state.get_effective_balance(i)?;
let current_epoch = state.current_epoch();
let previous_epoch = state.previous_epoch();
for validator in state.validators().iter() {
let effective_balance = validator.effective_balance;
let mut status = ValidatorStatus {
is_slashed: validator.slashed,
is_withdrawable_in_current_epoch: validator
.is_withdrawable_at(state.current_epoch()),
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,
..ValidatorStatus::default()
};
if validator.is_active_at(state.current_epoch()) {
if validator.is_active_at(current_epoch) {
status.is_active_in_current_epoch = true;
total_balances
.current_epoch
.safe_add_assign(effective_balance)?;
}
if validator.is_active_at(state.previous_epoch()) {
if validator.is_active_at(previous_epoch) {
status.is_active_in_previous_epoch = true;
total_balances
.previous_epoch
@@ -285,10 +291,10 @@ impl ValidatorStatuses {
}
// Compute the total balances
for (index, v) in self.statuses.iter().enumerate() {
for v in self.statuses.iter() {
// According to the spec, we only count unslashed validators towards the totals.
if !v.is_slashed {
let validator_balance = state.get_effective_balance(index)?;
let validator_balance = v.current_epoch_effective_balance;
if v.is_current_epoch_attester {
self.total_balances