Merge remote-tracking branch 'origin/unstable' into tree-states

This commit is contained in:
Michael Sproul
2024-04-05 15:14:04 +11:00
455 changed files with 7906 additions and 5229 deletions

View File

@@ -15,7 +15,7 @@ pub struct JustifiedBalances {
}
impl JustifiedBalances {
pub fn from_justified_state<T: EthSpec>(state: &BeaconState<T>) -> Result<Self, ArithError> {
pub fn from_justified_state<E: EthSpec>(state: &BeaconState<E>) -> Result<Self, ArithError> {
let current_epoch = state.current_epoch();
let mut total_effective_balance = 0u64;
let mut num_active_validators = 0u64;

View File

@@ -195,8 +195,10 @@ pub struct ProposerHeadInfo {
/// Information about the parent of the current head, which should be selected as the parent
/// for a new proposal *if* a re-org is decided on.
pub parent_node: ProtoNode,
/// The computed fraction of the active committee balance below which we can re-org.
pub re_org_weight_threshold: u64,
/// The computed fraction of the active head committee balance below which we can re-org.
pub re_org_head_weight_threshold: u64,
/// The computed fraction of the active parent committee balance above which we can re-org.
pub re_org_parent_weight_threshold: u64,
/// The current slot from fork choice's point of view, may lead the wall-clock slot by upto
/// 500ms.
pub current_slot: Slot,
@@ -207,13 +209,13 @@ pub struct ProposerHeadInfo {
/// This type intentionally does not implement `Debug` so that callers are forced to handle the
/// enum.
#[derive(Debug, Clone, PartialEq)]
pub enum ProposerHeadError<E> {
pub enum ProposerHeadError<T> {
DoNotReOrg(DoNotReOrg),
Error(E),
Error(T),
}
impl<E> From<DoNotReOrg> for ProposerHeadError<E> {
fn from(e: DoNotReOrg) -> ProposerHeadError<E> {
impl<T> From<DoNotReOrg> for ProposerHeadError<T> {
fn from(e: DoNotReOrg) -> ProposerHeadError<T> {
Self::DoNotReOrg(e)
}
}
@@ -224,15 +226,15 @@ impl From<Error> for ProposerHeadError<Error> {
}
}
impl<E1> ProposerHeadError<E1> {
pub fn convert_inner_error<E2>(self) -> ProposerHeadError<E2>
impl<T1> ProposerHeadError<T1> {
pub fn convert_inner_error<T2>(self) -> ProposerHeadError<T2>
where
E2: From<E1>,
T2: From<T1>,
{
self.map_inner_error(E2::from)
self.map_inner_error(T2::from)
}
pub fn map_inner_error<E2>(self, f: impl FnOnce(E1) -> E2) -> ProposerHeadError<E2> {
pub fn map_inner_error<T2>(self, f: impl FnOnce(T1) -> T2) -> ProposerHeadError<T2> {
match self {
ProposerHeadError::DoNotReOrg(reason) => ProposerHeadError::DoNotReOrg(reason),
ProposerHeadError::Error(error) => ProposerHeadError::Error(f(error)),
@@ -259,7 +261,11 @@ pub enum DoNotReOrg {
},
HeadNotWeak {
head_weight: u64,
re_org_weight_threshold: u64,
re_org_head_weight_threshold: u64,
},
ParentNotStrong {
parent_weight: u64,
re_org_parent_weight_threshold: u64,
},
HeadNotLate,
NotProposing,
@@ -288,9 +294,21 @@ impl std::fmt::Display for DoNotReOrg {
),
Self::HeadNotWeak {
head_weight,
re_org_weight_threshold,
re_org_head_weight_threshold,
} => {
write!(f, "head not weak ({head_weight}/{re_org_weight_threshold})")
write!(
f,
"head not weak ({head_weight}/{re_org_head_weight_threshold})"
)
}
Self::ParentNotStrong {
parent_weight,
re_org_parent_weight_threshold,
} => {
write!(
f,
"parent not strong ({parent_weight}/{re_org_parent_weight_threshold})"
)
}
Self::HeadNotLate => {
write!(f, "head arrived on time")
@@ -486,12 +504,14 @@ impl ProtoArrayForkChoice {
/// Get the block to propose on during `current_slot`.
///
/// This function returns a *definitive* result which should be acted on.
#[allow(clippy::too_many_arguments)]
pub fn get_proposer_head<E: EthSpec>(
&self,
current_slot: Slot,
canonical_head: Hash256,
justified_balances: &JustifiedBalances,
re_org_threshold: ReOrgThreshold,
re_org_head_threshold: ReOrgThreshold,
re_org_parent_threshold: ReOrgThreshold,
disallowed_offsets: &DisallowedReOrgOffsets,
max_epochs_since_finalization: Epoch,
) -> Result<ProposerHeadInfo, ProposerHeadError<Error>> {
@@ -499,7 +519,8 @@ impl ProtoArrayForkChoice {
current_slot,
canonical_head,
justified_balances,
re_org_threshold,
re_org_head_threshold,
re_org_parent_threshold,
disallowed_offsets,
max_epochs_since_finalization,
)?;
@@ -510,14 +531,26 @@ impl ProtoArrayForkChoice {
return Err(DoNotReOrg::HeadDistance.into());
}
// Only re-org if the head's weight is less than the configured committee fraction.
// Only re-org if the head's weight is less than the heads configured committee fraction.
let head_weight = info.head_node.weight;
let re_org_weight_threshold = info.re_org_weight_threshold;
let weak_head = head_weight < re_org_weight_threshold;
let re_org_head_weight_threshold = info.re_org_head_weight_threshold;
let weak_head = head_weight < re_org_head_weight_threshold;
if !weak_head {
return Err(DoNotReOrg::HeadNotWeak {
head_weight,
re_org_weight_threshold,
re_org_head_weight_threshold,
}
.into());
}
// Only re-org if the parent's weight is greater than the parents configured committee fraction.
let parent_weight = info.parent_node.weight;
let re_org_parent_weight_threshold = info.re_org_parent_weight_threshold;
let parent_strong = parent_weight > re_org_parent_weight_threshold;
if !parent_strong {
return Err(DoNotReOrg::ParentNotStrong {
parent_weight,
re_org_parent_weight_threshold,
}
.into());
}
@@ -529,12 +562,14 @@ impl ProtoArrayForkChoice {
/// Get information about the block to propose on during `current_slot`.
///
/// This function returns a *partial* result which must be processed further.
#[allow(clippy::too_many_arguments)]
pub fn get_proposer_head_info<E: EthSpec>(
&self,
current_slot: Slot,
canonical_head: Hash256,
justified_balances: &JustifiedBalances,
re_org_threshold: ReOrgThreshold,
re_org_head_threshold: ReOrgThreshold,
re_org_parent_threshold: ReOrgThreshold,
disallowed_offsets: &DisallowedReOrgOffsets,
max_epochs_since_finalization: Epoch,
) -> Result<ProposerHeadInfo, ProposerHeadError<Error>> {
@@ -595,15 +630,20 @@ impl ProtoArrayForkChoice {
return Err(DoNotReOrg::JustificationAndFinalizationNotCompetitive.into());
}
// Compute re-org weight threshold.
let re_org_weight_threshold =
calculate_committee_fraction::<E>(justified_balances, re_org_threshold.0)
// Compute re-org weight thresholds for head and parent.
let re_org_head_weight_threshold =
calculate_committee_fraction::<E>(justified_balances, re_org_head_threshold.0)
.ok_or(Error::ReOrgThresholdOverflow)?;
let re_org_parent_weight_threshold =
calculate_committee_fraction::<E>(justified_balances, re_org_parent_threshold.0)
.ok_or(Error::ReOrgThresholdOverflow)?;
Ok(ProposerHeadInfo {
head_node,
parent_node,
re_org_weight_threshold,
re_org_head_weight_threshold,
re_org_parent_weight_threshold,
current_slot,
})
}

View File

@@ -7,7 +7,6 @@ use crate::{
use ssz::{four_byte_option_impl, Encode};
use ssz_derive::{Decode, Encode};
use std::collections::HashMap;
use std::convert::TryFrom;
use superstruct::superstruct;
use types::{Checkpoint, Hash256};