From 778a32ab9b002c029f810299743f8686bf74eb32 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Thu, 17 Oct 2024 16:21:24 +0600 Subject: [PATCH 1/5] Add missing withdrawal requests tests --- .../test_process_withdrawal_request.py | 48 ++++++++++++++----- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_withdrawal_request.py b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_withdrawal_request.py index e3ebcae7e6..39626ee059 100644 --- a/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_withdrawal_request.py +++ b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_withdrawal_request.py @@ -124,7 +124,7 @@ def test_basic_withdrawal_request_with_full_partial_withdrawal_queue(spec, state ) -# Invalid tests +# Tests that should fail @with_electra_and_later @@ -237,6 +237,31 @@ def test_activation_epoch_less_than_shard_committee_period(spec, state): ) +@with_electra_and_later +@spec_state_test +def test_unknown_pubkey(spec, state): + rng = random.Random(1344) + # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit + state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH + + current_epoch = spec.get_current_epoch(state) + validator_index = rng.choice(spec.get_active_validator_indices(state, current_epoch)) + address = b"\x22" * 20 + pubkey = spec.BLSPubkey(b"\x23" * 48) + set_eth1_withdrawal_credential_with_balance( + spec, state, validator_index, address=address + ) + withdrawal_request = spec.WithdrawalRequest( + source_address=address, + validator_pubkey=pubkey, + amount=spec.FULL_EXIT_REQUEST_AMOUNT, + ) + + yield from run_withdrawal_request_processing( + spec, state, withdrawal_request, success=False + ) + + # Partial withdrawals tests @with_electra_and_later @@ -896,10 +921,6 @@ def run_withdrawal_request_processing( If ``valid == False``, run expecting ``AssertionError`` If ``success == False``, it doesn't initiate exit successfully """ - validator_index = get_validator_index_by_pubkey( - state, withdrawal_request.validator_pubkey - ) - yield "pre", state yield "withdrawal_request", withdrawal_request @@ -912,14 +933,7 @@ def run_withdrawal_request_processing( yield "post", None return - pre_exit_epoch = state.validators[validator_index].exit_epoch - pre_pending_partial_withdrawals = state.pending_partial_withdrawals.copy() - pre_balance = state.balances[validator_index] - pre_effective_balance = state.validators[validator_index].effective_balance pre_state = state.copy() - expected_amount_to_withdraw = compute_amount_to_withdraw( - spec, state, validator_index, withdrawal_request.amount - ) spec.process_withdrawal_request( state, withdrawal_request @@ -931,6 +945,13 @@ def run_withdrawal_request_processing( # No-op assert pre_state == state else: + validator_index = get_validator_index_by_pubkey( + state, withdrawal_request.validator_pubkey + ) + pre_exit_epoch = pre_state.validators[validator_index].exit_epoch + pre_pending_partial_withdrawals = pre_state.pending_partial_withdrawals.copy() + pre_balance = pre_state.balances[validator_index] + pre_effective_balance = pre_state.validators[validator_index].effective_balance assert state.balances[validator_index] == pre_balance assert ( state.validators[validator_index].effective_balance == pre_effective_balance @@ -943,6 +964,9 @@ def run_withdrawal_request_processing( assert state.pending_partial_withdrawals == pre_pending_partial_withdrawals # Partial withdrawal request else: + expected_amount_to_withdraw = compute_amount_to_withdraw( + spec, pre_state, validator_index, withdrawal_request.amount + ) assert state.validators[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH expected_withdrawable_epoch = ( state.earliest_exit_epoch From 792cb18bd1bbb0d09a00830bb62ad098c5f854fd Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Thu, 17 Oct 2024 17:30:51 +0600 Subject: [PATCH 2/5] Add more process_attestation tests --- .../test_process_attestation.py | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py index f268feb034..aca41a5a63 100644 --- a/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py +++ b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py @@ -1,12 +1,16 @@ +from eth2spec.test.helpers.constants import MINIMAL from eth2spec.test.context import ( always_bls, spec_state_test, with_electra_and_later, + with_presets, ) from eth2spec.test.helpers.attestations import ( run_attestation_processing, get_valid_attestation, sign_attestation, + build_attestation_data, + fill_aggregate_attestation, ) from eth2spec.test.helpers.state import ( next_slots, @@ -79,3 +83,30 @@ def test_invalid_nonset_committe_bits(spec, state): attestation.committee_bits[committee_index] = 0 yield from run_attestation_processing(spec, state, attestation, valid=False) + + +@with_electra_and_later +@spec_state_test +@with_presets([MINIMAL], "need multiple committees per slot") +@always_bls +def test_multiple_committees(spec, state): + attestation_data = build_attestation_data(spec, state, slot=state.slot, index=0) + attestation = spec.Attestation(data=attestation_data) + + # fill the attestation with two committees and finally sign it + fill_aggregate_attestation(spec, state, attestation, signed=False, committee_index=0) + fill_aggregate_attestation(spec, state, attestation, signed=True, committee_index=1) + + next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) + + yield from run_attestation_processing(spec, state, attestation) + + +@with_electra_and_later +@spec_state_test +@always_bls +def test_one_committee_with_gap(spec, state): + attestation = get_valid_attestation(spec, state, index=1, signed=True) + next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) + + yield from run_attestation_processing(spec, state, attestation) From f4a7f02af0480d77ed204615c42656c0c7629c77 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Thu, 17 Oct 2024 20:31:29 +0600 Subject: [PATCH 3/5] Apply suggestions by @jtraglia --- .../test/electra/block_processing/test_process_attestation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py index aca41a5a63..0922f4bd0c 100644 --- a/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py +++ b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py @@ -93,8 +93,8 @@ def test_multiple_committees(spec, state): attestation_data = build_attestation_data(spec, state, slot=state.slot, index=0) attestation = spec.Attestation(data=attestation_data) - # fill the attestation with two committees and finally sign it - fill_aggregate_attestation(spec, state, attestation, signed=False, committee_index=0) + # fill the attestation with two committees + fill_aggregate_attestation(spec, state, attestation, signed=True, committee_index=0) fill_aggregate_attestation(spec, state, attestation, signed=True, committee_index=1) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) From d64e537bd24c979f0a68d1d37b1f6cc468d23490 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Fri, 18 Oct 2024 09:31:51 +0600 Subject: [PATCH 4/5] Fix presets for process_attestation test --- .../test/electra/block_processing/test_process_attestation.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py index 0922f4bd0c..635d2472f4 100644 --- a/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py +++ b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py @@ -104,6 +104,7 @@ def test_multiple_committees(spec, state): @with_electra_and_later @spec_state_test +@with_presets([MINIMAL], "need multiple committees per slot") @always_bls def test_one_committee_with_gap(spec, state): attestation = get_valid_attestation(spec, state, index=1, signed=True) From 08cb8286b7dba5dadfa2c9e9110c77112c37c30f Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Fri, 1 Nov 2024 12:45:09 +0600 Subject: [PATCH 5/5] Fix and add more attestation tests --- .../test_process_attestation.py | 51 ++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py index 635d2472f4..b365bec1d6 100644 --- a/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py +++ b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py @@ -10,7 +10,8 @@ get_valid_attestation, sign_attestation, build_attestation_data, - fill_aggregate_attestation, + get_valid_attestation_at_slot, + get_empty_eip7549_aggregation_bits, ) from eth2spec.test.helpers.state import ( next_slots, @@ -39,7 +40,7 @@ def test_invalid_attestation_data_index_not_zero(spec, state): @with_electra_and_later @spec_state_test @always_bls -def test_invalid_committe_index(spec, state): +def test_invalid_committee_index(spec, state): """ EIP-7549 test """ @@ -57,7 +58,7 @@ def test_invalid_committe_index(spec, state): @with_electra_and_later @spec_state_test -def test_invalid_too_many_committe_bits(spec, state): +def test_invalid_too_many_committee_bits(spec, state): """ EIP-7549 test """ @@ -72,7 +73,7 @@ def test_invalid_too_many_committe_bits(spec, state): @with_electra_and_later @spec_state_test -def test_invalid_nonset_committe_bits(spec, state): +def test_invalid_nonset_committee_bits(spec, state): """ EIP-7549 test """ @@ -85,18 +86,51 @@ def test_invalid_nonset_committe_bits(spec, state): yield from run_attestation_processing(spec, state, attestation, valid=False) +@with_electra_and_later +@spec_state_test +def test_invalid_nonset_multiple_committee_bits(spec, state): + """ + EIP-7549 test + """ + attestation_data = build_attestation_data(spec, state, slot=state.slot, index=0) + attestation = spec.Attestation(data=attestation_data) + + # a single attestation with all committees of a slot, but with unset aggregation_bits + committees_per_slot = spec.get_committee_count_per_slot(state, spec.get_current_epoch(state)) + for index in range(committees_per_slot): + attestation.committee_bits[index] = True + + attestation.aggregation_bits = get_empty_eip7549_aggregation_bits( + spec, state, attestation.committee_bits, attestation.data.slot + ) + + next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) + + yield from run_attestation_processing(spec, state, attestation, valid=False) + + @with_electra_and_later @spec_state_test @with_presets([MINIMAL], "need multiple committees per slot") @always_bls def test_multiple_committees(spec, state): + """ + EIP-7549 test + """ attestation_data = build_attestation_data(spec, state, slot=state.slot, index=0) attestation = spec.Attestation(data=attestation_data) - # fill the attestation with two committees - fill_aggregate_attestation(spec, state, attestation, signed=True, committee_index=0) - fill_aggregate_attestation(spec, state, attestation, signed=True, committee_index=1) + # a single attestation with all committees of a slot + attestation = get_valid_attestation_at_slot(state, spec, state.slot) + + # check that all committees are presented in a single attestation + attesting_indices = set() + committees_per_slot = spec.get_committee_count_per_slot(state, spec.get_current_epoch(state)) + for index in range(committees_per_slot): + attesting_indices.update(spec.get_beacon_committee(state, state.slot, index)) + assert spec.get_attesting_indices(state, attestation) == attesting_indices + # advance a slot next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) yield from run_attestation_processing(spec, state, attestation) @@ -107,6 +141,9 @@ def test_multiple_committees(spec, state): @with_presets([MINIMAL], "need multiple committees per slot") @always_bls def test_one_committee_with_gap(spec, state): + """ + EIP-7549 test + """ attestation = get_valid_attestation(spec, state, index=1, signed=True) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)