mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-31 13:17:09 +00:00
merge from unstable
This commit is contained in:
@@ -400,15 +400,13 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignedBeaconBlock<E, Payload>
|
||||
/// `block_hash` from the parent beacon block's bid. If the parent beacon state is available
|
||||
/// this can alternatively be fetched from `state.latest_payload_bid`.
|
||||
///
|
||||
/// This function returns `false` for all blocks prior to Gloas and for the zero
|
||||
/// `parent_block_hash`.
|
||||
/// This function returns `false` for all blocks prior to Gloas.
|
||||
pub fn is_parent_block_full(&self, parent_block_hash: ExecutionBlockHash) -> bool {
|
||||
let Ok(signed_payload_bid) = self.message().body().signed_execution_payload_bid() else {
|
||||
// Prior to Gloas.
|
||||
return false;
|
||||
};
|
||||
parent_block_hash != ExecutionBlockHash::zero()
|
||||
&& signed_payload_bid.message.parent_block_hash == parent_block_hash
|
||||
signed_payload_bid.message.parent_block_hash == parent_block_hash
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{Address, ForkName, SignedRoot, Slot};
|
||||
use crate::{Address, ForkName, Hash256, SignedRoot, Slot};
|
||||
use bls::Signature;
|
||||
use context_deserialize::context_deserialize;
|
||||
use educe::Educe;
|
||||
@@ -16,6 +16,7 @@ use tree_hash_derive::TreeHash;
|
||||
#[context_deserialize(ForkName)]
|
||||
// https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/p2p-interface.md#new-proposerpreferences
|
||||
pub struct ProposerPreferences {
|
||||
pub checkpoint_root: Hash256,
|
||||
pub proposal_slot: Slot,
|
||||
pub validator_index: u64,
|
||||
pub fee_recipient: Address,
|
||||
|
||||
@@ -251,6 +251,9 @@ pub struct ChainSpec {
|
||||
pub builder_payment_threshold_numerator: u64,
|
||||
pub builder_payment_threshold_denominator: u64,
|
||||
pub min_builder_withdrawability_delay: Epoch,
|
||||
pub churn_limit_quotient_gloas: u64,
|
||||
pub consolidation_churn_limit_quotient: u64,
|
||||
pub max_per_epoch_activation_churn_limit_gloas: u64,
|
||||
|
||||
/*
|
||||
* Networking
|
||||
@@ -1268,6 +1271,14 @@ impl ChainSpec {
|
||||
builder_payment_threshold_numerator: 6,
|
||||
builder_payment_threshold_denominator: 10,
|
||||
min_builder_withdrawability_delay: Epoch::new(64),
|
||||
churn_limit_quotient_gloas: option_wrapper(|| u64::checked_pow(2, 15))
|
||||
.expect("calculation does not overflow"),
|
||||
consolidation_churn_limit_quotient: option_wrapper(|| u64::checked_pow(2, 16))
|
||||
.expect("calculation does not overflow"),
|
||||
max_per_epoch_activation_churn_limit_gloas: option_wrapper(|| {
|
||||
u64::checked_pow(2, 8)?.checked_mul(u64::checked_pow(10, 9)?)
|
||||
})
|
||||
.expect("calculation does not overflow"),
|
||||
max_request_payloads: 128,
|
||||
|
||||
/*
|
||||
@@ -1414,6 +1425,14 @@ impl ChainSpec {
|
||||
gloas_fork_version: [0x07, 0x00, 0x00, 0x01],
|
||||
gloas_fork_epoch: None,
|
||||
min_builder_withdrawability_delay: Epoch::new(2),
|
||||
churn_limit_quotient_gloas: option_wrapper(|| u64::checked_pow(2, 4))
|
||||
.expect("calculation does not overflow"),
|
||||
consolidation_churn_limit_quotient: option_wrapper(|| u64::checked_pow(2, 5))
|
||||
.expect("calculation does not overflow"),
|
||||
max_per_epoch_activation_churn_limit_gloas: option_wrapper(|| {
|
||||
u64::checked_pow(2, 7)?.checked_mul(u64::checked_pow(10, 9)?)
|
||||
})
|
||||
.expect("calculation does not overflow"),
|
||||
|
||||
/*
|
||||
* Derived time values (set by `compute_derived_values()`)
|
||||
@@ -1675,6 +1694,14 @@ impl ChainSpec {
|
||||
builder_payment_threshold_numerator: 6,
|
||||
builder_payment_threshold_denominator: 10,
|
||||
min_builder_withdrawability_delay: Epoch::new(64),
|
||||
churn_limit_quotient_gloas: option_wrapper(|| u64::checked_pow(2, 15))
|
||||
.expect("calculation does not overflow"),
|
||||
consolidation_churn_limit_quotient: option_wrapper(|| u64::checked_pow(2, 16))
|
||||
.expect("calculation does not overflow"),
|
||||
max_per_epoch_activation_churn_limit_gloas: option_wrapper(|| {
|
||||
u64::checked_pow(2, 8)?.checked_mul(u64::checked_pow(10, 9)?)
|
||||
})
|
||||
.expect("calculation does not overflow"),
|
||||
max_request_payloads: 128,
|
||||
|
||||
/*
|
||||
@@ -2125,6 +2152,16 @@ pub struct Config {
|
||||
#[serde(default = "default_min_builder_withdrawability_delay")]
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
min_builder_withdrawability_delay: u64,
|
||||
|
||||
#[serde(default = "default_churn_limit_quotient_gloas")]
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
churn_limit_quotient_gloas: u64,
|
||||
#[serde(default = "default_consolidation_churn_limit_quotient")]
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
consolidation_churn_limit_quotient: u64,
|
||||
#[serde(default = "default_max_per_epoch_activation_churn_limit_gloas")]
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
max_per_epoch_activation_churn_limit_gloas: u64,
|
||||
}
|
||||
|
||||
fn default_bellatrix_fork_version() -> [u8; 4] {
|
||||
@@ -2362,6 +2399,18 @@ const fn default_min_builder_withdrawability_delay() -> u64 {
|
||||
64
|
||||
}
|
||||
|
||||
const fn default_churn_limit_quotient_gloas() -> u64 {
|
||||
32_768
|
||||
}
|
||||
|
||||
const fn default_consolidation_churn_limit_quotient() -> u64 {
|
||||
65_536
|
||||
}
|
||||
|
||||
const fn default_max_per_epoch_activation_churn_limit_gloas() -> u64 {
|
||||
256_000_000_000
|
||||
}
|
||||
|
||||
fn max_blocks_by_root_request_common(max_request_blocks: u64) -> usize {
|
||||
let max_request_blocks = max_request_blocks as usize;
|
||||
RuntimeVariableList::<Hash256>::new(
|
||||
@@ -2613,6 +2662,11 @@ impl Config {
|
||||
contribution_due_bps: spec.contribution_due_bps,
|
||||
|
||||
min_builder_withdrawability_delay: spec.min_builder_withdrawability_delay.as_u64(),
|
||||
|
||||
churn_limit_quotient_gloas: spec.churn_limit_quotient_gloas,
|
||||
consolidation_churn_limit_quotient: spec.consolidation_churn_limit_quotient,
|
||||
max_per_epoch_activation_churn_limit_gloas: spec
|
||||
.max_per_epoch_activation_churn_limit_gloas,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2710,6 +2764,9 @@ impl Config {
|
||||
sync_message_due_bps,
|
||||
contribution_due_bps,
|
||||
min_builder_withdrawability_delay,
|
||||
churn_limit_quotient_gloas,
|
||||
consolidation_churn_limit_quotient,
|
||||
max_per_epoch_activation_churn_limit_gloas,
|
||||
} = self;
|
||||
|
||||
if preset_base != E::spec_name().to_string().as_str() {
|
||||
@@ -2817,6 +2874,10 @@ impl Config {
|
||||
|
||||
min_builder_withdrawability_delay: Epoch::new(min_builder_withdrawability_delay),
|
||||
|
||||
churn_limit_quotient_gloas,
|
||||
consolidation_churn_limit_quotient,
|
||||
max_per_epoch_activation_churn_limit_gloas,
|
||||
|
||||
..chain_spec.clone()
|
||||
};
|
||||
Some(spec.compute_derived_values::<E>())
|
||||
@@ -3719,9 +3780,7 @@ mod yaml_tests {
|
||||
"CONTRIBUTION_DUE_BPS_GLOAS",
|
||||
"MAX_REQUEST_PAYLOADS",
|
||||
// Heze networking
|
||||
"VIEW_FREEZE_CUTOFF_BPS",
|
||||
"INCLUSION_LIST_SUBMISSION_DUE_BPS",
|
||||
"PROPOSER_INCLUSION_LIST_CUTOFF_BPS",
|
||||
"INCLUSION_LIST_DUE_BPS",
|
||||
"MAX_REQUEST_INCLUSION_LIST",
|
||||
"MAX_BYTES_PER_INCLUSION_LIST",
|
||||
];
|
||||
|
||||
@@ -572,7 +572,7 @@ impl EthSpec for MinimalEthSpec {
|
||||
type NumberOfColumns = U128;
|
||||
type ProposerLookaheadSlots = U16; // Derived from (MIN_SEED_LOOKAHEAD + 1) * SLOTS_PER_EPOCH
|
||||
type BuilderPendingPaymentsLimit = U16; // 2 * SLOTS_PER_EPOCH = 2 * 8 = 16
|
||||
type PTCSize = U2;
|
||||
type PTCSize = U16;
|
||||
type PtcWindowLength = U24; // (2 + MIN_SEED_LOOKAHEAD) * SLOTS_PER_EPOCH
|
||||
type MaxBuildersPerWithdrawalsSweep = U16;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ pub struct ExecutionPayloadEnvelope<E: EthSpec> {
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
pub builder_index: u64,
|
||||
pub beacon_block_root: Hash256,
|
||||
pub parent_beacon_block_root: Hash256,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> ExecutionPayloadEnvelope<E> {
|
||||
@@ -30,6 +31,7 @@ impl<E: EthSpec> ExecutionPayloadEnvelope<E> {
|
||||
execution_requests: ExecutionRequests::default(),
|
||||
builder_index: 0,
|
||||
beacon_block_root: Hash256::zero(),
|
||||
parent_beacon_block_root: Hash256::zero(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2762,29 +2762,55 @@ impl<E: EthSpec> BeaconState<E> {
|
||||
/// Return the churn limit for the current epoch.
|
||||
pub fn get_balance_churn_limit(&self, spec: &ChainSpec) -> Result<u64, BeaconStateError> {
|
||||
let total_active_balance = self.get_total_active_balance()?;
|
||||
let quotient = if self.fork_name_unchecked().gloas_enabled() {
|
||||
spec.churn_limit_quotient_gloas
|
||||
} else {
|
||||
spec.churn_limit_quotient
|
||||
};
|
||||
let churn = std::cmp::max(
|
||||
spec.min_per_epoch_churn_limit_electra,
|
||||
total_active_balance.safe_div(spec.churn_limit_quotient)?,
|
||||
total_active_balance.safe_div(quotient)?,
|
||||
);
|
||||
|
||||
Ok(churn.safe_sub(churn.safe_rem(spec.effective_balance_increment)?)?)
|
||||
}
|
||||
|
||||
/// Return the churn limit for the current epoch dedicated to activations and exits.
|
||||
///
|
||||
/// From Gloas onwards this is the activation-only churn limit (EIP-8061); exits use
|
||||
/// [`Self::get_exit_churn_limit`].
|
||||
pub fn get_activation_exit_churn_limit(
|
||||
&self,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<u64, BeaconStateError> {
|
||||
let max_limit = if self.fork_name_unchecked().gloas_enabled() {
|
||||
spec.max_per_epoch_activation_churn_limit_gloas
|
||||
} else {
|
||||
spec.max_per_epoch_activation_exit_churn_limit
|
||||
};
|
||||
Ok(std::cmp::min(
|
||||
spec.max_per_epoch_activation_exit_churn_limit,
|
||||
max_limit,
|
||||
self.get_balance_churn_limit(spec)?,
|
||||
))
|
||||
}
|
||||
|
||||
/// Return the Gloas (EIP-8061) exit churn limit for the current epoch.
|
||||
///
|
||||
/// Unlike [`Self::get_activation_exit_churn_limit`], this is uncapped.
|
||||
pub fn get_exit_churn_limit(&self, spec: &ChainSpec) -> Result<u64, BeaconStateError> {
|
||||
self.get_balance_churn_limit(spec)
|
||||
}
|
||||
|
||||
pub fn get_consolidation_churn_limit(&self, spec: &ChainSpec) -> Result<u64, BeaconStateError> {
|
||||
self.get_balance_churn_limit(spec)?
|
||||
.safe_sub(self.get_activation_exit_churn_limit(spec)?)
|
||||
.map_err(Into::into)
|
||||
if self.fork_name_unchecked().gloas_enabled() {
|
||||
let total_active_balance = self.get_total_active_balance()?;
|
||||
let churn = total_active_balance.safe_div(spec.consolidation_churn_limit_quotient)?;
|
||||
Ok(churn.safe_sub(churn.safe_rem(spec.effective_balance_increment)?)?)
|
||||
} else {
|
||||
self.get_balance_churn_limit(spec)?
|
||||
.safe_sub(self.get_activation_exit_churn_limit(spec)?)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_pending_balance_to_withdraw(
|
||||
@@ -2879,7 +2905,11 @@ impl<E: EthSpec> BeaconState<E> {
|
||||
self.compute_activation_exit_epoch(self.current_epoch(), spec)?,
|
||||
);
|
||||
|
||||
let per_epoch_churn = self.get_activation_exit_churn_limit(spec)?;
|
||||
let per_epoch_churn = if self.fork_name_unchecked().gloas_enabled() {
|
||||
self.get_exit_churn_limit(spec)?
|
||||
} else {
|
||||
self.get_activation_exit_churn_limit(spec)?
|
||||
};
|
||||
// New epoch for exits
|
||||
let mut exit_balance_to_consume = if self.earliest_exit_epoch()? < earliest_exit_epoch {
|
||||
per_epoch_churn
|
||||
@@ -3103,7 +3133,19 @@ impl<E: EthSpec> BeaconState<E> {
|
||||
let total_active_balance = self.get_total_active_balance()?;
|
||||
let fork_name = self.fork_name_unchecked();
|
||||
|
||||
if fork_name.electra_enabled() {
|
||||
if fork_name.gloas_enabled() {
|
||||
// [Modified in Gloas:EIP8061]
|
||||
let exit_churn = self.get_exit_churn_limit(spec)?;
|
||||
let activation_churn = self.get_activation_exit_churn_limit(spec)?;
|
||||
let consolidation_churn = self.get_consolidation_churn_limit(spec)?;
|
||||
compute_weak_subjectivity_period_gloas(
|
||||
total_active_balance,
|
||||
exit_churn,
|
||||
activation_churn,
|
||||
consolidation_churn,
|
||||
spec,
|
||||
)
|
||||
} else if fork_name.electra_enabled() {
|
||||
let balance_churn_limit = self.get_balance_churn_limit(spec)?;
|
||||
compute_weak_subjectivity_period_electra(
|
||||
total_active_balance,
|
||||
@@ -3601,6 +3643,30 @@ pub fn compute_weak_subjectivity_period_electra(
|
||||
Ok(ws_period)
|
||||
}
|
||||
|
||||
/// Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.6/specs/gloas/weak-subjectivity.md
|
||||
pub fn compute_weak_subjectivity_period_gloas(
|
||||
total_active_balance: u64,
|
||||
exit_churn_limit: u64,
|
||||
activation_churn_limit: u64,
|
||||
consolidation_churn_limit: u64,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Epoch, BeaconStateError> {
|
||||
// delta = 2 * exit_churn // 3 + activation_churn // 3 + consolidation_churn
|
||||
let delta = exit_churn_limit
|
||||
.safe_mul(2)?
|
||||
.safe_div(3)?
|
||||
.safe_add(activation_churn_limit.safe_div(3)?)?
|
||||
.safe_add(consolidation_churn_limit)?;
|
||||
let epochs_for_validator_set_churn = SAFETY_DECAY
|
||||
.safe_mul(total_active_balance)?
|
||||
.safe_div(delta.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;
|
||||
|
||||
Reference in New Issue
Block a user