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
848904def 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