mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
Update attestation rewards API for Electra (#6819)
Closes: - https://github.com/sigp/lighthouse/issues/6818 Use `MAX_EFFECTIVE_BALANCE_ELECTRA` (2048) for attestation reward calculations involving Electra. Add a new `InteropGenesisBuilder` that tries to provide a more flexible way to build genesis states. Unfortunately due to lifetime jank, it is quite unergonomic at present. We may want to refactor this builder in future to make it easier to use.
This commit is contained in:
@@ -24,10 +24,134 @@ fn eth1_withdrawal_credentials(pubkey: &PublicKey, spec: &ChainSpec) -> Hash256
|
||||
Hash256::from_slice(&credentials)
|
||||
}
|
||||
|
||||
pub type WithdrawalCredentialsFn =
|
||||
Box<dyn for<'a> Fn(usize, &'a PublicKey, &'a ChainSpec) -> Hash256>;
|
||||
|
||||
/// Builds a genesis state as defined by the Eth2 interop procedure (see below).
|
||||
///
|
||||
/// Reference:
|
||||
/// https://github.com/ethereum/eth2.0-pm/tree/6e41fcf383ebeb5125938850d8e9b4e9888389b4/interop/mocked_start
|
||||
#[derive(Default)]
|
||||
pub struct InteropGenesisBuilder<E: EthSpec> {
|
||||
/// Mapping from validator index to initial balance for each validator.
|
||||
///
|
||||
/// If `None`, then the default balance of 32 ETH will be used.
|
||||
initial_balance_fn: Option<Box<dyn Fn(usize) -> u64>>,
|
||||
|
||||
/// Mapping from validator index and pubkey to withdrawal credentials for each validator.
|
||||
///
|
||||
/// If `None`, then default BLS withdrawal credentials will be used.
|
||||
withdrawal_credentials_fn: Option<WithdrawalCredentialsFn>,
|
||||
|
||||
/// The execution payload header to embed in the genesis state.
|
||||
execution_payload_header: Option<ExecutionPayloadHeader<E>>,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> InteropGenesisBuilder<E> {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn set_initial_balance_fn(mut self, initial_balance_fn: Box<dyn Fn(usize) -> u64>) -> Self {
|
||||
self.initial_balance_fn = Some(initial_balance_fn);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_withdrawal_credentials_fn(
|
||||
mut self,
|
||||
withdrawal_credentials_fn: WithdrawalCredentialsFn,
|
||||
) -> Self {
|
||||
self.withdrawal_credentials_fn = Some(withdrawal_credentials_fn);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_alternating_eth1_withdrawal_credentials(self) -> Self {
|
||||
self.set_withdrawal_credentials_fn(Box::new(alternating_eth1_withdrawal_credentials_fn))
|
||||
}
|
||||
|
||||
pub fn set_execution_payload_header(
|
||||
self,
|
||||
execution_payload_header: ExecutionPayloadHeader<E>,
|
||||
) -> Self {
|
||||
self.set_opt_execution_payload_header(Some(execution_payload_header))
|
||||
}
|
||||
|
||||
pub fn set_opt_execution_payload_header(
|
||||
mut self,
|
||||
execution_payload_header: Option<ExecutionPayloadHeader<E>>,
|
||||
) -> Self {
|
||||
self.execution_payload_header = execution_payload_header;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build_genesis_state(
|
||||
self,
|
||||
keypairs: &[Keypair],
|
||||
genesis_time: u64,
|
||||
eth1_block_hash: Hash256,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<BeaconState<E>, String> {
|
||||
// Generate withdrawal credentials using provided function, or default BLS.
|
||||
let withdrawal_credentials_fn = self.withdrawal_credentials_fn.unwrap_or_else(|| {
|
||||
Box::new(|_, pubkey, spec| bls_withdrawal_credentials(pubkey, spec))
|
||||
});
|
||||
|
||||
let withdrawal_credentials = keypairs
|
||||
.iter()
|
||||
.map(|key| &key.pk)
|
||||
.enumerate()
|
||||
.map(|(i, pubkey)| withdrawal_credentials_fn(i, pubkey, spec))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Generate initial balances.
|
||||
let initial_balance_fn = self
|
||||
.initial_balance_fn
|
||||
.unwrap_or_else(|| Box::new(|_| spec.max_effective_balance));
|
||||
|
||||
let eth1_timestamp = 2_u64.pow(40);
|
||||
|
||||
let initial_balances = (0..keypairs.len())
|
||||
.map(initial_balance_fn)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let datas = keypairs
|
||||
.into_par_iter()
|
||||
.zip(withdrawal_credentials.into_par_iter())
|
||||
.zip(initial_balances.into_par_iter())
|
||||
.map(|((keypair, withdrawal_credentials), amount)| {
|
||||
let mut data = DepositData {
|
||||
withdrawal_credentials,
|
||||
pubkey: keypair.pk.clone().into(),
|
||||
amount,
|
||||
signature: Signature::empty().into(),
|
||||
};
|
||||
|
||||
data.signature = data.create_signature(&keypair.sk, spec);
|
||||
|
||||
data
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut state = initialize_beacon_state_from_eth1(
|
||||
eth1_block_hash,
|
||||
eth1_timestamp,
|
||||
genesis_deposits(datas, spec)?,
|
||||
self.execution_payload_header,
|
||||
spec,
|
||||
)
|
||||
.map_err(|e| format!("Unable to initialize genesis state: {:?}", e))?;
|
||||
|
||||
*state.genesis_time_mut() = genesis_time;
|
||||
|
||||
// Invalidate all the caches after all the manual state surgery.
|
||||
state
|
||||
.drop_all_caches()
|
||||
.map_err(|e| format!("Unable to drop caches: {:?}", e))?;
|
||||
|
||||
Ok(state)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn interop_genesis_state<E: EthSpec>(
|
||||
keypairs: &[Keypair],
|
||||
genesis_time: u64,
|
||||
@@ -35,18 +159,21 @@ pub fn interop_genesis_state<E: EthSpec>(
|
||||
execution_payload_header: Option<ExecutionPayloadHeader<E>>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<BeaconState<E>, String> {
|
||||
let withdrawal_credentials = keypairs
|
||||
.iter()
|
||||
.map(|keypair| bls_withdrawal_credentials(&keypair.pk, spec))
|
||||
.collect::<Vec<_>>();
|
||||
interop_genesis_state_with_withdrawal_credentials::<E>(
|
||||
keypairs,
|
||||
&withdrawal_credentials,
|
||||
genesis_time,
|
||||
eth1_block_hash,
|
||||
execution_payload_header,
|
||||
spec,
|
||||
)
|
||||
InteropGenesisBuilder::new()
|
||||
.set_opt_execution_payload_header(execution_payload_header)
|
||||
.build_genesis_state(keypairs, genesis_time, eth1_block_hash, spec)
|
||||
}
|
||||
|
||||
fn alternating_eth1_withdrawal_credentials_fn<'a>(
|
||||
index: usize,
|
||||
pubkey: &'a PublicKey,
|
||||
spec: &'a ChainSpec,
|
||||
) -> Hash256 {
|
||||
if index % 2usize == 0usize {
|
||||
bls_withdrawal_credentials(pubkey, spec)
|
||||
} else {
|
||||
eth1_withdrawal_credentials(pubkey, spec)
|
||||
}
|
||||
}
|
||||
|
||||
// returns an interop genesis state except every other
|
||||
@@ -58,80 +185,10 @@ pub fn interop_genesis_state_with_eth1<E: EthSpec>(
|
||||
execution_payload_header: Option<ExecutionPayloadHeader<E>>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<BeaconState<E>, String> {
|
||||
let withdrawal_credentials = keypairs
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, keypair)| {
|
||||
if index % 2 == 0 {
|
||||
bls_withdrawal_credentials(&keypair.pk, spec)
|
||||
} else {
|
||||
eth1_withdrawal_credentials(&keypair.pk, spec)
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
interop_genesis_state_with_withdrawal_credentials::<E>(
|
||||
keypairs,
|
||||
&withdrawal_credentials,
|
||||
genesis_time,
|
||||
eth1_block_hash,
|
||||
execution_payload_header,
|
||||
spec,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn interop_genesis_state_with_withdrawal_credentials<E: EthSpec>(
|
||||
keypairs: &[Keypair],
|
||||
withdrawal_credentials: &[Hash256],
|
||||
genesis_time: u64,
|
||||
eth1_block_hash: Hash256,
|
||||
execution_payload_header: Option<ExecutionPayloadHeader<E>>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<BeaconState<E>, String> {
|
||||
if keypairs.len() != withdrawal_credentials.len() {
|
||||
return Err(format!(
|
||||
"wrong number of withdrawal credentials, expected: {}, got: {}",
|
||||
keypairs.len(),
|
||||
withdrawal_credentials.len()
|
||||
));
|
||||
}
|
||||
|
||||
let eth1_timestamp = 2_u64.pow(40);
|
||||
let amount = spec.max_effective_balance;
|
||||
|
||||
let datas = keypairs
|
||||
.into_par_iter()
|
||||
.zip(withdrawal_credentials.into_par_iter())
|
||||
.map(|(keypair, &withdrawal_credentials)| {
|
||||
let mut data = DepositData {
|
||||
withdrawal_credentials,
|
||||
pubkey: keypair.pk.clone().into(),
|
||||
amount,
|
||||
signature: Signature::empty().into(),
|
||||
};
|
||||
|
||||
data.signature = data.create_signature(&keypair.sk, spec);
|
||||
|
||||
data
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut state = initialize_beacon_state_from_eth1(
|
||||
eth1_block_hash,
|
||||
eth1_timestamp,
|
||||
genesis_deposits(datas, spec)?,
|
||||
execution_payload_header,
|
||||
spec,
|
||||
)
|
||||
.map_err(|e| format!("Unable to initialize genesis state: {:?}", e))?;
|
||||
|
||||
*state.genesis_time_mut() = genesis_time;
|
||||
|
||||
// Invalidate all the caches after all the manual state surgery.
|
||||
state
|
||||
.drop_all_caches()
|
||||
.map_err(|e| format!("Unable to drop caches: {:?}", e))?;
|
||||
|
||||
Ok(state)
|
||||
InteropGenesisBuilder::new()
|
||||
.set_alternating_eth1_withdrawal_credentials()
|
||||
.set_opt_execution_payload_header(execution_payload_header)
|
||||
.build_genesis_state(keypairs, genesis_time, eth1_block_hash, spec)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -7,6 +7,6 @@ pub use eth1::Eth1Endpoint;
|
||||
pub use eth1_genesis_service::{Eth1GenesisService, Statistics};
|
||||
pub use interop::{
|
||||
bls_withdrawal_credentials, interop_genesis_state, interop_genesis_state_with_eth1,
|
||||
interop_genesis_state_with_withdrawal_credentials, DEFAULT_ETH1_BLOCK_HASH,
|
||||
InteropGenesisBuilder, DEFAULT_ETH1_BLOCK_HASH,
|
||||
};
|
||||
pub use types::test_utils::generate_deterministic_keypairs;
|
||||
|
||||
Reference in New Issue
Block a user