Refactor postponed deposit processing

This commit is contained in:
Mikhail Kalinin 2024-07-05 18:04:38 +06:00
parent 5a2f887f76
commit ee4da7b58a
1 changed files with 38 additions and 61 deletions

View File

@ -59,7 +59,6 @@
- [New `get_active_balance`](#new-get_active_balance) - [New `get_active_balance`](#new-get_active_balance)
- [New `get_pending_balance_to_withdraw`](#new-get_pending_balance_to_withdraw) - [New `get_pending_balance_to_withdraw`](#new-get_pending_balance_to_withdraw)
- [Modified `get_attesting_indices`](#modified-get_attesting_indices) - [Modified `get_attesting_indices`](#modified-get_attesting_indices)
- [New `get_activation_churn_consumption`](#new-get_activation_churn_consumption)
- [Modified `get_next_sync_committee_indices`](#modified-get_next_sync_committee_indices) - [Modified `get_next_sync_committee_indices`](#modified-get_next_sync_committee_indices)
- [Beacon state mutators](#beacon-state-mutators) - [Beacon state mutators](#beacon-state-mutators)
- [Modified `initiate_validator_exit`](#modified-initiate_validator_exit) - [Modified `initiate_validator_exit`](#modified-initiate_validator_exit)
@ -633,27 +632,6 @@ def get_attesting_indices(state: BeaconState, attestation: Attestation) -> Set[V
return output return output
``` ```
#### New `get_activation_churn_consumption`
```python
def get_activation_churn_consumption(state: BeaconState, deposit: PendingDeposit) -> Gwei:
"""
Return amount of activation churn consumed by the ``deposit``.
"""
validator_pubkeys = [v.pubkey for v in state.validators]
if deposit.pubkey not in validator_pubkeys:
return deposit.amount
else:
validator_index = ValidatorIndex(validator_pubkeys.index(deposit.pubkey))
validator = state.validators[validator_index]
# Validator is exiting, do not consume the churn
if validator.exit_epoch < FAR_FUTURE_EPOCH:
return Gwei(0)
else:
return deposit.amount
```
#### Modified `get_next_sync_committee_indices` #### Modified `get_next_sync_committee_indices`
*Note*: The function `get_next_sync_committee_indices` is modified to use `MAX_EFFECTIVE_BALANCE_ELECTRA`. *Note*: The function `get_next_sync_committee_indices` is modified to use `MAX_EFFECTIVE_BALANCE_ELECTRA`.
@ -892,11 +870,9 @@ def process_registry_updates(state: BeaconState) -> None:
#### New `apply_pending_deposit` #### New `apply_pending_deposit`
```python ```python
def apply_pending_deposit(state: BeaconState, deposit: PendingDeposit) -> bool: def apply_pending_deposit(state: BeaconState, deposit: PendingDeposit) -> None:
""" """
Applies ``deposit`` to the ``state``. Applies ``deposit`` to the ``state``.
Returns ``True`` if ``deposit`` has been successfully applied
and can be removed from the queue.
""" """
validator_pubkeys = [v.pubkey for v in state.validators] validator_pubkeys = [v.pubkey for v in state.validators]
if deposit.pubkey not in validator_pubkeys: if deposit.pubkey not in validator_pubkeys:
@ -910,32 +886,22 @@ def apply_pending_deposit(state: BeaconState, deposit: PendingDeposit) -> bool:
add_validator_to_registry(state, deposit.pubkey, deposit.withdrawal_credentials, deposit.amount) add_validator_to_registry(state, deposit.pubkey, deposit.withdrawal_credentials, deposit.amount)
else: else:
validator_index = ValidatorIndex(validator_pubkeys.index(deposit.pubkey)) validator_index = ValidatorIndex(validator_pubkeys.index(deposit.pubkey))
# Increase balance
increase_balance(state, validator_index, deposit.amount)
# If validator has not exited, check if valid deposit switch to compounding credentials.
validator = state.validators[validator_index] validator = state.validators[validator_index]
# Validator is exiting, postpone the deposit until after withdrawable epoch if (
if validator.exit_epoch < FAR_FUTURE_EPOCH: validator.exit_epoch < get_current_epoch(state)
if get_current_epoch(state) <= validator.withdrawable_epoch: and is_compounding_withdrawal_credential(deposit.withdrawal_credentials)
return False and has_eth1_withdrawal_credential(validator)
# Deposited balance will never become active. Increase balance but do not consume churn and is_valid_deposit_signature(
else: deposit.pubkey,
increase_balance(state, validator_index, deposit.amount) deposit.withdrawal_credentials,
# Validator is not exiting, attempt to process deposit deposit.amount,
else: deposit.signature
# Increase balance )
increase_balance(state, validator_index, deposit.amount) ):
# Check if valid deposit switch to compounding credentials. switch_to_compounding_validator(state, validator_index)
if (
is_compounding_withdrawal_credential(deposit.withdrawal_credentials)
and has_eth1_withdrawal_credential(validator)
and is_valid_deposit_signature(
deposit.pubkey,
deposit.withdrawal_credentials,
deposit.amount,
deposit.signature
)
):
switch_to_compounding_validator(state, validator_index)
return True
``` ```
#### New `process_pending_deposits` #### New `process_pending_deposits`
@ -973,19 +939,30 @@ def process_pending_deposits(state: BeaconState) -> None:
if next_deposit_index >= MAX_PENDING_DEPOSITS_PER_EPOCH_PROCESSING: if next_deposit_index >= MAX_PENDING_DEPOSITS_PER_EPOCH_PROCESSING:
break break
# Check if deposit fits in the churn, otherwise, do no more deposit processing in this epoch. # Read validator state
churn_consumption = get_activation_churn_consumption(state, deposit) is_validator_exited = False
if processed_amount + churn_consumption > available_for_processing: is_validator_withdrawn = False
is_churn_limit_reached = True validator_pubkeys = [v.pubkey for v in state.validators]
break if deposit.pubkey:
validator = state.validators[ValidatorIndex(validator_pubkeys.index(deposit.pubkey))]
is_validator_exited = validator.exit_epoch < FAR_FUTURE_EPOCH
is_validator_withdrawn = validator.withdrawable_epoch < get_current_epoch(state)
# Consume churn and apply deposit if is_validator_withdrawn:
processed_amount += churn_consumption # Deposited balance will never become active. Increase balance but do not consume churn
is_deposit_applied = apply_pending_deposit(state, deposit) apply_pending_deposit(state, deposit)
elif is_validator_exited:
# Postpone deposit if it has not been applied. # Validator is exiting, postpone the deposit until after withdrawable epoch
if not is_deposit_applied:
deposits_to_postpone.append(deposit) deposits_to_postpone.append(deposit)
else:
# Check if deposit fits in the churn, otherwise, do no more deposit processing in this epoch.
is_churn_limit_reached = processed_amount + deposit.amount > available_for_processing
if is_churn_limit_reached:
break
# Consume churn and apply deposit.
processed_amount += deposit.amount
apply_pending_deposit(state, deposit)
# Regardless of how the deposit was handled, we move on in the queue. # Regardless of how the deposit was handled, we move on in the queue.
next_deposit_index += 1 next_deposit_index += 1