Skip to content

Commit 43e7344

Browse files
committed
Refactor process_pending_deposits
1 parent 179ee8e commit 43e7344

File tree

1 file changed

+76
-48
lines changed

1 file changed

+76
-48
lines changed

specs/electra/beacon-chain.md

Lines changed: 76 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
- [Epoch processing](#epoch-processing)
7373
- [Updated `process_epoch`](#updated-process_epoch)
7474
- [Updated `process_registry_updates`](#updated--process_registry_updates)
75+
- [New `apply_pending_deposit`](#new-apply_pending_deposit)
7576
- [New `process_pending_deposits`](#new-process_pending_deposits)
7677
- [New `process_pending_consolidations`](#new-process_pending_consolidations)
7778
- [Updated `process_effective_balance_updates`](#updated-process_effective_balance_updates)
@@ -626,22 +627,22 @@ def get_attesting_indices(state: BeaconState, attestation: Attestation) -> Set[V
626627
#### `get_activation_churn_consumption`
627628

628629
```python
629-
def get_activation_churn_consumption(state: BeaconState, pending_deposit: PendingDeposit) -> Gwei:
630+
def get_activation_churn_consumption(state: BeaconState, deposit: PendingDeposit) -> Gwei:
630631
"""
631-
Return amount of activation churn consumed by the ``pending_deposit``.
632+
Return amount of activation churn consumed by the ``deposit``.
632633
"""
633634
validator_pubkeys = [v.pubkey for v in state.validators]
634635

635-
if pending_deposit.pubkey not in validator_pubkeys:
636-
return pending_deposit.amount
636+
if deposit.pubkey not in validator_pubkeys:
637+
return deposit.amount
637638
else:
638-
validator_index = ValidatorIndex(validator_pubkeys.index(pending_deposit.pubkey))
639+
validator_index = ValidatorIndex(validator_pubkeys.index(deposit.pubkey))
639640
validator = state.validators[validator_index]
640641
# Validator is exiting, do not consume the churn
641642
if validator.exit_epoch < FAR_FUTURE_EPOCH:
642643
return Gwei(0)
643644
else:
644-
return pending_deposit.amount
645+
return deposit.amount
645646
```
646647

647648
### Beacon state mutators
@@ -842,8 +843,63 @@ def process_registry_updates(state: BeaconState) -> None:
842843
validator.activation_epoch = activation_epoch
843844
```
844845

846+
#### New `apply_pending_deposit`
847+
848+
```python
849+
def apply_pending_deposit(state: BeaconState, deposit: PendingDeposit) -> bool:
850+
"""
851+
Applies ``deposit`` to the ``state``.
852+
Returns ``True`` if ``deposit`` has been successfully applied
853+
and can be removed from the queue.
854+
"""
855+
validator_pubkeys = [v.pubkey for v in state.validators]
856+
if deposit.pubkey not in validator_pubkeys:
857+
# Verify the deposit signature (proof of possession) which is not checked by the deposit contract
858+
if is_valid_deposit_signature(
859+
deposit.pubkey,
860+
deposit.withdrawal_credentials,
861+
deposit.amount,
862+
deposit.signature
863+
):
864+
add_validator_to_registry(state, deposit.pubkey, deposit.withdrawal_credentials, deposit.amount)
865+
else:
866+
validator_index = ValidatorIndex(validator_pubkeys.index(deposit.pubkey))
867+
validator = state.validators[validator_index]
868+
# Validator is exiting, postpone the deposit until after withdrawable epoch
869+
if validator.exit_epoch < FAR_FUTURE_EPOCH:
870+
if get_current_epoch(state) <= validator.withdrawable_epoch:
871+
return False
872+
# Deposited balance will never become active. Increase balance but do not consume churn
873+
else:
874+
increase_balance(state, validator_index, deposit.amount)
875+
# Validator is not exiting, attempt to process deposit
876+
else:
877+
# Increase balance
878+
increase_balance(state, validator_index, deposit.amount)
879+
# Check if valid deposit switch to compounding credentials.
880+
if (
881+
is_compounding_withdrawal_credential(deposit.withdrawal_credentials)
882+
and has_eth1_withdrawal_credential(validator)
883+
and is_valid_deposit_signature(
884+
deposit.pubkey,
885+
deposit.withdrawal_credentials,
886+
deposit.amount,
887+
deposit.signature
888+
)
889+
):
890+
switch_to_compounding_validator(state, validator_index)
891+
892+
return True
893+
```
894+
845895
#### New `process_pending_deposits`
846896

897+
Iterating over `pending_deposits` queue this function runs the following checks before applying pending deposit:
898+
1. All Eth1 bridge deposits are processed before the first deposit request gets processed.
899+
2. Deposit position in the queue is finalized.
900+
3. Deposit does not exceed the `MAX_PENDING_DEPOSITS_PER_EPOCH_PROCESSING` limit.
901+
4. Deposit does not exceed the activation churn limit.
902+
847903
```python
848904
def process_pending_deposits(state: BeaconState) -> None:
849905
available_for_processing = state.deposit_balance_to_consume + get_activation_exit_churn_limit(state)
@@ -854,16 +910,20 @@ def process_pending_deposits(state: BeaconState) -> None:
854910
finalized_slot = compute_start_slot_at_epoch(state.finalized_checkpoint.epoch)
855911

856912
for deposit in state.pending_deposits:
857-
# Do not process a deposit request if Eth1 bridge deposits are not yet applied.
858-
is_deposit_request = deposit.slot > GENESIS_SLOT
859-
if is_deposit_request and state.eth1_deposit_index < state.deposit_requests_start_index:
913+
# Do not process deposit requests if Eth1 bridge deposits are not yet applied.
914+
if (
915+
# Is deposit request
916+
deposit.slot > GENESIS_SLOT and
917+
# There are pending Eth1 bridge deposits
918+
state.eth1_deposit_index < state.deposit_requests_start_index
919+
):
860920
break
861921

862922
# Check if deposit has been finalized, otherwise, stop processing.
863923
if deposit.slot > finalized_slot:
864924
break
865925

866-
# Check if number of processed deposits fits in the limit, otherwise, stop processing.
926+
# Check if number of processed deposits has not reached the limit, otherwise, stop processing.
867927
if next_deposit_index > MAX_PENDING_DEPOSITS_PER_EPOCH_PROCESSING:
868928
break
869929

@@ -873,52 +933,20 @@ def process_pending_deposits(state: BeaconState) -> None:
873933
is_churn_limit_reached = True
874934
break
875935

876-
# Consume churn and process deposit
936+
# Consume churn and apply deposit
877937
processed_amount += churn_consumption
938+
is_deposit_applied = apply_pending_deposit(state, deposit)
878939

879-
validator_pubkeys = [v.pubkey for v in state.validators]
880-
881-
if deposit.pubkey not in validator_pubkeys:
882-
# Verify the deposit signature (proof of possession) which is not checked by the deposit contract
883-
if is_valid_deposit_signature(
884-
deposit.pubkey,
885-
deposit.withdrawal_credentials,
886-
deposit.amount,
887-
deposit.signature
888-
):
889-
add_validator_to_registry(state, deposit.pubkey, deposit.withdrawal_credentials, deposit.amount)
890-
else:
891-
validator_index = ValidatorIndex(validator_pubkeys.index(deposit.pubkey))
892-
validator = state.validators[validator_index]
893-
# Validator is exiting, postpone the deposit until after withdrawable epoch
894-
if validator.exit_epoch < FAR_FUTURE_EPOCH:
895-
if get_current_epoch(state) <= validator.withdrawable_epoch:
896-
deposits_to_postpone.append(deposit)
897-
# Deposited balance will never become active. Increase balance but do not consume churn
898-
else:
899-
increase_balance(state, validator_index, deposit.amount)
900-
# Validator is not exiting, attempt to process deposit
901-
else:
902-
# Increase balance
903-
increase_balance(state, validator_index, deposit.amount)
904-
# Check if valid deposit switch to compounding credentials.
905-
if (
906-
is_compounding_withdrawal_credential(deposit.withdrawal_credentials)
907-
and has_eth1_withdrawal_credential(validator)
908-
and is_valid_deposit_signature(
909-
deposit.pubkey,
910-
deposit.withdrawal_credentials,
911-
deposit.amount,
912-
deposit.signature
913-
)
914-
):
915-
switch_to_compounding_validator(state, validator_index)
940+
# Postpone deposit if it has not been applied.
941+
if not is_deposit_applied:
942+
deposits_to_postpone.append(deposit)
916943

917944
# Regardless of how the deposit was handled, we move on in the queue.
918945
next_deposit_index += 1
919946

920947
state.pending_deposits = state.pending_deposits[next_deposit_index:]
921948

949+
# Accumulate churn only if the churn limit has been hit.
922950
if is_churn_limit_reached:
923951
state.deposit_balance_to_consume = available_for_processing - processed_amount
924952
else:

0 commit comments

Comments
 (0)