diff --git a/tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_apply_pending_deposit.py b/tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_apply_pending_deposit.py index 019db4f87..c5ed4aa3a 100644 --- a/tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_apply_pending_deposit.py +++ b/tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_apply_pending_deposit.py @@ -5,114 +5,129 @@ from eth2spec.test.context import ( from eth2spec.test.helpers.keys import privkeys, pubkeys from tests.core.pyspec.eth2spec.test.helpers.deposits import build_deposit_data + @with_electra_and_later @spec_state_test def test_apply_pending_deposit_add_validator_to_registry(spec, state): - amount = 100 + amount = 100 - # choose a value public key that's not in the validator set outside of the mainnet preset of 256 + # select validator set outside of the mainnet preset of 256 index = 2000 - withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkeys[index])[1:] + withdrawal_credentials = ( + spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkeys[index])[1:] + ) deposit_data = build_deposit_data(spec, - pubkeys[index], - privkeys[index], - amount, - withdrawal_credentials, - signed=True) + pubkeys[index], + privkeys[index], + amount, + withdrawal_credentials, + signed=True) deposit = spec.PendingDeposit( pubkey=pubkeys[index], - withdrawal_credentials= withdrawal_credentials, + withdrawal_credentials=withdrawal_credentials, amount=amount, slot=spec.GENESIS_SLOT, signature=deposit_data.signature, - ) + ) old_validator_count = len(state.validators) - spec.apply_pending_deposit(state,deposit) + spec.apply_pending_deposit(state, deposit) # validator count should increase by 1 - assert len(state.validators) == old_validator_count+1 + assert len(state.validators) == old_validator_count + 1 + @with_electra_and_later @spec_state_test def test_apply_pending_deposit_increases_balance(spec, state): - amount = 100 + amount = 100 state.validators[0].exit_epoch = spec.FAR_FUTURE_EPOCH # signature doesn't matter here as it's interpreted as a top-up deposit = spec.PendingDeposit( pubkey=state.validators[0].pubkey, - withdrawal_credentials= state.validators[0].withdrawal_credentials, + withdrawal_credentials=state.validators[0].withdrawal_credentials, amount=amount, - slot=spec.GENESIS_SLOT, - ) - # reset the balance + slot=spec.GENESIS_SLOT + ) + # reset the balance state.balances[0] = 0 # run test - spec.apply_pending_deposit(state,deposit) + spec.apply_pending_deposit(state, deposit) assert state.balances[0] == amount @with_electra_and_later @spec_state_test def test_apply_pending_deposit_switch_to_compounding(spec, state): - amount = 100 + amount = 100 # choose a value public key that's in the validator set index = 0 - withdrawal_credentials = spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX + spec.hash(pubkeys[index])[1:] - compounding_credentials = spec.COMPOUNDING_WITHDRAWAL_PREFIX + spec.hash(pubkeys[index])[1:] + withdrawal_credentials = ( + spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX + + spec.hash(pubkeys[index])[1:] + ) + compounding_credentials = ( + spec.COMPOUNDING_WITHDRAWAL_PREFIX + + spec.hash(pubkeys[index])[1:] + ) state.slot = spec.SLOTS_PER_EPOCH * 2 state.validators[index].withdrawal_credentials = withdrawal_credentials # set validator to be exited by current epoch state.validators[index].exit_epoch = spec.get_current_epoch(state) - 1 deposit_data = build_deposit_data(spec, - pubkeys[index], - privkeys[index], - amount, - compounding_credentials, - signed=True) + pubkeys[index], + privkeys[index], + amount, + compounding_credentials, + signed=True) deposit = spec.PendingDeposit( pubkey=pubkeys[index], - withdrawal_credentials= compounding_credentials, + withdrawal_credentials=compounding_credentials, amount=amount, slot=spec.GENESIS_SLOT, signature=deposit_data.signature, - ) + ) state.balances[0] = 0 # run test - spec.apply_pending_deposit(state,deposit) + spec.apply_pending_deposit(state, deposit) # validator balance should increase assert state.balances[0] == amount - assert state.validators[0].withdrawal_credentials == compounding_credentials + current_credentials = state.validators[0].withdrawal_credentials + assert current_credentials == compounding_credentials + @with_electra_and_later @spec_state_test -def test_apply_pending_deposit_switch_to_compounding_while_validator_not_exited(spec, state): - amount = 100 +def test_apply_pending_deposit_switch_to_compounding_not_exited(spec, state): + amount = 100 # choose a value public key that's in the validator set index = 0 - withdrawal_credentials = spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX + spec.hash(pubkeys[index])[1:] - compounding_credentials = spec.COMPOUNDING_WITHDRAWAL_PREFIX + spec.hash(pubkeys[index])[1:] + withdrawal_credentials = ( + spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX + spec.hash(pubkeys[index])[1:] + ) + compounding_credentials = ( + spec.COMPOUNDING_WITHDRAWAL_PREFIX + spec.hash(pubkeys[index])[1:] + ) state.validators[index].withdrawal_credentials = withdrawal_credentials # set validator to not be exited state.validators[index].exit_epoch = spec.FAR_FUTURE_EPOCH deposit_data = build_deposit_data(spec, - pubkeys[index], - privkeys[index], - amount, - compounding_credentials, - signed=True) + pubkeys[index], + privkeys[index], + amount, + compounding_credentials, + signed=True) deposit = spec.PendingDeposit( pubkey=pubkeys[index], - withdrawal_credentials= compounding_credentials, + withdrawal_credentials=compounding_credentials, amount=amount, slot=spec.GENESIS_SLOT, signature=deposit_data.signature, - ) + ) state.balances[0] = 0 # run test - spec.apply_pending_deposit(state,deposit) + spec.apply_pending_deposit(state, deposit) # validator balance should increase assert state.balances[0] == amount # make sure validator did not switch to compounding if not exited assert state.validators[0].withdrawal_credentials == withdrawal_credentials - \ No newline at end of file diff --git a/tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_process_pending_deposits.py b/tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_process_pending_deposits.py index e6319aa6b..207bf8940 100644 --- a/tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_process_pending_deposits.py +++ b/tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_process_pending_deposits.py @@ -9,26 +9,35 @@ from eth2spec.test.helpers.deposits import ( def run_process_pending_deposits(spec, state): - yield from run_epoch_processing_with(spec, state, 'process_pending_deposits') + yield from run_epoch_processing_with( + spec, state, 'process_pending_deposits') + @with_electra_and_later @spec_state_test def test_pending_deposit_over_max(spec, state): # pick an amount that adds to less than churn limit - amount = 100 + amount = 100 overmax = spec.MAX_PENDING_DEPOSITS_PER_EPOCH_PROCESSING + 1 for i in range(overmax): - state.pending_deposits.append(spec.PendingDeposit( - pubkey=state.validators[i].pubkey, - withdrawal_credentials=state.validators[i].withdrawal_credentials, - amount=amount, - slot=spec.GENESIS_SLOT, - )) - assert len(state.pending_deposits) == overmax,"pending deposits is not over max" + state.pending_deposits.append( + spec.PendingDeposit( + pubkey=state.validators[i].pubkey, + withdrawal_credentials=( + state.validators[i].withdrawal_credentials + ), + amount=amount, + slot=spec.GENESIS_SLOT, + ) + ) + assert len(state.pending_deposits) == overmax, \ + "pending deposits is not overmax" + # the remaining deposit over MAX_PENDING_DEPOSITS_PER_EPOCH_PROCESSING + # should remain in pending_deposits yield from run_process_pending_deposits(spec, state) - # the remaining deposit over MAX_PENDING_DEPOSITS_PER_EPOCH_PROCESSING should remain in pending_deposits assert len(state.pending_deposits) == 1 + @with_electra_and_later @spec_state_test def test_pending_deposit_eth1_bridge_not_applied(spec, state): @@ -40,9 +49,9 @@ def test_pending_deposit_eth1_bridge_not_applied(spec, state): amount=amount, slot=1, )) - # set deposit_requests_start_index to something high so that deposit is not processed + # set deposit_requests_start_index to something high state.deposit_requests_start_index = 100000000000000000 - # set deposit_balance_to_consume to some initial amount to see its removal later on in the test + # set deposit_balance_to_consume to some initial amount state.deposit_balance_to_consume = amount yield from run_process_pending_deposits(spec, state) # deposit_balance_to_consume was reset to 0 @@ -56,18 +65,16 @@ def test_pending_deposit_eth1_bridge_not_applied(spec, state): def test_pending_deposit_not_finalized(spec, state): amount = spec.MIN_ACTIVATION_BALANCE # set slot to something not finalized - slot=spec.compute_start_slot_at_epoch(state.finalized_checkpoint.epoch+1) # deposit is not finalized yet, so it is postponed state.pending_deposits.append(spec.PendingDeposit( pubkey=state.validators[0].pubkey, withdrawal_credentials=state.validators[0].withdrawal_credentials, amount=amount, - slot=spec.get_current_epoch(state), + slot=spec.get_current_epoch(state) + 1, )) - # set deposit_requests_start_index to something low so that we skip the bridge validation + # skip the bridge validation state.deposit_requests_start_index = 0 - print("deposit indexes",state.eth1_deposit_index,state.deposit_requests_start_index) - # set deposit_balance_to_consume to some initial amount to see its removal later on in the test + # set deposit_balance_to_consume to some initial amount state.deposit_balance_to_consume = amount yield from run_process_pending_deposits(spec, state) # deposit_balance_to_consume was reset to 0 @@ -75,12 +82,13 @@ def test_pending_deposit_not_finalized(spec, state): # deposit was postponed and not processed assert len(state.pending_deposits) == 1 + @with_electra_and_later @spec_state_test def test_pending_deposit_validator_withdrawn(spec, state): amount = spec.MIN_ACTIVATION_BALANCE - - withdrawal_credentials = spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX + spec.hash(state.validators[0].pubkey)[1:] + hash = spec.hash(state.validators[0].pubkey)[1:] + withdrawal_credentials = spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX + hash state.slot = spec.SLOTS_PER_EPOCH * 2 state.validators[0].withdrawal_credentials = withdrawal_credentials # set validator to be withdrawable by current epoch @@ -91,10 +99,9 @@ def test_pending_deposit_validator_withdrawn(spec, state): amount=amount, slot=spec.GENESIS_SLOT, )) - # set deposit_requests_start_index to something low so that we skip the bridge validation + # skip the bridge validation state.deposit_requests_start_index = 0 - print("deposit indexes",state.eth1_deposit_index,state.deposit_requests_start_index) - # set deposit_balance_to_consume to some initial amount to see its removal later on in the test + # set deposit_balance_to_consume to some initial amount state.deposit_balance_to_consume = amount # reset balance for assert state.balances[0] = 0 @@ -106,12 +113,13 @@ def test_pending_deposit_validator_withdrawn(spec, state): # balance increases because of withdraw assert state.balances[0] == amount + @with_electra_and_later @spec_state_test def test_pending_deposit_validator_exiting_but_not_withdrawn(spec, state): amount = spec.MIN_ACTIVATION_BALANCE - - withdrawal_credentials = spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX + spec.hash(state.validators[0].pubkey)[1:] + hash = spec.hash(state.validators[0].pubkey)[1:] + withdrawal_credentials = spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX + hash state.slot = spec.SLOTS_PER_EPOCH * 2 state.validators[0].withdrawal_credentials = withdrawal_credentials # set validator to be withdrawable by current epoch @@ -123,16 +131,15 @@ def test_pending_deposit_validator_exiting_but_not_withdrawn(spec, state): amount=amount, slot=spec.GENESIS_SLOT, )) - # set deposit_requests_start_index to something low so that we skip the bridge validation + # skip the bridge validation state.deposit_requests_start_index = 0 - print("deposit indexes",state.eth1_deposit_index,state.deposit_requests_start_index) - # set deposit_balance_to_consume to some initial amount to see its removal later on in the test + # set deposit_balance_to_consume to some initial amount state.deposit_balance_to_consume = amount yield from run_process_pending_deposits(spec, state) # deposit_balance_to_consume was reset to 0 assert state.deposit_balance_to_consume == 0 - # deposit was postponed and not processed + # deposit was postponed and not processed assert len(state.pending_deposits) == 1 @@ -149,7 +156,7 @@ def test_pending_deposit_min_activation_balance(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 + # No leftover deposit balance to consume assert state.deposit_balance_to_consume == 0 assert state.pending_deposits == [] @@ -186,9 +193,8 @@ def test_pending_deposit_balance_above_churn(spec, state): # deposit was above churn, balance hasn't changed assert state.balances[index] == pre_balance # deposit balance to consume is the full churn limit - assert state.deposit_balance_to_consume == spec.get_activation_exit_churn_limit( - state - ) + wantedBalanceToConsume = spec.get_activation_exit_churn_limit(state) + assert state.deposit_balance_to_consume == wantedBalanceToConsume # deposit is still in the queue assert state.pending_deposits == [ build_pending_deposit_top_up(spec, state, index, amount) @@ -210,7 +216,7 @@ def test_pending_deposit_preexisting_churn(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 + # No leftover deposit balance to consume assert state.deposit_balance_to_consume == 0 # queue emptied assert state.pending_deposits == [] @@ -221,10 +227,12 @@ def test_pending_deposit_preexisting_churn(spec, state): def test_multiple_pending_deposits_below_churn(spec, state): amount = 10**9 state.pending_deposits.append( - build_pending_deposit_top_up(spec, state, validator_index=0, amount=amount) + build_pending_deposit_top_up(spec, state, + validator_index=0, amount=amount) ) state.pending_deposits.append( - build_pending_deposit_top_up(spec, state, validator_index=1, amount=amount) + build_pending_deposit_top_up(spec, state, + validator_index=1, amount=amount) ) pre_balances = state.balances.copy() @@ -232,7 +240,7 @@ def test_multiple_pending_deposits_below_churn(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 + # No leftover deposit balance to consume assert state.deposit_balance_to_consume == 0 assert state.pending_deposits == [] @@ -244,7 +252,8 @@ def test_multiple_pending_deposits_above_churn(spec, state): amount = (spec.get_activation_exit_churn_limit(state) // 3) + 1 for i in [0, 1, 2]: state.pending_deposits.append( - build_pending_deposit_top_up(spec, state, validator_index=i, amount=amount) + build_pending_deposit_top_up(spec, state, + validator_index=i, amount=amount) ) pre_balances = state.balances.copy() @@ -261,7 +270,8 @@ def test_multiple_pending_deposits_above_churn(spec, state): ) # third deposit is still in the queue assert state.pending_deposits == [ - build_pending_deposit_top_up(spec, state, validator_index=2, amount=amount) + build_pending_deposit_top_up(spec, state, + validator_index=2, amount=amount) ] @@ -270,7 +280,10 @@ 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_deposits.append(build_pending_deposit_top_up(spec, state, validator_index=index, amount=amount)) + 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 @@ -280,7 +293,7 @@ def test_skipped_deposit_exiting_validator(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 + # All deposits either processed or postponed assert state.deposit_balance_to_consume == 0 # The deposit is still in the queue assert state.pending_deposits == pre_pending_deposits @@ -292,7 +305,10 @@ 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_deposits.append(build_pending_deposit_top_up(spec, state, validator_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) @@ -314,7 +330,10 @@ 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_deposits.append(build_pending_deposit_top_up(spec, state, validator_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) @@ -325,10 +344,13 @@ def test_multiple_pending_one_skipped(spec, state): for i in [0, 2]: assert state.balances[i] == pre_balances[i] + amount assert state.balances[1] == pre_balances[1] - # All deposits either processed or postponed, no leftover deposit balance to consume + # All deposits either processed or postponed assert state.deposit_balance_to_consume == 0 # second deposit is still in the queue - assert state.pending_deposits == [build_pending_deposit_top_up(spec, state, validator_index=1, amount=amount)] + assert state.pending_deposits == [ + build_pending_deposit_top_up(spec, state, + validator_index=1, amount=amount) + ] @with_electra_and_later @@ -338,8 +360,16 @@ 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_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)) + 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) @@ -352,11 +382,16 @@ def test_mixture_of_skipped_and_above_churn(spec, state): for i in [1, 2]: assert state.balances[i] == pre_balances[i] # First deposit consumes some deposit balance - # 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_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)] + # Deposit is not processed + wanted_balance = spec.get_activation_exit_churn_limit(state) - amount01 + assert state.deposit_balance_to_consume == wanted_balance + # second and third deposit still in the queue + 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 @@ -364,42 +399,55 @@ 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_deposits.append(build_pending_deposit_top_up(spec, state, validator_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) + withdrawable_epoch = state.validators[index].withdrawable_epoch + state.slot = spec.SLOTS_PER_EPOCH * (withdrawable_epoch + 1) 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 + # No leftover deposit balance to consume assert state.deposit_balance_to_consume == 0 assert state.pending_deposits == [] @with_electra_and_later @spec_state_test -def test_processing_deposit_of_withdrawable_validator_does_not_get_churned(spec, state): +def test_processing_deposit_of_withdrawable_validator_not_churned(spec, state): amount = spec.MAX_EFFECTIVE_BALANCE_ELECTRA for i in [0, 1]: - state.pending_deposits.append(build_pending_deposit_top_up(spec, state, validator_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) # Set epoch to withdrawable epoch + 1 to allow processing of the deposit - state.slot = spec.SLOTS_PER_EPOCH * (state.validators[0].withdrawable_epoch + 1) + withdraw_epoch = state.validators[0].withdrawable_epoch + state.slot = spec.SLOTS_PER_EPOCH * (withdraw_epoch + 1) # Don't use run_epoch_processing_with to avoid penalties being applied yield 'pre', state spec.process_pending_deposits(state) yield 'post', state - # First deposit is processed though above churn limit, because validator is withdrawable + # First deposit is processed though above churn limit assert state.balances[0] == pre_balances[0] + amount # Second deposit is not processed because above churn assert state.balances[1] == pre_balances[1] - # Second deposit is not processed, so there's leftover deposit balance to consume. + # Second deposit is not processed # First deposit does not consume any. - assert state.deposit_balance_to_consume == spec.get_activation_exit_churn_limit(state) - assert state.pending_deposits == [build_pending_deposit_top_up(spec, state, validator_index=1, amount=amount)] + wantedLimit = spec.get_activation_exit_churn_limit(state) + assert state.deposit_balance_to_consume == wantedLimit + assert state.pending_deposits == [ + build_pending_deposit_top_up(spec, state, + validator_index=1, amount=amount) + ]