@@ -395,7 +395,37 @@ def test_consolidation_balance_through_two_churn_epochs(spec, state):
395395 assert state .consolidation_balance_to_consume == expected_balance
396396
397397
398- # Failing tests
398+ @with_electra_and_later
399+ @with_presets ([MINIMAL ], "need sufficient consolidation churn limit" )
400+ @with_custom_state (
401+ balances_fn = scaled_churn_balances_exceed_activation_exit_churn_limit ,
402+ threshold_fn = default_activation_threshold ,
403+ )
404+ @spec_test
405+ @single_phase
406+ def test_source_equals_target_switches_to_compounding (spec , state ):
407+ current_epoch = spec .get_current_epoch (state )
408+ source_index = spec .get_active_validator_indices (state , current_epoch )[0 ]
409+
410+ # Set source to eth1 credentials
411+ source_address = b"\x22 " * 20
412+ set_eth1_withdrawal_credential_with_balance (
413+ spec , state , source_index , address = source_address
414+ )
415+ # Make consolidation from source to source
416+ consolidation = spec .ConsolidationRequest (
417+ source_address = source_address ,
418+ source_pubkey = state .validators [source_index ].pubkey ,
419+ target_pubkey = state .validators [source_index ].pubkey ,
420+ )
421+
422+ # Check the the return condition
423+ assert consolidation .source_pubkey == consolidation .target_pubkey
424+
425+ yield from run_consolidation_processing (
426+ spec , state , consolidation , success = True
427+ )
428+
399429
400430@with_electra_and_later
401431@with_presets ([MINIMAL ], "need sufficient consolidation churn limit" )
@@ -405,7 +435,7 @@ def test_consolidation_balance_through_two_churn_epochs(spec, state):
405435)
406436@spec_test
407437@single_phase
408- def test_incorrect_source_equals_target (spec , state ):
438+ def test_source_equals_target_switches_to_compounding_with_excess (spec , state ):
409439 current_epoch = spec .get_current_epoch (state )
410440 source_index = spec .get_active_validator_indices (state , current_epoch )[0 ]
411441
@@ -414,6 +444,8 @@ def test_incorrect_source_equals_target(spec, state):
414444 set_eth1_withdrawal_credential_with_balance (
415445 spec , state , source_index , address = source_address
416446 )
447+ # Add excess balance
448+ state .balances [source_index ] = state .balances [source_index ] + spec .EFFECTIVE_BALANCE_INCREMENT
417449 # Make consolidation from source to source
418450 consolidation = spec .ConsolidationRequest (
419451 source_address = source_address ,
@@ -425,10 +457,12 @@ def test_incorrect_source_equals_target(spec, state):
425457 assert consolidation .source_pubkey == consolidation .target_pubkey
426458
427459 yield from run_consolidation_processing (
428- spec , state , consolidation , success = False
460+ spec , state , consolidation , success = True
429461 )
430462
431463
464+ # Failing tests
465+
432466@with_electra_and_later
433467@with_presets ([MINIMAL ], "need sufficient consolidation churn limit" )
434468@with_custom_state (
@@ -815,36 +849,54 @@ def run_consolidation_processing(spec, state, consolidation, success=True):
815849 pre_exit_epoch_source = source_validator .exit_epoch
816850 pre_exit_epoch_target = target_validator .exit_epoch
817851 pre_pending_consolidations = state .pending_consolidations .copy ()
852+ pre_target_withdrawal_credentials = target_validator .withdrawal_credentials
853+ pre_target_balance = state .balances [target_index ]
818854 else :
819855 pre_state = state .copy ()
820856
821857 yield 'pre' , state
822858 yield 'consolidation_request' , consolidation
823859
824860 spec .process_consolidation_request (state , consolidation )
861+ # print(state.validators[target_index].withdrawal_credentials)
825862
826863 yield 'post' , state
827864
828865 if success :
829- # Check source and target have execution credentials
866+ # Check source has execution credentials
830867 assert spec .has_execution_withdrawal_credential (source_validator )
868+ # Check target has compounding credentials
831869 assert spec .has_execution_withdrawal_credential (target_validator )
832870 # Check source address in the consolidation fits the withdrawal credentials
833871 assert source_validator .withdrawal_credentials [12 :] == consolidation .source_address
834- # Check source and target are not the same
835- assert source_index != target_index
836872 # Check source and target were not exiting
837873 assert pre_exit_epoch_source == spec .FAR_FUTURE_EPOCH
838874 assert pre_exit_epoch_target == spec .FAR_FUTURE_EPOCH
839- # Check source is now exiting
840- assert state .validators [source_index ].exit_epoch < spec .FAR_FUTURE_EPOCH
841- # Check that the exit epoch matches earliest_consolidation_epoch
842- assert state .validators [source_index ].exit_epoch == state .earliest_consolidation_epoch
843- # Check that the correct consolidation has been appended
844- expected_new_pending_consolidation = spec .PendingConsolidation (
845- source_index = source_index ,
846- target_index = target_index ,
847- )
848- assert state .pending_consolidations == pre_pending_consolidations + [expected_new_pending_consolidation ]
875+ # Check excess balance is queued if the target switched to compounding
876+ if pre_target_withdrawal_credentials [:1 ] == spec .ETH1_ADDRESS_WITHDRAWAL_PREFIX :
877+ assert state .validators [target_index ].withdrawal_credentials == (
878+ spec .COMPOUNDING_WITHDRAWAL_PREFIX + pre_target_withdrawal_credentials [1 :])
879+ assert state .balances [target_index ] == spec .MIN_ACTIVATION_BALANCE
880+ if pre_target_balance > spec .MIN_ACTIVATION_BALANCE :
881+ assert state .pending_balance_deposits == [spec .PendingBalanceDeposit (
882+ index = target_index , amount = (pre_target_balance - spec .MIN_ACTIVATION_BALANCE ))]
883+ # If source and target are same, no consolidation must have been initiated
884+ if source_index == target_index :
885+ assert state .validators [source_index ].exit_epoch == spec .FAR_FUTURE_EPOCH
886+ assert state .pending_consolidations == []
887+ else :
888+ # Check source is now exiting
889+ assert state .validators [source_index ].exit_epoch < spec .FAR_FUTURE_EPOCH
890+ # Check that the exit epoch matches earliest_consolidation_epoch
891+ assert state .validators [source_index ].exit_epoch == state .earliest_consolidation_epoch
892+ # Check that the withdrawable_epoch is set correctly
893+ assert state .validators [source_index ].withdrawable_epoch == (
894+ state .validators [source_index ].exit_epoch + spec .config .MIN_VALIDATOR_WITHDRAWABILITY_DELAY )
895+ # Check that the correct consolidation has been appended
896+ expected_new_pending_consolidation = spec .PendingConsolidation (
897+ source_index = source_index ,
898+ target_index = target_index ,
899+ )
900+ assert state .pending_consolidations == pre_pending_consolidations + [expected_new_pending_consolidation ]
849901 else :
850902 assert pre_state == state
0 commit comments