mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-18 04:13:00 +00:00
Merge branch 'unstable' of https://github.com/sigp/lighthouse into gloas-block-and-bid-production
This commit is contained in:
@@ -55,9 +55,21 @@ use crate::{
|
||||
};
|
||||
|
||||
pub const CACHED_EPOCHS: usize = 3;
|
||||
|
||||
// Pre-electra WS calculations are not supported. On mainnet, pre-electra epochs are outside the weak subjectivity
|
||||
// period. The default pre-electra WS value is set to 256 to allow for `basic-sim``, `fallback-sim`` test case `revert_minority_fork_on_resume`
|
||||
// to pass. 256 is a small enough number to trigger the WS safety check pre-electra on mainnet.
|
||||
pub const DEFAULT_PRE_ELECTRA_WS_PERIOD: u64 = 256;
|
||||
|
||||
const MAX_RANDOM_BYTE: u64 = (1 << 8) - 1;
|
||||
const MAX_RANDOM_VALUE: u64 = (1 << 16) - 1;
|
||||
|
||||
// `SAFETY_DECAY` is defined as the maximum percentage tolerable loss in the one-third
|
||||
// safety margin of FFG finality. Thus, any attack exploiting the Weak Subjectivity Period has
|
||||
// a safety margin of at least `1/3 - SAFETY_DECAY/100`.
|
||||
// Spec: https://github.com/ethereum/consensus-specs/blob/1937aff86b41b5171a9bc3972515986f1bbbf303/specs/phase0/weak-subjectivity.md?plain=1#L50-L71
|
||||
const SAFETY_DECAY: u64 = 10;
|
||||
|
||||
pub type Validators<E> = List<Validator, <E as EthSpec>::ValidatorRegistryLimit>;
|
||||
pub type Balances<E> = List<u64, <E as EthSpec>::ValidatorRegistryLimit>;
|
||||
|
||||
@@ -3007,6 +3019,26 @@ impl<E: EthSpec> BeaconState<E> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the weak subjectivity period for `self`
|
||||
pub fn compute_weak_subjectivity_period(
|
||||
&self,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Epoch, BeaconStateError> {
|
||||
let total_active_balance = self.get_total_active_balance()?;
|
||||
let fork_name = self.fork_name_unchecked();
|
||||
|
||||
if fork_name.electra_enabled() {
|
||||
let balance_churn_limit = self.get_balance_churn_limit(spec)?;
|
||||
compute_weak_subjectivity_period_electra(
|
||||
total_active_balance,
|
||||
balance_churn_limit,
|
||||
spec,
|
||||
)
|
||||
} else {
|
||||
Ok(Epoch::new(DEFAULT_PRE_ELECTRA_WS_PERIOD))
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the payload timeliness committee for the given `slot`.
|
||||
///
|
||||
/// Requires the committee cache to be initialized.
|
||||
@@ -3382,3 +3414,75 @@ impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for BeaconState<E> {
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Spec: https://github.com/ethereum/consensus-specs/blob/1937aff86b41b5171a9bc3972515986f1bbbf303/specs/electra/weak-subjectivity.md?plain=1#L30
|
||||
pub fn compute_weak_subjectivity_period_electra(
|
||||
total_active_balance: u64,
|
||||
balance_churn_limit: u64,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Epoch, BeaconStateError> {
|
||||
let epochs_for_validator_set_churn = SAFETY_DECAY
|
||||
.safe_mul(total_active_balance)?
|
||||
.safe_div(balance_churn_limit.safe_mul(200)?)?;
|
||||
let ws_period = spec
|
||||
.min_validator_withdrawability_delay
|
||||
.safe_add(epochs_for_validator_set_churn)?;
|
||||
|
||||
Ok(ws_period)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod weak_subjectivity_tests {
|
||||
use crate::state::beacon_state::compute_weak_subjectivity_period_electra;
|
||||
use crate::{ChainSpec, Epoch, EthSpec, MainnetEthSpec};
|
||||
|
||||
const GWEI_PER_ETH: u64 = 1_000_000_000;
|
||||
|
||||
#[test]
|
||||
fn test_compute_weak_subjectivity_period_electra() {
|
||||
let mut spec = MainnetEthSpec::default_spec();
|
||||
spec.altair_fork_epoch = Some(Epoch::new(0));
|
||||
spec.bellatrix_fork_epoch = Some(Epoch::new(0));
|
||||
spec.capella_fork_epoch = Some(Epoch::new(0));
|
||||
spec.deneb_fork_epoch = Some(Epoch::new(0));
|
||||
spec.electra_fork_epoch = Some(Epoch::new(0));
|
||||
|
||||
// A table of some expected values:
|
||||
// https://github.com/ethereum/consensus-specs/blob/1937aff86b41b5171a9bc3972515986f1bbbf303/specs/electra/weak-subjectivity.md?plain=1#L44-L54
|
||||
// (total_active_balance, expected_ws_period)
|
||||
let expected_values: Vec<(u64, u64)> = vec![
|
||||
(1_048_576 * GWEI_PER_ETH, 665),
|
||||
(2_097_152 * GWEI_PER_ETH, 1_075),
|
||||
(4_194_304 * GWEI_PER_ETH, 1_894),
|
||||
(8_388_608 * GWEI_PER_ETH, 3_532),
|
||||
(16_777_216 * GWEI_PER_ETH, 3_532),
|
||||
(33_554_432 * GWEI_PER_ETH, 3_532),
|
||||
// This value cross referenced w/
|
||||
// beacon_chain/tests/tests.rs:test_compute_weak_subjectivity_period
|
||||
(1536 * GWEI_PER_ETH, 256),
|
||||
];
|
||||
|
||||
for (total_active_balance, expected_ws_period) in expected_values {
|
||||
let balance_churn_limit = get_balance_churn_limit(total_active_balance, &spec);
|
||||
|
||||
let calculated_ws_period = compute_weak_subjectivity_period_electra(
|
||||
total_active_balance,
|
||||
balance_churn_limit,
|
||||
&spec,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(calculated_ws_period, expected_ws_period);
|
||||
}
|
||||
}
|
||||
|
||||
// caclulate the balance_churn_limit without dealing with states
|
||||
// and without initializing the active balance cache
|
||||
fn get_balance_churn_limit(total_active_balance: u64, spec: &ChainSpec) -> u64 {
|
||||
let churn = std::cmp::max(
|
||||
spec.min_per_epoch_churn_limit_electra,
|
||||
total_active_balance / spec.churn_limit_quotient,
|
||||
);
|
||||
churn - (churn % spec.effective_balance_increment)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ pub use balance::Balance;
|
||||
pub use beacon_state::{
|
||||
BeaconState, BeaconStateAltair, BeaconStateBase, BeaconStateBellatrix, BeaconStateCapella,
|
||||
BeaconStateDeneb, BeaconStateElectra, BeaconStateError, BeaconStateFulu, BeaconStateGloas,
|
||||
BeaconStateHash, BeaconStateRef, CACHED_EPOCHS,
|
||||
BeaconStateHash, BeaconStateRef, CACHED_EPOCHS, DEFAULT_PRE_ELECTRA_WS_PERIOD,
|
||||
};
|
||||
pub use committee_cache::{
|
||||
CommitteeCache, compute_committee_index_in_epoch, compute_committee_range_in_epoch,
|
||||
|
||||
Reference in New Issue
Block a user