Added Capella Epoch Processing Logic (#3666)
This commit is contained in:
parent
137f230344
commit
f1a3b3b01c
@ -381,6 +381,8 @@ impl<T: EthSpec> From<ExecutionPayload<T>> for JsonExecutionPayload<T> {
|
||||
pub struct JsonWithdrawal {
|
||||
#[serde(with = "eth2_serde_utils::u64_hex_be")]
|
||||
pub index: u64,
|
||||
#[serde(with = "eth2_serde_utils::u64_hex_be")]
|
||||
pub validator_index: u64,
|
||||
pub address: Address,
|
||||
#[serde(with = "eth2_serde_utils::u256_hex_be")]
|
||||
pub amount: Uint256,
|
||||
@ -390,6 +392,7 @@ impl From<Withdrawal> for JsonWithdrawal {
|
||||
fn from(withdrawal: Withdrawal) -> Self {
|
||||
Self {
|
||||
index: withdrawal.index,
|
||||
validator_index: withdrawal.validator_index,
|
||||
address: withdrawal.address,
|
||||
amount: Uint256::from((withdrawal.amount as u128) * 1000000000u128),
|
||||
}
|
||||
@ -400,6 +403,7 @@ impl From<JsonWithdrawal> for Withdrawal {
|
||||
fn from(jw: JsonWithdrawal) -> Self {
|
||||
Self {
|
||||
index: jw.index,
|
||||
validator_index: jw.validator_index,
|
||||
address: jw.address,
|
||||
//FIXME(sean) if EE gives us too large a number this panics
|
||||
amount: (jw.amount / 1000000000).as_u64(),
|
||||
|
@ -4,6 +4,7 @@ mod get_attesting_indices;
|
||||
mod get_indexed_attestation;
|
||||
mod initiate_validator_exit;
|
||||
mod slash_validator;
|
||||
mod withdraw_balance;
|
||||
|
||||
pub mod altair;
|
||||
pub mod base;
|
||||
@ -14,6 +15,7 @@ pub use get_attesting_indices::{get_attesting_indices, get_attesting_indices_fro
|
||||
pub use get_indexed_attestation::get_indexed_attestation;
|
||||
pub use initiate_validator_exit::initiate_validator_exit;
|
||||
pub use slash_validator::slash_validator;
|
||||
pub use withdraw_balance::withdraw_balance;
|
||||
|
||||
use safe_arith::SafeArith;
|
||||
use types::{BeaconState, BeaconStateError, EthSpec};
|
||||
|
28
consensus/state_processing/src/common/withdraw_balance.rs
Normal file
28
consensus/state_processing/src/common/withdraw_balance.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use crate::common::decrease_balance;
|
||||
use safe_arith::SafeArith;
|
||||
use types::{BeaconStateError as Error, *};
|
||||
|
||||
pub fn withdraw_balance<T: EthSpec>(
|
||||
state: &mut BeaconState<T>,
|
||||
validator_index: usize,
|
||||
amount: u64,
|
||||
) -> Result<(), Error> {
|
||||
decrease_balance(state, validator_index as usize, amount)?;
|
||||
|
||||
let withdrawal_address = Address::from_slice(
|
||||
&state
|
||||
.get_validator(validator_index)?
|
||||
.withdrawal_credentials
|
||||
.as_bytes()[12..],
|
||||
);
|
||||
let withdrawal = Withdrawal {
|
||||
index: *state.next_withdrawal_index()?,
|
||||
validator_index: validator_index as u64,
|
||||
address: withdrawal_address,
|
||||
amount,
|
||||
};
|
||||
state.next_withdrawal_index_mut()?.safe_add_assign(1)?;
|
||||
state.withdrawal_queue_mut()?.push(withdrawal)?;
|
||||
|
||||
Ok(())
|
||||
}
|
@ -66,9 +66,9 @@ pub fn process_epoch<T: EthSpec>(
|
||||
altair::process_sync_committee_updates(state, spec)?;
|
||||
|
||||
// Withdrawals
|
||||
process_full_withdrawals(state)?;
|
||||
process_full_withdrawals(state, spec)?;
|
||||
|
||||
process_partial_withdrawals(state)?;
|
||||
process_partial_withdrawals(state, spec)?;
|
||||
|
||||
// Rotate the epoch caches to suit the epoch transition.
|
||||
state.advance_caches(spec)?;
|
||||
|
@ -1,10 +1,23 @@
|
||||
use crate::common::withdraw_balance;
|
||||
use crate::EpochProcessingError;
|
||||
use types::beacon_state::BeaconState;
|
||||
use types::eth_spec::EthSpec;
|
||||
use types::{beacon_state::BeaconState, eth_spec::EthSpec, ChainSpec};
|
||||
|
||||
pub fn process_full_withdrawals<T: EthSpec>(
|
||||
_state: &mut BeaconState<T>,
|
||||
state: &mut BeaconState<T>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), EpochProcessingError> {
|
||||
todo!("implement this");
|
||||
let current_epoch = state.current_epoch();
|
||||
// FIXME: is this the most efficient way to do this?
|
||||
for validator_index in 0..state.validators().len() {
|
||||
// TODO: is this the correct way to handle validators not existing?
|
||||
if let (Some(validator), Some(balance)) = (
|
||||
state.validators().get(validator_index),
|
||||
state.balances().get(validator_index),
|
||||
) {
|
||||
if validator.is_fully_withdrawable_at(*balance, current_epoch, spec) {
|
||||
withdraw_balance(state, validator_index, *balance)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,10 +1,39 @@
|
||||
use crate::common::withdraw_balance;
|
||||
use crate::EpochProcessingError;
|
||||
use types::beacon_state::BeaconState;
|
||||
use types::eth_spec::EthSpec;
|
||||
use safe_arith::SafeArith;
|
||||
use types::{beacon_state::BeaconState, eth_spec::EthSpec, ChainSpec};
|
||||
|
||||
pub fn process_partial_withdrawals<T: EthSpec>(
|
||||
_state: &mut BeaconState<T>,
|
||||
state: &mut BeaconState<T>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), EpochProcessingError> {
|
||||
todo!("implement this");
|
||||
let mut partial_withdrawals_count = 0;
|
||||
let mut validator_index = *state.next_partial_withdrawal_validator_index()? as usize;
|
||||
|
||||
let n_validators = state.validators().len();
|
||||
// FIXME: is this the most efficient way to do this?
|
||||
for _ in 0..n_validators {
|
||||
// TODO: is this the correct way to handle validators not existing?
|
||||
if let (Some(validator), Some(balance)) = (
|
||||
state.validators().get(validator_index),
|
||||
state.balances().get(validator_index),
|
||||
) {
|
||||
if validator.is_partially_withdrawable_validator(*balance, spec) {
|
||||
withdraw_balance(
|
||||
state,
|
||||
validator_index,
|
||||
*balance - spec.max_effective_balance,
|
||||
)?;
|
||||
partial_withdrawals_count.safe_add_assign(1)?;
|
||||
|
||||
validator_index = validator_index.safe_add(1)? % n_validators;
|
||||
if partial_withdrawals_count == T::max_partial_withdrawals_per_epoch() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*state.next_partial_withdrawal_validator_index_mut()? = validator_index as u64;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ pub struct ChainSpec {
|
||||
*/
|
||||
pub genesis_fork_version: [u8; 4],
|
||||
pub bls_withdrawal_prefix_byte: u8,
|
||||
pub eth1_address_withdrawal_prefix_byte: u8,
|
||||
|
||||
/*
|
||||
* Time parameters
|
||||
@ -519,7 +520,8 @@ impl ChainSpec {
|
||||
* Initial Values
|
||||
*/
|
||||
genesis_fork_version: [0; 4],
|
||||
bls_withdrawal_prefix_byte: 0,
|
||||
bls_withdrawal_prefix_byte: 0x00,
|
||||
eth1_address_withdrawal_prefix_byte: 0x01,
|
||||
|
||||
/*
|
||||
* Time parameters
|
||||
@ -748,7 +750,8 @@ impl ChainSpec {
|
||||
* Initial Values
|
||||
*/
|
||||
genesis_fork_version: [0x00, 0x00, 0x00, 0x64],
|
||||
bls_withdrawal_prefix_byte: 0,
|
||||
bls_withdrawal_prefix_byte: 0x00,
|
||||
eth1_address_withdrawal_prefix_byte: 0x01,
|
||||
|
||||
/*
|
||||
* Time parameters
|
||||
|
@ -65,6 +65,27 @@ impl Validator {
|
||||
// Has not yet been activated
|
||||
&& self.activation_epoch == spec.far_future_epoch
|
||||
}
|
||||
|
||||
/// Returns `true` if the validator has eth1 withdrawal credential
|
||||
pub fn has_eth1_withdrawal_credential(&self, spec: &ChainSpec) -> bool {
|
||||
self.withdrawal_credentials
|
||||
.as_bytes()
|
||||
.first()
|
||||
.map(|byte| *byte == spec.eth1_address_withdrawal_prefix_byte)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Returns `true` if the validator is fully withdrawable at some epoch
|
||||
pub fn is_fully_withdrawable_at(&self, balance: u64, epoch: Epoch, spec: &ChainSpec) -> bool {
|
||||
self.has_eth1_withdrawal_credential(spec) && self.withdrawable_epoch <= epoch && balance > 0
|
||||
}
|
||||
|
||||
/// Returns `true` if the validator is partially withdrawable
|
||||
pub fn is_partially_withdrawable_validator(&self, balance: u64, spec: &ChainSpec) -> bool {
|
||||
self.has_eth1_withdrawal_credential(spec)
|
||||
&& self.effective_balance == spec.max_effective_balance
|
||||
&& balance > spec.max_effective_balance
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Validator {
|
||||
|
@ -15,6 +15,7 @@ use tree_hash_derive::TreeHash;
|
||||
pub struct Withdrawal {
|
||||
#[serde(with = "eth2_serde_utils::quoted_u64")]
|
||||
pub index: u64,
|
||||
pub validator_index: u64,
|
||||
pub address: Address,
|
||||
pub amount: u64,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user