Add pending_deposits queue and queue deposit requests
This commit is contained in:
parent
3644f360b8
commit
fd75470eab
|
@ -10,7 +10,7 @@ MAX_EFFECTIVE_BALANCE_ELECTRA: 2048000000000
|
|||
# State list lengths
|
||||
# ---------------------------------------------------------------
|
||||
# `uint64(2**27)` (= 134,217,728)
|
||||
PENDING_BALANCE_DEPOSITS_LIMIT: 134217728
|
||||
PENDING_DEPOSITS_LIMIT: 134217728
|
||||
# `uint64(2**27)` (= 134,217,728)
|
||||
PENDING_PARTIAL_WITHDRAWALS_LIMIT: 134217728
|
||||
# `uint64(2**18)` (= 262,144)
|
||||
|
|
|
@ -10,7 +10,7 @@ MAX_EFFECTIVE_BALANCE_ELECTRA: 2048000000000
|
|||
# State list lengths
|
||||
# ---------------------------------------------------------------
|
||||
# `uint64(2**27)` (= 134,217,728)
|
||||
PENDING_BALANCE_DEPOSITS_LIMIT: 134217728
|
||||
PENDING_DEPOSITS_LIMIT: 134217728
|
||||
# [customized] `uint64(2**6)` (= 64)
|
||||
PENDING_PARTIAL_WITHDRAWALS_LIMIT: 64
|
||||
# [customized] `uint64(2**6)` (= 64)
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
- [Containers](#containers)
|
||||
- [New containers](#new-containers)
|
||||
- [`DepositRequest`](#depositrequest)
|
||||
- [`PendingBalanceDeposit`](#pendingbalancedeposit)
|
||||
- [`PendingDeposit`](#pendingdeposit)
|
||||
- [`PendingPartialWithdrawal`](#pendingpartialwithdrawal)
|
||||
- [`ExecutionLayerWithdrawalRequest`](#executionlayerwithdrawalrequest)
|
||||
- [`ExecutionLayerConsolidationRequest`](#executionlayerconsolidationrequest)
|
||||
|
@ -70,7 +70,7 @@
|
|||
- [Epoch processing](#epoch-processing)
|
||||
- [Updated `process_epoch`](#updated-process_epoch)
|
||||
- [Updated `process_registry_updates`](#updated--process_registry_updates)
|
||||
- [New `process_pending_balance_deposits`](#new-process_pending_balance_deposits)
|
||||
- [New `process_pending_deposits`](#new-process_pending_deposits)
|
||||
- [New `process_pending_consolidations`](#new-process_pending_consolidations)
|
||||
- [Updated `process_effective_balance_updates`](#updated-process_effective_balance_updates)
|
||||
- [Block processing](#block-processing)
|
||||
|
@ -86,8 +86,6 @@
|
|||
- [Deposits](#deposits)
|
||||
- [Updated `apply_deposit`](#updated--apply_deposit)
|
||||
- [New `is_valid_deposit_signature`](#new-is_valid_deposit_signature)
|
||||
- [Modified `add_validator_to_registry`](#modified-add_validator_to_registry)
|
||||
- [Updated `get_validator_from_deposit`](#updated-get_validator_from_deposit)
|
||||
- [Voluntary exits](#voluntary-exits)
|
||||
- [Updated `process_voluntary_exit`](#updated-process_voluntary_exit)
|
||||
- [Execution layer withdrawal requests](#execution-layer-withdrawal-requests)
|
||||
|
@ -156,7 +154,7 @@ The following values are (non-configurable) constants used throughout the specif
|
|||
|
||||
| Name | Value | Unit |
|
||||
| - | - | :-: |
|
||||
| `PENDING_BALANCE_DEPOSITS_LIMIT` | `uint64(2**27)` (= 134,217,728) | pending balance deposits |
|
||||
| `PENDING_DEPOSITS_LIMIT` | `uint64(2**27)` (= 134,217,728) | pending deposits |
|
||||
| `PENDING_PARTIAL_WITHDRAWALS_LIMIT` | `uint64(2**27)` (= 134,217,728) | pending partial withdrawals |
|
||||
| `PENDING_CONSOLIDATIONS_LIMIT` | `uint64(2**18)` (= 262,144) | pending consolidations |
|
||||
|
||||
|
@ -207,14 +205,17 @@ class DepositRequest(Container):
|
|||
index: uint64
|
||||
```
|
||||
|
||||
#### `PendingBalanceDeposit`
|
||||
#### `PendingDeposit`
|
||||
|
||||
*Note*: The container is new in EIP7251.
|
||||
|
||||
```python
|
||||
class PendingBalanceDeposit(Container):
|
||||
index: ValidatorIndex
|
||||
class PendingDeposit(Container):
|
||||
pubkey: BLSPubkey
|
||||
withdrawal_credentials: Bytes32
|
||||
amount: Gwei
|
||||
signature: BLSSignature
|
||||
slot: Slot
|
||||
```
|
||||
|
||||
#### `PendingPartialWithdrawal`
|
||||
|
@ -420,7 +421,7 @@ class BeaconState(Container):
|
|||
earliest_exit_epoch: Epoch # [New in Electra:EIP7251]
|
||||
consolidation_balance_to_consume: Gwei # [New in Electra:EIP7251]
|
||||
earliest_consolidation_epoch: Epoch # [New in Electra:EIP7251]
|
||||
pending_balance_deposits: List[PendingBalanceDeposit, PENDING_BALANCE_DEPOSITS_LIMIT] # [New in Electra:EIP7251]
|
||||
pending_deposits: List[PendingDeposit, PENDING_DEPOSITS_LIMIT] # [New in Electra:EIP7251]
|
||||
# [New in Electra:EIP7251]
|
||||
pending_partial_withdrawals: List[PendingPartialWithdrawal, PENDING_PARTIAL_WITHDRAWALS_LIMIT]
|
||||
pending_consolidations: List[PendingConsolidation, PENDING_CONSOLIDATIONS_LIMIT] # [New in Electra:EIP7251]
|
||||
|
@ -655,9 +656,14 @@ def queue_excess_active_balance(state: BeaconState, index: ValidatorIndex) -> No
|
|||
if balance > MIN_ACTIVATION_BALANCE:
|
||||
excess_balance = balance - MIN_ACTIVATION_BALANCE
|
||||
state.balances[index] = MIN_ACTIVATION_BALANCE
|
||||
state.pending_balance_deposits.append(
|
||||
PendingBalanceDeposit(index=index, amount=excess_balance)
|
||||
)
|
||||
validator = state.validators[index]
|
||||
state.pending_deposits.append(PendingDeposit(
|
||||
pubkey=validator.pubkey,
|
||||
withdrawal_credentials=validator.withdrawal_credentials,
|
||||
amount=excess_balance,
|
||||
signature=bls.G2_POINT_AT_INFINITY,
|
||||
slot=GENESIS_SLOT,
|
||||
))
|
||||
```
|
||||
|
||||
#### New `queue_entire_balance_and_reset_validator`
|
||||
|
@ -668,9 +674,13 @@ def queue_entire_balance_and_reset_validator(state: BeaconState, index: Validato
|
|||
validator = state.validators[index]
|
||||
validator.effective_balance = 0
|
||||
validator.activation_eligibility_epoch = FAR_FUTURE_EPOCH
|
||||
state.pending_balance_deposits.append(
|
||||
PendingBalanceDeposit(index=index, amount=balance)
|
||||
)
|
||||
state.pending_deposits.append(PendingDeposit(
|
||||
pubkey=validator.pubkey,
|
||||
withdrawal_credentials=validator.withdrawal_credentials,
|
||||
amount=balance,
|
||||
signature=bls.G2_POINT_AT_INFINITY,
|
||||
slot=GENESIS_SLOT,
|
||||
))
|
||||
```
|
||||
|
||||
#### New `compute_exit_epoch_and_update_churn`
|
||||
|
@ -769,7 +779,7 @@ def process_epoch(state: BeaconState) -> None:
|
|||
process_registry_updates(state) # [Modified in Electra:EIP7251]
|
||||
process_slashings(state)
|
||||
process_eth1_data_reset(state)
|
||||
process_pending_balance_deposits(state) # [New in Electra:EIP7251]
|
||||
process_pending_deposits(state) # [New in Electra:EIP7251]
|
||||
process_pending_consolidations(state) # [New in Electra:EIP7251]
|
||||
process_effective_balance_updates(state) # [Modified in Electra:EIP7251]
|
||||
process_slashings_reset(state)
|
||||
|
@ -804,44 +814,75 @@ def process_registry_updates(state: BeaconState) -> None:
|
|||
validator.activation_epoch = activation_epoch
|
||||
```
|
||||
|
||||
#### New `process_pending_balance_deposits`
|
||||
#### New `process_pending_deposits`
|
||||
|
||||
```python
|
||||
def process_pending_balance_deposits(state: BeaconState) -> None:
|
||||
def process_pending_deposits(state: BeaconState) -> None:
|
||||
available_for_processing = state.deposit_balance_to_consume + get_activation_exit_churn_limit(state)
|
||||
processed_amount = 0
|
||||
next_deposit_index = 0
|
||||
deposits_to_postpone = []
|
||||
|
||||
for deposit in state.pending_balance_deposits:
|
||||
validator = state.validators[deposit.index]
|
||||
# Validator is exiting, postpone the deposit until after withdrawable epoch
|
||||
if validator.exit_epoch < FAR_FUTURE_EPOCH:
|
||||
if get_current_epoch(state) <= validator.withdrawable_epoch:
|
||||
deposits_to_postpone.append(deposit)
|
||||
# Deposited balance will never become active. Increase balance but do not consume churn
|
||||
else:
|
||||
increase_balance(state, deposit.index, deposit.amount)
|
||||
# Validator is not exiting, attempt to process deposit
|
||||
else:
|
||||
for deposit in state.pending_deposits:
|
||||
validator_pubkeys = [v.pubkey for v in state.validators]
|
||||
|
||||
if deposit.pubkey not in validator_pubkeys:
|
||||
# Deposit does not fit in the churn, no more deposit processing in this epoch.
|
||||
if processed_amount + deposit.amount > available_for_processing:
|
||||
break
|
||||
# Deposit fits in the churn, process it. Increase balance and consume churn.
|
||||
else:
|
||||
increase_balance(state, deposit.index, deposit.amount)
|
||||
# Verify the deposit signature (proof of possession) which is not checked by the deposit contract
|
||||
if is_valid_deposit_signature(
|
||||
deposit.pubkey,
|
||||
deposit.withdrawal_credentials,
|
||||
deposit.amount,
|
||||
deposit.signature
|
||||
):
|
||||
add_validator_to_registry(state, deposit.pubkey, deposit.withdrawal_credentials, deposit.amount)
|
||||
# Consume churn only if signature is valid.
|
||||
processed_amount += deposit.amount
|
||||
else:
|
||||
validator_index = ValidatorIndex(validator_pubkeys.index(deposit.pubkey))
|
||||
validator = state.validators[validator_index]
|
||||
# Validator is exiting, postpone the deposit until after withdrawable epoch
|
||||
if validator.exit_epoch < FAR_FUTURE_EPOCH:
|
||||
if get_current_epoch(state) <= validator.withdrawable_epoch:
|
||||
deposits_to_postpone.append(deposit)
|
||||
# Deposited balance will never become active. Increase balance but do not consume churn
|
||||
else:
|
||||
increase_balance(state, validator_index, deposit.amount)
|
||||
# Validator is not exiting, attempt to process deposit
|
||||
else:
|
||||
# Deposit does not fit in the churn, no more deposit processing in this epoch.
|
||||
if processed_amount + deposit.amount > available_for_processing:
|
||||
break
|
||||
# Deposit fits in the churn, process it. Increase balance and consume churn.
|
||||
else:
|
||||
increase_balance(state, validator_index, deposit.amount)
|
||||
processed_amount += deposit.amount
|
||||
# Check if valid deposit switch to compounding credentials
|
||||
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)
|
||||
|
||||
# Regardless of how the deposit was handled, we move on in the queue.
|
||||
next_deposit_index += 1
|
||||
|
||||
state.pending_balance_deposits = state.pending_balance_deposits[next_deposit_index:]
|
||||
state.pending_deposits = state.pending_deposits[next_deposit_index:]
|
||||
|
||||
if len(state.pending_balance_deposits) == 0:
|
||||
if len(state.pending_deposits) == 0:
|
||||
state.deposit_balance_to_consume = Gwei(0)
|
||||
else:
|
||||
state.deposit_balance_to_consume = available_for_processing - processed_amount
|
||||
|
||||
state.pending_balance_deposits += deposits_to_postpone
|
||||
state.pending_deposits += deposits_to_postpone
|
||||
```
|
||||
|
||||
#### New `process_pending_consolidations`
|
||||
|
@ -1143,21 +1184,25 @@ def apply_deposit(state: BeaconState,
|
|||
if pubkey not in validator_pubkeys:
|
||||
# Verify the deposit signature (proof of possession) which is not checked by the deposit contract
|
||||
if is_valid_deposit_signature(pubkey, withdrawal_credentials, amount, signature):
|
||||
add_validator_to_registry(state, pubkey, withdrawal_credentials, amount)
|
||||
add_validator_to_registry(state, pubkey, withdrawal_credentials, Gwei(0)) # [Modified in Electra:EIP7251]
|
||||
# [New in Electra:EIP7251]
|
||||
state.pending_deposits.append(PendingDeposit(
|
||||
pubkey=pubkey,
|
||||
withdrawal_credentials=withdrawal_credentials,
|
||||
amount=amount,
|
||||
signature=signature,
|
||||
slot=GENESIS_SLOT,
|
||||
))
|
||||
else:
|
||||
# Increase balance by deposit amount
|
||||
index = ValidatorIndex(validator_pubkeys.index(pubkey))
|
||||
state.pending_balance_deposits.append(
|
||||
PendingBalanceDeposit(index=index, amount=amount)
|
||||
) # [Modified in Electra:EIP-7251]
|
||||
# Check if valid deposit switch to compounding credentials
|
||||
if (
|
||||
is_compounding_withdrawal_credential(withdrawal_credentials)
|
||||
and has_eth1_withdrawal_credential(state.validators[index])
|
||||
and is_valid_deposit_signature(pubkey, withdrawal_credentials, amount, signature)
|
||||
):
|
||||
switch_to_compounding_validator(state, index)
|
||||
|
||||
# [Modified in Electra:EIP-7251]
|
||||
state.pending_deposits.append(PendingDeposit(
|
||||
pubkey=pubkey,
|
||||
withdrawal_credentials=withdrawal_credentials,
|
||||
amount=amount,
|
||||
signature=signature,
|
||||
slot=GENESIS_SLOT
|
||||
))
|
||||
```
|
||||
|
||||
###### New `is_valid_deposit_signature`
|
||||
|
@ -1177,38 +1222,6 @@ def is_valid_deposit_signature(pubkey: BLSPubkey,
|
|||
return bls.Verify(pubkey, signing_root, signature)
|
||||
```
|
||||
|
||||
###### Modified `add_validator_to_registry`
|
||||
|
||||
```python
|
||||
def add_validator_to_registry(state: BeaconState,
|
||||
pubkey: BLSPubkey,
|
||||
withdrawal_credentials: Bytes32,
|
||||
amount: uint64) -> None:
|
||||
index = get_index_for_new_validator(state)
|
||||
validator = get_validator_from_deposit(pubkey, withdrawal_credentials)
|
||||
set_or_append_list(state.validators, index, validator)
|
||||
set_or_append_list(state.balances, index, 0) # [Modified in Electra:EIP7251]
|
||||
set_or_append_list(state.previous_epoch_participation, index, ParticipationFlags(0b0000_0000))
|
||||
set_or_append_list(state.current_epoch_participation, index, ParticipationFlags(0b0000_0000))
|
||||
set_or_append_list(state.inactivity_scores, index, uint64(0))
|
||||
state.pending_balance_deposits.append(PendingBalanceDeposit(index=index, amount=amount)) # [New in Electra:EIP7251]
|
||||
```
|
||||
|
||||
###### Updated `get_validator_from_deposit`
|
||||
|
||||
```python
|
||||
def get_validator_from_deposit(pubkey: BLSPubkey, withdrawal_credentials: Bytes32) -> Validator:
|
||||
return Validator(
|
||||
pubkey=pubkey,
|
||||
withdrawal_credentials=withdrawal_credentials,
|
||||
activation_eligibility_epoch=FAR_FUTURE_EPOCH,
|
||||
activation_epoch=FAR_FUTURE_EPOCH,
|
||||
exit_epoch=FAR_FUTURE_EPOCH,
|
||||
withdrawable_epoch=FAR_FUTURE_EPOCH,
|
||||
effective_balance=0, # [Modified in Electra:EIP7251]
|
||||
)
|
||||
```
|
||||
|
||||
##### Voluntary exits
|
||||
###### Updated `process_voluntary_exit`
|
||||
|
||||
|
@ -1315,13 +1328,13 @@ def process_deposit_request(state: BeaconState, deposit_request: DepositRequest)
|
|||
if state.deposit_requests_start_index == UNSET_DEPOSIT_REQUESTS_START_INDEX:
|
||||
state.deposit_requests_start_index = deposit_request.index
|
||||
|
||||
apply_deposit(
|
||||
state=state,
|
||||
state.pending_deposits.append(PendingDeposit(
|
||||
pubkey=deposit_request.pubkey,
|
||||
withdrawal_credentials=deposit_request.withdrawal_credentials,
|
||||
amount=deposit_request.amount,
|
||||
signature=deposit_request.signature,
|
||||
)
|
||||
slot=state.slot,
|
||||
))
|
||||
```
|
||||
|
||||
##### Execution layer consolidation requests
|
||||
|
@ -1431,9 +1444,11 @@ def initialize_beacon_state_from_eth1(eth1_block_hash: Hash32,
|
|||
process_deposit(state, deposit)
|
||||
|
||||
# Process deposit balance updates
|
||||
for deposit in state.pending_balance_deposits:
|
||||
increase_balance(state, deposit.index, deposit.amount)
|
||||
state.pending_balance_deposits = []
|
||||
validator_pubkeys = [v.pubkey for v in state.validators]
|
||||
for deposit in state.pending_deposits:
|
||||
validator_index = ValidatorIndex(validator_pubkeys.index(deposit.pubkey))
|
||||
increase_balance(state, validator_index, deposit.amount)
|
||||
state.pending_deposits = []
|
||||
|
||||
# Process activations
|
||||
for index, validator in enumerate(state.validators):
|
||||
|
|
|
@ -154,7 +154,7 @@ def upgrade_to_electra(pre: deneb.BeaconState) -> BeaconState:
|
|||
earliest_exit_epoch=earliest_exit_epoch,
|
||||
consolidation_balance_to_consume=0,
|
||||
earliest_consolidation_epoch=compute_activation_exit_epoch(get_current_epoch(pre)),
|
||||
pending_balance_deposits=[],
|
||||
pending_deposits=[],
|
||||
pending_partial_withdrawals=[],
|
||||
pending_consolidations=[],
|
||||
)
|
||||
|
|
|
@ -32,10 +32,13 @@ def test_success_top_up_to_withdrawn_validator(spec, state):
|
|||
yield from run_deposit_processing(spec, state, deposit, validator_index)
|
||||
|
||||
if is_post_electra(spec):
|
||||
pending_balance_deposits_len = len(state.pending_balance_deposits)
|
||||
pending_balance_deposit = state.pending_balance_deposits[pending_balance_deposits_len - 1]
|
||||
assert pending_balance_deposit.amount == amount
|
||||
assert pending_balance_deposit.index == validator_index
|
||||
pending_deposits_len = len(state.pending_deposits)
|
||||
pending_deposit = state.pending_deposits[pending_deposits_len - 1]
|
||||
assert pending_deposit.pubkey == deposit.data.pubkey
|
||||
assert pending_deposit.withdrawal_credentials == deposit.data.withdrawal_credentials
|
||||
assert pending_deposit.amount == deposit.data.amount
|
||||
assert pending_deposit.signature == deposit.data.signature
|
||||
assert pending_deposit.slot == spec.GENESIS_SLOT
|
||||
else:
|
||||
assert state.balances[validator_index] == amount
|
||||
assert state.validators[validator_index].effective_balance == 0
|
||||
|
@ -47,7 +50,7 @@ def test_success_top_up_to_withdrawn_validator(spec, state):
|
|||
if is_post_electra(spec):
|
||||
has_execution_withdrawal = spec.has_execution_withdrawal_credential(validator)
|
||||
is_withdrawable = validator.withdrawable_epoch <= current_epoch
|
||||
has_non_zero_balance = pending_balance_deposit.amount > 0
|
||||
has_non_zero_balance = pending_deposit.amount > 0
|
||||
# NOTE: directly compute `is_fully_withdrawable_validator` conditions here
|
||||
# to work around how the epoch processing changed balance updates
|
||||
assert has_execution_withdrawal and is_withdrawable and has_non_zero_balance
|
||||
|
|
|
@ -365,8 +365,11 @@ def test_top_up_and_partial_withdrawable_validator(spec, state):
|
|||
yield 'post', state
|
||||
|
||||
if is_post_electra(spec):
|
||||
assert state.pending_balance_deposits[0].amount == amount
|
||||
assert state.pending_balance_deposits[0].index == validator_index
|
||||
assert state.pending_deposits[0].pubkey == deposit.data.pubkey
|
||||
assert state.pending_deposits[0].withdrawal_credentials == deposit.data.withdrawal_credentials
|
||||
assert state.pending_deposits[0].amount == deposit.data.amount
|
||||
assert state.pending_deposits[0].signature == deposit.data.signature
|
||||
assert state.pending_deposits[0].slot == spec.GENESIS_SLOT
|
||||
else:
|
||||
# Since withdrawals happen before deposits, it becomes partially withdrawable after state transition.
|
||||
validator = state.validators[validator_index]
|
||||
|
@ -405,7 +408,7 @@ def test_top_up_to_fully_withdrawn_validator(spec, state):
|
|||
|
||||
balance = state.balances[validator_index]
|
||||
if is_post_electra(spec):
|
||||
balance += state.pending_balance_deposits[0].amount
|
||||
balance += state.pending_deposits[0].amount
|
||||
|
||||
assert spec.is_fully_withdrawable_validator(
|
||||
state.validators[validator_index],
|
||||
|
|
|
@ -122,8 +122,8 @@ def test_top_up__max_effective_balance(spec, state):
|
|||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
deposits_len = len(state.pending_balance_deposits)
|
||||
assert state.pending_balance_deposits[deposits_len - 1].amount == amount
|
||||
deposits_len = len(state.pending_deposits)
|
||||
assert state.pending_deposits[deposits_len - 1].amount == amount
|
||||
assert state.validators[validator_index].effective_balance == spec.MAX_EFFECTIVE_BALANCE
|
||||
|
||||
|
||||
|
@ -141,8 +141,8 @@ def test_top_up__less_effective_balance(spec, state):
|
|||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
deposits_len = len(state.pending_balance_deposits)
|
||||
assert state.pending_balance_deposits[deposits_len - 1].amount == amount
|
||||
deposits_len = len(state.pending_deposits)
|
||||
assert state.pending_deposits[deposits_len - 1].amount == amount
|
||||
# unchanged effective balance
|
||||
assert state.validators[validator_index].effective_balance == initial_effective_balance
|
||||
|
||||
|
@ -161,8 +161,8 @@ def test_top_up__zero_balance(spec, state):
|
|||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
deposits_len = len(state.pending_balance_deposits)
|
||||
assert state.pending_balance_deposits[deposits_len - 1].amount == amount
|
||||
deposits_len = len(state.pending_deposits)
|
||||
assert state.pending_deposits[deposits_len - 1].amount == amount
|
||||
# unchanged effective balance
|
||||
assert state.validators[validator_index].effective_balance == initial_effective_balance
|
||||
|
||||
|
@ -276,18 +276,18 @@ def test_success_top_up_to_withdrawn_validator(spec, state):
|
|||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
deposits_len = len(state.pending_balance_deposits)
|
||||
assert state.pending_balance_deposits[deposits_len - 1].amount == amount
|
||||
deposits_len = len(state.pending_deposits)
|
||||
assert state.pending_deposits[deposits_len - 1].amount == amount
|
||||
assert state.validators[validator_index].effective_balance == 0
|
||||
|
||||
validator = state.validators[validator_index]
|
||||
|
||||
pending_balance_deposits_len = len(state.pending_balance_deposits)
|
||||
pending_balance_deposit = state.pending_balance_deposits[pending_balance_deposits_len - 1]
|
||||
pending_deposits_len = len(state.pending_deposits)
|
||||
pending_deposit = state.pending_deposits[pending_deposits_len - 1]
|
||||
current_epoch = spec.get_current_epoch(state)
|
||||
has_execution_withdrawal = spec.has_execution_withdrawal_credential(validator)
|
||||
is_withdrawable = validator.withdrawable_epoch <= current_epoch
|
||||
has_non_zero_balance = pending_balance_deposit.amount > 0
|
||||
has_non_zero_balance = pending_deposit.amount > 0
|
||||
# NOTE: directly compute `is_fully_withdrawable_validator` conditions here
|
||||
# to work around how the epoch processing changed balance updates
|
||||
assert has_execution_withdrawal and is_withdrawable and has_non_zero_balance
|
||||
|
|
|
@ -3,10 +3,13 @@ from eth2spec.test.context import (
|
|||
spec_state_test,
|
||||
with_electra_and_later,
|
||||
)
|
||||
from eth2spec.test.helpers.deposits import (
|
||||
build_pending_deposit_top_up,
|
||||
)
|
||||
|
||||
|
||||
def run_process_pending_balance_deposits(spec, state):
|
||||
yield from run_epoch_processing_with(spec, state, 'process_pending_balance_deposits')
|
||||
def run_process_pending_deposits(spec, state):
|
||||
yield from run_epoch_processing_with(spec, state, 'process_pending_deposits')
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
|
@ -14,17 +17,17 @@ def run_process_pending_balance_deposits(spec, state):
|
|||
def test_pending_deposit_min_activation_balance(spec, state):
|
||||
index = 0
|
||||
amount = spec.MIN_ACTIVATION_BALANCE
|
||||
state.pending_balance_deposits.append(
|
||||
spec.PendingBalanceDeposit(index=index, amount=amount)
|
||||
state.pending_deposits.append(
|
||||
build_pending_deposit_top_up(spec, state, index, amount)
|
||||
)
|
||||
pre_balance = state.balances[index]
|
||||
|
||||
yield from run_process_pending_balance_deposits(spec, state)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
assert state.balances[index] == pre_balance + amount
|
||||
# No leftover deposit balance to consume when there are no deposits left to process
|
||||
assert state.deposit_balance_to_consume == 0
|
||||
assert state.pending_balance_deposits == []
|
||||
assert state.pending_deposits == []
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
|
@ -32,16 +35,16 @@ def test_pending_deposit_min_activation_balance(spec, state):
|
|||
def test_pending_deposit_balance_equal_churn(spec, state):
|
||||
index = 0
|
||||
amount = spec.get_activation_exit_churn_limit(state)
|
||||
state.pending_balance_deposits.append(
|
||||
spec.PendingBalanceDeposit(index=index, amount=amount)
|
||||
state.pending_deposits.append(
|
||||
build_pending_deposit_top_up(spec, state, index, amount)
|
||||
)
|
||||
pre_balance = state.balances[index]
|
||||
|
||||
yield from run_process_pending_balance_deposits(spec, state)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
assert state.balances[index] == pre_balance + amount
|
||||
assert state.deposit_balance_to_consume == 0
|
||||
assert state.pending_balance_deposits == []
|
||||
assert state.pending_deposits == []
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
|
@ -49,12 +52,12 @@ def test_pending_deposit_balance_equal_churn(spec, state):
|
|||
def test_pending_deposit_balance_above_churn(spec, state):
|
||||
index = 0
|
||||
amount = spec.get_activation_exit_churn_limit(state) + 1
|
||||
state.pending_balance_deposits.append(
|
||||
spec.PendingBalanceDeposit(index=index, amount=amount)
|
||||
state.pending_deposits.append(
|
||||
build_pending_deposit_top_up(spec, state, index, amount)
|
||||
)
|
||||
pre_balance = state.balances[index]
|
||||
|
||||
yield from run_process_pending_balance_deposits(spec, state)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
# deposit was above churn, balance hasn't changed
|
||||
assert state.balances[index] == pre_balance
|
||||
|
@ -63,8 +66,8 @@ def test_pending_deposit_balance_above_churn(spec, state):
|
|||
state
|
||||
)
|
||||
# deposit is still in the queue
|
||||
assert state.pending_balance_deposits == [
|
||||
spec.PendingBalanceDeposit(index=index, amount=amount)
|
||||
assert state.pending_deposits == [
|
||||
build_pending_deposit_top_up(spec, state, index, amount)
|
||||
]
|
||||
|
||||
|
||||
|
@ -74,40 +77,40 @@ def test_pending_deposit_preexisting_churn(spec, state):
|
|||
index = 0
|
||||
amount = 10**9 + 1
|
||||
state.deposit_balance_to_consume = 2 * amount
|
||||
state.pending_balance_deposits.append(
|
||||
spec.PendingBalanceDeposit(index=index, amount=amount)
|
||||
state.pending_deposits.append(
|
||||
build_pending_deposit_top_up(spec, state, index, amount)
|
||||
)
|
||||
pre_balance = state.balances[index]
|
||||
|
||||
yield from run_process_pending_balance_deposits(spec, state)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
# balance was deposited correctly
|
||||
assert state.balances[index] == pre_balance + amount
|
||||
# No leftover deposit balance to consume when there are no deposits left to process
|
||||
assert state.deposit_balance_to_consume == 0
|
||||
# queue emptied
|
||||
assert state.pending_balance_deposits == []
|
||||
assert state.pending_deposits == []
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_multiple_pending_deposits_below_churn(spec, state):
|
||||
amount = 10**9
|
||||
state.pending_balance_deposits.append(
|
||||
spec.PendingBalanceDeposit(index=0, amount=amount)
|
||||
state.pending_deposits.append(
|
||||
build_pending_deposit_top_up(spec, state, validator_index=0, amount=amount)
|
||||
)
|
||||
state.pending_balance_deposits.append(
|
||||
spec.PendingBalanceDeposit(index=1, amount=amount)
|
||||
state.pending_deposits.append(
|
||||
build_pending_deposit_top_up(spec, state, validator_index=1, amount=amount)
|
||||
)
|
||||
pre_balances = state.balances.copy()
|
||||
|
||||
yield from run_process_pending_balance_deposits(spec, state)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
for i in [0, 1]:
|
||||
assert state.balances[i] == pre_balances[i] + amount
|
||||
# No leftover deposit balance to consume when there are no deposits left to process
|
||||
assert state.deposit_balance_to_consume == 0
|
||||
assert state.pending_balance_deposits == []
|
||||
assert state.pending_deposits == []
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
|
@ -116,12 +119,12 @@ def test_multiple_pending_deposits_above_churn(spec, state):
|
|||
# set third deposit to be over the churn
|
||||
amount = (spec.get_activation_exit_churn_limit(state) // 3) + 1
|
||||
for i in [0, 1, 2]:
|
||||
state.pending_balance_deposits.append(
|
||||
spec.PendingBalanceDeposit(index=i, amount=amount)
|
||||
state.pending_deposits.append(
|
||||
build_pending_deposit_top_up(spec, state, validator_index=i, amount=amount)
|
||||
)
|
||||
pre_balances = state.balances.copy()
|
||||
|
||||
yield from run_process_pending_balance_deposits(spec, state)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
# First two deposits are processed, third is not because above churn
|
||||
for i in [0, 1]:
|
||||
|
@ -133,8 +136,8 @@ def test_multiple_pending_deposits_above_churn(spec, state):
|
|||
== spec.get_activation_exit_churn_limit(state) - 2 * amount
|
||||
)
|
||||
# third deposit is still in the queue
|
||||
assert state.pending_balance_deposits == [
|
||||
spec.PendingBalanceDeposit(index=2, amount=amount)
|
||||
assert state.pending_deposits == [
|
||||
build_pending_deposit_top_up(spec, state, validator_index=2, amount=amount)
|
||||
]
|
||||
|
||||
|
||||
|
@ -143,20 +146,20 @@ def test_multiple_pending_deposits_above_churn(spec, state):
|
|||
def test_skipped_deposit_exiting_validator(spec, state):
|
||||
index = 0
|
||||
amount = spec.MIN_ACTIVATION_BALANCE
|
||||
state.pending_balance_deposits.append(spec.PendingBalanceDeposit(index=index, amount=amount))
|
||||
pre_pending_balance_deposits = state.pending_balance_deposits.copy()
|
||||
state.pending_deposits.append(build_pending_deposit_top_up(spec, state, validator_index=index, amount=amount))
|
||||
pre_pending_deposits = state.pending_deposits.copy()
|
||||
pre_balance = state.balances[index]
|
||||
# Initiate the validator's exit
|
||||
spec.initiate_validator_exit(state, index)
|
||||
|
||||
yield from run_process_pending_balance_deposits(spec, state)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
# Deposit is skipped because validator is exiting
|
||||
assert state.balances[index] == pre_balance
|
||||
# All deposits either processed or postponed, no leftover deposit balance to consume
|
||||
assert state.deposit_balance_to_consume == 0
|
||||
# The deposit is still in the queue
|
||||
assert state.pending_balance_deposits == pre_pending_balance_deposits
|
||||
assert state.pending_deposits == pre_pending_deposits
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
|
@ -165,21 +168,21 @@ def test_multiple_skipped_deposits_exiting_validators(spec, state):
|
|||
amount = spec.EFFECTIVE_BALANCE_INCREMENT
|
||||
for i in [0, 1, 2]:
|
||||
# Append pending deposit for validator i
|
||||
state.pending_balance_deposits.append(spec.PendingBalanceDeposit(index=i, amount=amount))
|
||||
state.pending_deposits.append(build_pending_deposit_top_up(spec, state, validator_index=i, amount=amount))
|
||||
|
||||
# Initiate the exit of validator i
|
||||
spec.initiate_validator_exit(state, i)
|
||||
pre_pending_balance_deposits = state.pending_balance_deposits.copy()
|
||||
pre_pending_deposits = state.pending_deposits.copy()
|
||||
pre_balances = state.balances.copy()
|
||||
|
||||
yield from run_process_pending_balance_deposits(spec, state)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
# All deposits are postponed, no balance changes
|
||||
assert state.balances == pre_balances
|
||||
# All deposits are postponed, no leftover deposit balance to consume
|
||||
assert state.deposit_balance_to_consume == 0
|
||||
# All deposits still in the queue, in the same order
|
||||
assert state.pending_balance_deposits == pre_pending_balance_deposits
|
||||
assert state.pending_deposits == pre_pending_deposits
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
|
@ -187,12 +190,12 @@ def test_multiple_skipped_deposits_exiting_validators(spec, state):
|
|||
def test_multiple_pending_one_skipped(spec, state):
|
||||
amount = spec.EFFECTIVE_BALANCE_INCREMENT
|
||||
for i in [0, 1, 2]:
|
||||
state.pending_balance_deposits.append(spec.PendingBalanceDeposit(index=i, amount=amount))
|
||||
state.pending_deposits.append(build_pending_deposit_top_up(spec, state, validator_index=i, amount=amount))
|
||||
pre_balances = state.balances.copy()
|
||||
# Initiate the second validator's exit
|
||||
spec.initiate_validator_exit(state, 1)
|
||||
|
||||
yield from run_process_pending_balance_deposits(spec, state)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
# First and last deposit are processed, second is not because of exiting
|
||||
for i in [0, 2]:
|
||||
|
@ -201,7 +204,7 @@ def test_multiple_pending_one_skipped(spec, state):
|
|||
# All deposits either processed or postponed, no leftover deposit balance to consume
|
||||
assert state.deposit_balance_to_consume == 0
|
||||
# second deposit is still in the queue
|
||||
assert state.pending_balance_deposits == [spec.PendingBalanceDeposit(index=1, amount=amount)]
|
||||
assert state.pending_deposits == [build_pending_deposit_top_up(spec, state, validator_index=1, amount=amount)]
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
|
@ -211,13 +214,13 @@ def test_mixture_of_skipped_and_above_churn(spec, state):
|
|||
amount2 = spec.MAX_EFFECTIVE_BALANCE_ELECTRA
|
||||
# First two validators have small deposit, third validators a large one
|
||||
for i in [0, 1]:
|
||||
state.pending_balance_deposits.append(spec.PendingBalanceDeposit(index=i, amount=amount01))
|
||||
state.pending_balance_deposits.append(spec.PendingBalanceDeposit(index=2, amount=amount2))
|
||||
state.pending_deposits.append(build_pending_deposit_top_up(spec, state, validator_index=i, amount=amount01))
|
||||
state.pending_deposits.append(build_pending_deposit_top_up(spec, state, validator_index=2, amount=amount2))
|
||||
pre_balances = state.balances.copy()
|
||||
# Initiate the second validator's exit
|
||||
spec.initiate_validator_exit(state, 1)
|
||||
|
||||
yield from run_process_pending_balance_deposits(spec, state)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
# First deposit is processed
|
||||
assert state.balances[0] == pre_balances[0] + amount01
|
||||
|
@ -228,8 +231,8 @@ def test_mixture_of_skipped_and_above_churn(spec, state):
|
|||
# Deposit balance to consume is not reset because third deposit is not processed
|
||||
assert state.deposit_balance_to_consume == spec.get_activation_exit_churn_limit(state) - amount01
|
||||
# second and third deposit still in the queue, but second is appended at the end
|
||||
assert state.pending_balance_deposits == [spec.PendingBalanceDeposit(index=2, amount=amount2),
|
||||
spec.PendingBalanceDeposit(index=1, amount=amount01)]
|
||||
assert state.pending_deposits == [build_pending_deposit_top_up(spec, state, validator_index=2, amount=amount2),
|
||||
build_pending_deposit_top_up(spec, state, validator_index=1, amount=amount01)]
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
|
@ -237,20 +240,20 @@ def test_mixture_of_skipped_and_above_churn(spec, state):
|
|||
def test_processing_deposit_of_withdrawable_validator(spec, state):
|
||||
index = 0
|
||||
amount = spec.MIN_ACTIVATION_BALANCE
|
||||
state.pending_balance_deposits.append(spec.PendingBalanceDeposit(index=index, amount=amount))
|
||||
state.pending_deposits.append(build_pending_deposit_top_up(spec, state, validator_index=index, amount=amount))
|
||||
pre_balance = state.balances[index]
|
||||
# Initiate the validator's exit
|
||||
spec.initiate_validator_exit(state, index)
|
||||
# Set epoch to withdrawable epoch + 1 to allow processing of the deposit
|
||||
state.slot = spec.SLOTS_PER_EPOCH * (state.validators[index].withdrawable_epoch + 1)
|
||||
|
||||
yield from run_process_pending_balance_deposits(spec, state)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
# Deposit is correctly processed
|
||||
assert state.balances[index] == pre_balance + amount
|
||||
# No leftover deposit balance to consume when there are no deposits left to process
|
||||
assert state.deposit_balance_to_consume == 0
|
||||
assert state.pending_balance_deposits == []
|
||||
assert state.pending_deposits == []
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
|
@ -258,7 +261,7 @@ def test_processing_deposit_of_withdrawable_validator(spec, state):
|
|||
def test_processing_deposit_of_withdrawable_validator_does_not_get_churned(spec, state):
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE_ELECTRA
|
||||
for i in [0, 1]:
|
||||
state.pending_balance_deposits.append(spec.PendingBalanceDeposit(index=i, amount=amount))
|
||||
state.pending_deposits.append(build_pending_deposit_top_up(spec, state, validator_index=i, amount=amount))
|
||||
pre_balances = state.balances.copy()
|
||||
# Initiate the first validator's exit
|
||||
spec.initiate_validator_exit(state, 0)
|
||||
|
@ -266,7 +269,7 @@ def test_processing_deposit_of_withdrawable_validator_does_not_get_churned(spec,
|
|||
state.slot = spec.SLOTS_PER_EPOCH * (state.validators[0].withdrawable_epoch + 1)
|
||||
# Don't use run_epoch_processing_with to avoid penalties being applied
|
||||
yield 'pre', state
|
||||
spec.process_pending_balance_deposits(state)
|
||||
spec.process_pending_deposits(state)
|
||||
yield 'post', state
|
||||
# First deposit is processed though above churn limit, because validator is withdrawable
|
||||
assert state.balances[0] == pre_balances[0] + amount
|
||||
|
@ -275,4 +278,4 @@ def test_processing_deposit_of_withdrawable_validator_does_not_get_churned(spec,
|
|||
# Second deposit is not processed, so there's leftover deposit balance to consume.
|
||||
# First deposit does not consume any.
|
||||
assert state.deposit_balance_to_consume == spec.get_activation_exit_churn_limit(state)
|
||||
assert state.pending_balance_deposits == [spec.PendingBalanceDeposit(index=1, amount=amount)]
|
||||
assert state.pending_deposits == [build_pending_deposit_top_up(spec, state, validator_index=1, amount=amount)]
|
|
@ -16,7 +16,7 @@ from eth2spec.test.helpers.execution_payload import (
|
|||
)
|
||||
from eth2spec.test.helpers.keys import privkeys, pubkeys
|
||||
from eth2spec.test.helpers.state import (
|
||||
state_transition_and_sign_block
|
||||
state_transition_and_sign_block,
|
||||
)
|
||||
|
||||
|
||||
|
@ -30,6 +30,10 @@ def run_deposit_transition_block(spec, state, block, top_up_keys=[], valid=True)
|
|||
"""
|
||||
yield 'pre', state
|
||||
|
||||
pre_pending_deposits_len = len(state.pending_deposits)
|
||||
pre_validators_len = len(state.validators)
|
||||
|
||||
# Include deposits into a block
|
||||
signed_block = state_transition_and_sign_block(spec, state, block, not valid)
|
||||
|
||||
yield 'blocks', [signed_block]
|
||||
|
@ -37,12 +41,39 @@ def run_deposit_transition_block(spec, state, block, top_up_keys=[], valid=True)
|
|||
|
||||
# Check that deposits are applied
|
||||
if valid:
|
||||
expected_pubkeys = [d.data.pubkey for d in block.body.deposits]
|
||||
deposit_requests = block.body.execution_payload.deposit_requests
|
||||
expected_pubkeys = expected_pubkeys + [d.pubkey for d in deposit_requests if (d.pubkey not in top_up_keys)]
|
||||
actual_pubkeys = [v.pubkey for v in state.validators[len(state.validators) - len(expected_pubkeys):]]
|
||||
# Check that deposits are applied
|
||||
for i, deposit in enumerate(block.body.deposits):
|
||||
# Validator is created with 0 balance
|
||||
validator = state.validators[pre_validators_len + i]
|
||||
assert validator.pubkey == deposit.data.pubkey
|
||||
assert validator.withdrawal_credentials == deposit.data.withdrawal_credentials
|
||||
assert validator.effective_balance == spec.Gwei(0)
|
||||
assert state.balances[pre_validators_len + i] == spec.Gwei(0)
|
||||
|
||||
assert actual_pubkeys == expected_pubkeys
|
||||
# The corresponding pending deposit is created
|
||||
pending_deposit = state.pending_deposits[pre_pending_deposits_len + i]
|
||||
assert pending_deposit.pubkey == deposit.data.pubkey
|
||||
assert pending_deposit.withdrawal_credentials == deposit.data.withdrawal_credentials
|
||||
assert pending_deposit.amount == deposit.data.amount
|
||||
assert pending_deposit.signature == deposit.data.signature
|
||||
assert pending_deposit.slot == spec.GENESIS_SLOT
|
||||
|
||||
# Assert that no unexpected validators were created
|
||||
assert len(state.validators) == pre_validators_len + len(block.body.deposits)
|
||||
|
||||
# Check that deposit requests are processed
|
||||
for i, deposit_request in enumerate(block.body.execution_payload.deposit_requests):
|
||||
# The corresponding pending deposit is created
|
||||
pending_deposit = state.pending_deposits[pre_pending_deposits_len + len(block.body.deposits) + i]
|
||||
assert pending_deposit.pubkey == deposit_request.pubkey
|
||||
assert pending_deposit.withdrawal_credentials == deposit_request.withdrawal_credentials
|
||||
assert pending_deposit.amount == deposit_request.amount
|
||||
assert pending_deposit.signature == deposit_request.signature
|
||||
assert pending_deposit.slot == signed_block.message.slot
|
||||
|
||||
# Assert that no unexpected pending deposits were created
|
||||
assert len(state.pending_deposits) == pre_pending_deposits_len + len(
|
||||
block.body.deposits) + len(block.body.execution_payload.deposit_requests)
|
||||
|
||||
|
||||
def prepare_state_and_block(spec,
|
||||
|
@ -222,12 +253,12 @@ def test_deposit_transition__deposit_and_top_up_same_block(spec, state):
|
|||
block.body.execution_payload.deposit_requests[0].pubkey = top_up_keys[0]
|
||||
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
|
||||
|
||||
pre_pending_deposits = len(state.pending_balance_deposits)
|
||||
pre_pending_deposits = len(state.pending_deposits)
|
||||
|
||||
yield from run_deposit_transition_block(spec, state, block, top_up_keys=top_up_keys)
|
||||
|
||||
# Check the top up
|
||||
assert len(state.pending_balance_deposits) == pre_pending_deposits + 2
|
||||
assert state.pending_balance_deposits[pre_pending_deposits].amount == block.body.deposits[0].data.amount
|
||||
assert len(state.pending_deposits) == pre_pending_deposits + 2
|
||||
assert state.pending_deposits[pre_pending_deposits].amount == block.body.deposits[0].data.amount
|
||||
amount_from_deposit = block.body.execution_payload.deposit_requests[0].amount
|
||||
assert state.pending_balance_deposits[pre_pending_deposits + 1].amount == amount_from_deposit
|
||||
assert state.pending_deposits[pre_pending_deposits + 1].amount == amount_from_deposit
|
||||
|
|
|
@ -219,6 +219,22 @@ def prepare_deposit_request(spec, validator_index, amount,
|
|||
signed,
|
||||
)
|
||||
|
||||
|
||||
def build_pending_deposit_top_up(spec, state, validator_index, amount, slot=None):
|
||||
"""
|
||||
Create a pending deposit which is a top up to an existing validator
|
||||
"""
|
||||
if slot is None:
|
||||
slot = spec.GENESIS_SLOT
|
||||
|
||||
return spec.PendingDeposit(
|
||||
pubkey=state.validators[validator_index].pubkey,
|
||||
withdrawal_credentials=state.validators[validator_index].withdrawal_credentials,
|
||||
amount=amount,
|
||||
signature=bls.G2_POINT_AT_INFINITY,
|
||||
slot=slot,
|
||||
)
|
||||
|
||||
#
|
||||
# Run processing
|
||||
#
|
||||
|
@ -243,7 +259,7 @@ def run_deposit_processing(spec, state, deposit, validator_index, valid=True, ef
|
|||
pre_effective_balance = state.validators[validator_index].effective_balance
|
||||
|
||||
if is_post_electra(spec):
|
||||
pre_pending_deposits = len(state.pending_balance_deposits)
|
||||
pre_pending_deposits = len(state.pending_deposits)
|
||||
|
||||
yield 'pre', state
|
||||
yield 'deposit', deposit
|
||||
|
@ -285,9 +301,13 @@ def run_deposit_processing(spec, state, deposit, validator_index, valid=True, ef
|
|||
assert get_balance(state, validator_index) == pre_balance
|
||||
assert state.validators[validator_index].effective_balance == pre_effective_balance
|
||||
# new correct balance deposit queued up
|
||||
assert len(state.pending_balance_deposits) == pre_pending_deposits + 1
|
||||
assert state.pending_balance_deposits[pre_pending_deposits].amount == deposit.data.amount
|
||||
assert state.pending_balance_deposits[pre_pending_deposits].index == validator_index
|
||||
assert len(state.pending_deposits) == pre_pending_deposits + 1
|
||||
assert state.pending_deposits[pre_pending_deposits].pubkey == deposit.data.pubkey
|
||||
assert state.pending_deposits[
|
||||
pre_pending_deposits].withdrawal_credentials == deposit.data.withdrawal_credentials
|
||||
assert state.pending_deposits[pre_pending_deposits].amount == deposit.data.amount
|
||||
assert state.pending_deposits[pre_pending_deposits].signature == deposit.data.signature
|
||||
assert state.pending_deposits[pre_pending_deposits].slot == spec.GENESIS_SLOT
|
||||
|
||||
assert state.eth1_deposit_index == state.eth1_data.deposit_count
|
||||
|
||||
|
@ -337,7 +357,7 @@ def run_deposit_request_processing(spec, state, deposit_request, validator_index
|
|||
pre_balance = get_balance(state, validator_index)
|
||||
pre_effective_balance = state.validators[validator_index].effective_balance
|
||||
|
||||
pre_pending_deposits = len(state.pending_balance_deposits)
|
||||
pre_pending_deposits = len(state.pending_deposits)
|
||||
|
||||
yield 'pre', state
|
||||
yield 'deposit_request', deposit_request
|
||||
|
@ -363,13 +383,17 @@ def run_deposit_request_processing(spec, state, deposit_request, validator_index
|
|||
assert len(state.validators) == pre_validator_count
|
||||
assert len(state.balances) == pre_validator_count
|
||||
else:
|
||||
# new validator
|
||||
assert len(state.validators) == pre_validator_count + 1
|
||||
assert len(state.balances) == pre_validator_count + 1
|
||||
# new validator is only created after the pending_deposits processing
|
||||
assert len(state.validators) == pre_validator_count
|
||||
assert len(state.balances) == pre_validator_count
|
||||
|
||||
assert len(state.pending_balance_deposits) == pre_pending_deposits + 1
|
||||
assert state.pending_balance_deposits[pre_pending_deposits].amount == deposit_request.amount
|
||||
assert state.pending_balance_deposits[pre_pending_deposits].index == validator_index
|
||||
assert len(state.pending_deposits) == pre_pending_deposits + 1
|
||||
assert state.pending_deposits[pre_pending_deposits].pubkey == deposit_request.pubkey
|
||||
assert state.pending_deposits[
|
||||
pre_pending_deposits].withdrawal_credentials == deposit_request.withdrawal_credentials
|
||||
assert state.pending_deposits[pre_pending_deposits].amount == deposit_request.amount
|
||||
assert state.pending_deposits[pre_pending_deposits].signature == deposit_request.signature
|
||||
assert state.pending_deposits[pre_pending_deposits].slot == state.slot
|
||||
|
||||
|
||||
def run_deposit_request_processing_with_specific_fork_version(
|
||||
|
|
|
@ -36,6 +36,8 @@ def get_process_calls(spec):
|
|||
'process_sync_committee_updates', # altair
|
||||
'process_full_withdrawals', # capella
|
||||
'process_partial_withdrawals', # capella
|
||||
'process_pending_deposits', # electra
|
||||
'process_pending_consolidations', # electra
|
||||
# TODO: add sharding processing functions when spec stabilizes.
|
||||
]
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ def create_genesis_state(spec, validator_balances, activation_threshold):
|
|||
state.earliest_exit_epoch = spec.GENESIS_EPOCH
|
||||
state.consolidation_balance_to_consume = 0
|
||||
state.earliest_consolidation_epoch = 0
|
||||
state.pending_balance_deposits = []
|
||||
state.pending_deposits = []
|
||||
state.pending_partial_withdrawals = []
|
||||
state.pending_consolidations = []
|
||||
|
||||
|
|
|
@ -745,7 +745,7 @@ def test_deposit_in_block(spec, state):
|
|||
yield 'post', state
|
||||
|
||||
if is_post_electra(spec):
|
||||
balance = state.pending_balance_deposits[0].amount
|
||||
balance = state.pending_deposits[0].amount
|
||||
else:
|
||||
balance = get_balance(state, validator_index)
|
||||
|
||||
|
@ -816,7 +816,7 @@ def test_deposit_top_up(spec, state):
|
|||
|
||||
balance = get_balance(state, validator_index)
|
||||
if is_post_electra(spec):
|
||||
balance += state.pending_balance_deposits[0].amount
|
||||
balance += state.pending_deposits[0].amount
|
||||
|
||||
assert balance == (
|
||||
validator_pre_balance + amount + sync_committee_reward - sync_committee_penalty
|
||||
|
|
|
@ -39,7 +39,7 @@ if __name__ == "__main__":
|
|||
|
||||
_new_electra_mods = {key: 'eth2spec.test.electra.epoch_processing.test_process_' + key for key in [
|
||||
'effective_balance_updates',
|
||||
'pending_balance_deposits',
|
||||
'pending_deposits',
|
||||
'pending_consolidations',
|
||||
]}
|
||||
electra_mods = combine_mods(_new_electra_mods, deneb_mods)
|
||||
|
|
Loading…
Reference in New Issue