diff --git a/.circleci/config.yml b/.circleci/config.yml index 0367da9dd9..ef2eff9e26 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -181,6 +181,19 @@ jobs: command: make citest fork=eip7002 - store_test_results: path: tests/core/pyspec/test-reports + test-eip7549: + docker: + - image: circleci/python:3.9 + working_directory: ~/specs-repo + steps: + - restore_cache: + key: v3-specs-repo-{{ .Branch }}-{{ .Revision }} + - restore_pyspec_cached_venv + - run: + name: Run py-tests + command: make citest fork=eip7549 + - store_test_results: + path: tests/core/pyspec/test-reports test-whisk: docker: - image: circleci/python:3.9 @@ -333,6 +346,9 @@ workflows: - test-eip7002: requires: - install_pyspec_test + - test-eip7549: + requires: + - install_pyspec_test - test-whisk: requires: - install_pyspec_test diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 2973afb068..9693217971 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -71,7 +71,7 @@ jobs: needs: [preclear,lint,codespell,table_of_contents] strategy: matrix: - version: ["phase0", "altair", "bellatrix", "capella", "deneb", "eip6110", "eip7002", "whisk", "eip7594"] + version: ["phase0", "altair", "bellatrix", "capella", "deneb", "eip6110", "eip7002", "eip7549", "whisk", "eip7594"] steps: - name: Checkout this repo uses: actions/checkout@v3.2.0 diff --git a/Makefile b/Makefile index d0d750e893..c6bc8dd842 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ MARKDOWN_FILES = $(wildcard $(SPEC_DIR)/*/*.md) \ $(wildcard $(SPEC_DIR)/_features/*/*/*.md) \ $(wildcard $(SSZ_DIR)/*.md) -ALL_EXECUTABLE_SPEC_NAMES = phase0 altair bellatrix capella deneb eip6110 eip7002 whisk +ALL_EXECUTABLE_SPEC_NAMES = phase0 altair bellatrix capella deneb eip6110 eip7002 eip7549 whisk # The parameters for commands. Use `foreach` to avoid listing specs again. COVERAGE_SCOPE := $(foreach S,$(ALL_EXECUTABLE_SPEC_NAMES), --cov=eth2spec.$S.$(TEST_PRESET_TYPE)) PYLINT_SCOPE := $(foreach S,$(ALL_EXECUTABLE_SPEC_NAMES), ./eth2spec/$S) diff --git a/configs/mainnet.yaml b/configs/mainnet.yaml index 28809f94a2..1092ec507d 100644 --- a/configs/mainnet.yaml +++ b/configs/mainnet.yaml @@ -62,6 +62,9 @@ EIP7002_FORK_EPOCH: 18446744073709551615 # EIP7251 EIP7251_FORK_VERSION: 0x06000000 # temporary stub EIP7251_FORK_EPOCH: 18446744073709551615 +# EIP7549 +EIP7549_FORK_VERSION: 0x06000000 # temporary stub +EIP7549_FORK_EPOCH: 18446744073709551615 # WHISK WHISK_FORK_VERSION: 0x08000000 # temporary stub WHISK_FORK_EPOCH: 18446744073709551615 diff --git a/configs/minimal.yaml b/configs/minimal.yaml index 96a0f662d8..07f0da4e22 100644 --- a/configs/minimal.yaml +++ b/configs/minimal.yaml @@ -59,8 +59,11 @@ EIP6110_FORK_EPOCH: 18446744073709551615 EIP7002_FORK_VERSION: 0x07000001 EIP7002_FORK_EPOCH: 18446744073709551615 # EIP7251 -EIP7251_FORK_VERSION: 0x06000000 # temporary stub +EIP7251_FORK_VERSION: 0x06000001 # temporary stub EIP7251_FORK_EPOCH: 18446744073709551615 +# EIP7549 +EIP7549_FORK_VERSION: 0x06000001 # temporary stub +EIP7549_FORK_EPOCH: 18446744073709551615 # WHISK WHISK_FORK_VERSION: 0x08000001 WHISK_FORK_EPOCH: 18446744073709551615 diff --git a/presets/mainnet/eip7549.yaml b/presets/mainnet/eip7549.yaml new file mode 100644 index 0000000000..6d10f82e15 --- /dev/null +++ b/presets/mainnet/eip7549.yaml @@ -0,0 +1,8 @@ +# Mainnet preset - EIP7594 + +# # Max operations per block +# --------------------------------------------------------------- +# `uint64(2**0)` (= 1) +MAX_ATTESTER_SLASHINGS_EIP7549: 1 +# `uint64(2 * 3)` (= 8) +MAX_ATTESTATIONS_EIP7549: 8 diff --git a/presets/minimal/eip7549.yaml b/presets/minimal/eip7549.yaml new file mode 100644 index 0000000000..17e21652a3 --- /dev/null +++ b/presets/minimal/eip7549.yaml @@ -0,0 +1,8 @@ +# Minimal preset - EIP7594 + +# # Max operations per block +# --------------------------------------------------------------- +# `uint64(2**0)` (= 1) +MAX_ATTESTER_SLASHINGS_EIP7549: 1 +# `uint64(2 * 3)` (= 8) +MAX_ATTESTATIONS_EIP7549: 8 diff --git a/specs/_features/eip7549/beacon-chain.md b/specs/_features/eip7549/beacon-chain.md index cac3a57237..9ee88e7def 100644 --- a/specs/_features/eip7549/beacon-chain.md +++ b/specs/_features/eip7549/beacon-chain.md @@ -12,6 +12,7 @@ - [Modified containers](#modified-containers) - [`Attestation`](#attestation) - [`IndexedAttestation`](#indexedattestation) + - [`BeaconBlockBody`](#beaconblockbody) - [Helper functions](#helper-functions) - [Misc](#misc) - [`get_committee_indices`](#get_committee_indices) @@ -33,8 +34,8 @@ This is the beacon chain specification to move the attestation committee index o | Name | Value | Description | | - | - | - | -| `MAX_ATTESTER_SLASHINGS` | `2**0` (= 1) | -| `MAX_ATTESTATIONS` | `2**3` (= 8) | +| `MAX_ATTESTER_SLASHINGS_EIP7549` | `2**0` (= 1) | +| `MAX_ATTESTATIONS_EIP7549` | `2**3` (= 8) | ## Containers @@ -60,6 +61,26 @@ class IndexedAttestation(Container): signature: BLSSignature ``` +#### `BeaconBlockBody` + +```python +class BeaconBlockBody(Container): + randao_reveal: BLSSignature + eth1_data: Eth1Data # Eth1 data vote + graffiti: Bytes32 # Arbitrary data + # Operations + proposer_slashings: List[ProposerSlashing, MAX_PROPOSER_SLASHINGS] + attester_slashings: List[AttesterSlashing, MAX_ATTESTER_SLASHINGS_EIP7549] # [Modified in EIP7549] + attestations: List[Attestation, MAX_ATTESTATIONS_EIP7549] # [Modified in EIP7549] + deposits: List[Deposit, MAX_DEPOSITS] + voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS] + sync_aggregate: SyncAggregate + # Execution + execution_payload: ExecutionPayload + bls_to_execution_changes: List[SignedBLSToExecutionChange, MAX_BLS_TO_EXECUTION_CHANGES] + blob_kzg_commitments: List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK] +``` + ## Helper functions ### Misc @@ -67,8 +88,8 @@ class IndexedAttestation(Container): #### `get_committee_indices` ```python -def get_committee_indices(commitee_bits: Bitvector) -> List[CommitteeIndex]: - return [CommitteeIndex(index) for bit, index in enumerate(commitee_bits) if bit] +def get_committee_indices(commitee_bits: Bitvector) -> Sequence[CommitteeIndex]: + return [CommitteeIndex(index) for index, bit in enumerate(commitee_bits) if bit] ``` ### Beacon state accessors @@ -80,8 +101,7 @@ def get_attesting_indices(state: BeaconState, attestation: Attestation) -> Set[V """ Return the set of attesting indices corresponding to ``aggregation_bits`` and ``committee_bits``. """ - - output = set() + output: Set[ValidatorIndex] = set() committee_indices = get_committee_indices(attestation.committee_bits) committee_offset = 0 for index in committee_indices: diff --git a/specs/_features/eip7549/fork.md b/specs/_features/eip7549/fork.md new file mode 100644 index 0000000000..9294670db8 --- /dev/null +++ b/specs/_features/eip7549/fork.md @@ -0,0 +1,141 @@ +# EIP-7549 -- Fork Logic + +**Notice**: This document is a work-in-progress for researchers and implementers. + +## Table of contents + + + + +- [Introduction](#introduction) +- [Configuration](#configuration) +- [Helper functions](#helper-functions) + - [Misc](#misc) + - [Modified `compute_fork_version`](#modified-compute_fork_version) +- [Fork to EIP-7549](#fork-to-eip-7549) + - [Fork trigger](#fork-trigger) + - [Upgrading the state](#upgrading-the-state) + + + +## Introduction + +This document describes the process of EIP-7549 upgrade. + +## Configuration + +Warning: this configuration is not definitive. + +| Name | Value | +| - | - | +| `EIP7549_FORK_VERSION` | `Version('0x06000000')` | +| `EIP7549_FORK_EPOCH` | `Epoch(18446744073709551615)` **TBD** | + +## Helper functions + +### Misc + +#### Modified `compute_fork_version` + +```python +def compute_fork_version(epoch: Epoch) -> Version: + """ + Return the fork version at the given ``epoch``. + """ + if epoch >= EIP7549_FORK_EPOCH: + return EIP7549_FORK_VERSION + if epoch >= DENEB_FORK_EPOCH: + return DENEB_FORK_VERSION + if epoch >= CAPELLA_FORK_EPOCH: + return CAPELLA_FORK_VERSION + if epoch >= BELLATRIX_FORK_EPOCH: + return BELLATRIX_FORK_VERSION + if epoch >= ALTAIR_FORK_EPOCH: + return ALTAIR_FORK_VERSION + return GENESIS_FORK_VERSION +``` + +## Fork to EIP-7549 + +### Fork trigger + +TBD. This fork is defined for testing purposes, the EIP may be combined with other consensus-layer upgrade. +For now, we assume the condition will be triggered at epoch `EIP7549_FORK_EPOCH`. + +Note that for the pure EIP-7549 networks, we don't apply `upgrade_to_eip7549` since it starts with EIP-7549 version logic. + +### Upgrading the state + +If `state.slot % SLOTS_PER_EPOCH == 0` and `compute_epoch_at_slot(state.slot) == EIP7549_FORK_EPOCH`, +an irregular state change is made to upgrade to EIP-7549. + +```python +def upgrade_to_eip7549(pre: capella.BeaconState) -> BeaconState: + epoch = capella.get_current_epoch(pre) + latest_execution_payload_header = ExecutionPayloadHeader( + parent_hash=pre.latest_execution_payload_header.parent_hash, + fee_recipient=pre.latest_execution_payload_header.fee_recipient, + state_root=pre.latest_execution_payload_header.state_root, + receipts_root=pre.latest_execution_payload_header.receipts_root, + logs_bloom=pre.latest_execution_payload_header.logs_bloom, + prev_randao=pre.latest_execution_payload_header.prev_randao, + block_number=pre.latest_execution_payload_header.block_number, + gas_limit=pre.latest_execution_payload_header.gas_limit, + gas_used=pre.latest_execution_payload_header.gas_used, + timestamp=pre.latest_execution_payload_header.timestamp, + extra_data=pre.latest_execution_payload_header.extra_data, + base_fee_per_gas=pre.latest_execution_payload_header.base_fee_per_gas, + block_hash=pre.latest_execution_payload_header.block_hash, + transactions_root=pre.latest_execution_payload_header.transactions_root, + withdrawals_root=pre.latest_execution_payload_header.withdrawals_root, + ) + post = BeaconState( + # Versioning + genesis_time=pre.genesis_time, + genesis_validators_root=pre.genesis_validators_root, + slot=pre.slot, + fork=Fork( + previous_version=pre.fork.current_version, + current_version=EIP7549_FORK_VERSION, # [Modified in EIP-7549] + epoch=epoch, + ), + # History + latest_block_header=pre.latest_block_header, + block_roots=pre.block_roots, + state_roots=pre.state_roots, + historical_roots=pre.historical_roots, + # Eth1 + eth1_data=pre.eth1_data, + eth1_data_votes=pre.eth1_data_votes, + eth1_deposit_index=pre.eth1_deposit_index, + # Registry + validators=pre.validators, + balances=pre.balances, + # Randomness + randao_mixes=pre.randao_mixes, + # Slashings + slashings=pre.slashings, + # Participation + previous_epoch_participation=pre.previous_epoch_participation, + current_epoch_participation=pre.current_epoch_participation, + # Finality + justification_bits=pre.justification_bits, + previous_justified_checkpoint=pre.previous_justified_checkpoint, + current_justified_checkpoint=pre.current_justified_checkpoint, + finalized_checkpoint=pre.finalized_checkpoint, + # Inactivity + inactivity_scores=pre.inactivity_scores, + # Sync + current_sync_committee=pre.current_sync_committee, + next_sync_committee=pre.next_sync_committee, + # Execution-layer + latest_execution_payload_header=latest_execution_payload_header, + # Withdrawals + next_withdrawal_index=pre.next_withdrawal_index, + next_withdrawal_validator_index=pre.next_withdrawal_validator_index, + # Deep history valid from Capella onwards + historical_summaries=pre.historical_summaries, + ) + + return post +``` diff --git a/specs/_features/eip7549/validator.md b/specs/_features/eip7549/validator.md index 98310bc6fd..d904e23f92 100644 --- a/specs/_features/eip7549/validator.md +++ b/specs/_features/eip7549/validator.md @@ -9,6 +9,7 @@ - [Modifications in EIP-7549](#modifications-in-eip-7549) - [Block proposal](#block-proposal) - [Constructing the `BeaconBlockBody`](#constructing-the-beaconblockbody) + - [Attester slashings](#attester-slashings) - [Attestations](#attestations) - [Attesting](#attesting) - [Construct attestation](#construct-attestation) @@ -24,6 +25,10 @@ #### Constructing the `BeaconBlockBody` +##### Attester slashings + +Changed the max attestations size to `MAX_ATTESTER_SLASHINGS_EIP7549`. + ##### Attestations The network attestation aggregates contain only the assigned committee attestations. @@ -31,7 +36,7 @@ Attestation aggregates received by the block proposer from the committee aggrega The proposer should run the following function to construct an on chain final aggregate form a list of network aggregates with equal `AttestationData`: ```python -def compute_on_chain_aggregate(network_aggregates: List[Attestation]) -> Attestation: +def compute_on_chain_aggregate(network_aggregates: Sequence[Attestation]) -> Attestation: aggregates = sorted(network_aggregates, key=lambda a: get_committee_indices(a.committee_bits)[0]) data = aggregates[0].data diff --git a/tests/core/pyspec/eth2spec/test/context.py b/tests/core/pyspec/eth2spec/test/context.py index 687b372bce..64d3635789 100644 --- a/tests/core/pyspec/eth2spec/test/context.py +++ b/tests/core/pyspec/eth2spec/test/context.py @@ -8,8 +8,8 @@ from .exceptions import SkippedTest from .helpers.constants import ( PHASE0, ALTAIR, BELLATRIX, CAPELLA, DENEB, - EIP6110, EIP7002, EIP7594, - WHISK, EIP7251, + EIP6110, EIP7002, EIP7251, EIP7549, EIP7594, + WHISK, MINIMAL, ALL_PHASES, POST_FORK_OF, @@ -521,6 +521,7 @@ def wrapper(*args, spec: Spec, **kw): with_deneb_and_later = with_all_phases_from(DENEB) with_eip6110_and_later = with_all_phases_from(EIP6110) with_eip7002_and_later = with_all_phases_from(EIP7002) +with_eip7549_and_later = with_all_phases_from(EIP7549) with_whisk_and_later = with_all_phases_from(WHISK, all_phases=ALLOWED_TEST_RUNNER_FORKS) with_eip7594_and_later = with_all_phases_from(EIP7594, all_phases=ALLOWED_TEST_RUNNER_FORKS) with_eip7251_and_later = with_all_phases_from(EIP7251, all_phases=ALLOWED_TEST_RUNNER_FORKS) diff --git a/tests/core/pyspec/eth2spec/test/helpers/attestations.py b/tests/core/pyspec/eth2spec/test/helpers/attestations.py index 9e549a74bf..528de7f67c 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/attestations.py +++ b/tests/core/pyspec/eth2spec/test/helpers/attestations.py @@ -5,7 +5,7 @@ from eth2spec.test.context import expect_assertion_error from eth2spec.test.helpers.state import state_transition_and_sign_block, next_epoch, next_slot from eth2spec.test.helpers.block import build_empty_block_for_next_slot -from eth2spec.test.helpers.forks import is_post_altair, is_post_deneb +from eth2spec.test.helpers.forks import is_post_altair, is_post_deneb, is_post_eip7549 from eth2spec.test.helpers.keys import privkeys from eth2spec.utils import bls from eth2spec.utils.ssz.ssz_typing import Bitlist @@ -78,7 +78,7 @@ def build_attestation_data(spec, state, slot, index, beacon_block_root=None, sha data = spec.AttestationData( slot=slot, - index=index, + index=0 if is_post_eip7549(spec) else index, beacon_block_root=beacon_block_root, source=spec.Checkpoint(epoch=source_epoch, root=source_root), target=spec.Checkpoint(epoch=spec.compute_epoch_at_slot(slot), root=epoch_boundary_root), @@ -106,14 +106,19 @@ def get_valid_attestation(spec, beacon_committee = spec.get_beacon_committee(state, slot, index) - committee_size = len(beacon_committee) - aggregation_bits = Bitlist[spec.MAX_VALIDATORS_PER_COMMITTEE](*([0] * committee_size)) - attestation = spec.Attestation( - aggregation_bits=aggregation_bits, - data=attestation_data, - ) + if is_post_eip7549(spec): + # will fill aggregation_bits later + attestation = spec.Attestation(data=attestation_data) + else: + committee_size = len(beacon_committee) + aggregation_bits = Bitlist[spec.MAX_VALIDATORS_PER_COMMITTEE](*([0] * committee_size)) + attestation = spec.Attestation( + aggregation_bits=aggregation_bits, + data=attestation_data, + ) # fill the attestation with (optionally filtered) participants, and optionally sign it - fill_aggregate_attestation(spec, state, attestation, signed=signed, filter_participant_set=filter_participant_set) + fill_aggregate_attestation(spec, state, attestation, signed=signed, + filter_participant_set=filter_participant_set, committee_index=index) return attestation @@ -159,7 +164,7 @@ def compute_max_inclusion_slot(spec, attestation): return attestation.data.slot + spec.SLOTS_PER_EPOCH -def fill_aggregate_attestation(spec, state, attestation, signed=False, filter_participant_set=None): +def fill_aggregate_attestation(spec, state, attestation, committee_index, signed=False, filter_participant_set=None): """ `signed`: Signing is optional. `filter_participant_set`: Optional, filters the full committee indices set (default) to a subset that participates @@ -167,15 +172,27 @@ def fill_aggregate_attestation(spec, state, attestation, signed=False, filter_pa beacon_committee = spec.get_beacon_committee( state, attestation.data.slot, - attestation.data.index, + committee_index, ) # By default, have everyone participate participants = set(beacon_committee) # But optionally filter the participants to a smaller amount if filter_participant_set is not None: participants = filter_participant_set(participants) + + if is_post_eip7549(spec): + attestation.committee_bits = spec.Bitvector[spec.MAX_COMMITTEES_PER_SLOT]() + attestation.committee_bits[committee_index] = True + attestation.aggregation_bits = get_empty_eip7549_aggregation_bits( + spec, state, attestation.committee_bits, attestation.data.slot) for i in range(len(beacon_committee)): - attestation.aggregation_bits[i] = beacon_committee[i] in participants + if is_post_eip7549(spec): + offset = get_eip7549_aggregation_bits_offset( + spec, state, attestation.data.slot, attestation.committee_bits, committee_index) + aggregation_bits_index = offset + i + attestation.aggregation_bits[aggregation_bits_index] = beacon_committee[i] in participants + else: + attestation.aggregation_bits[i] = beacon_committee[i] in participants if signed and len(participants) > 0: sign_attestation(spec, state, attestation) @@ -384,3 +401,34 @@ def cached_prepare_state_with_attestations(spec, state): # Put the LRU cache result into the state view, as if we transitioned the original view state.set_backing(_prep_state_cache_dict[key]) + + +def get_max_attestations(spec): + if is_post_eip7549(spec): + return spec.MAX_ATTESTATIONS_EIP7549 + else: + return spec.MAX_ATTESTATIONS + + +def get_empty_eip7549_aggregation_bits(spec, state, committee_bits, slot): + committee_indices = spec.get_committee_indices(committee_bits) + participants_count = 0 + for index in committee_indices: + committee = spec.get_beacon_committee(state, slot, index) + participants_count += len(committee) + aggregation_bits = Bitlist[spec.MAX_VALIDATORS_PER_COMMITTEE * spec.MAX_COMMITTEES_PER_SLOT]( + [False] * participants_count + ) + return aggregation_bits + + +def get_eip7549_aggregation_bits_offset(spec, state, slot, committee_bits, committee_index): + committee_indices = spec.get_committee_indices(committee_bits) + assert committee_index in committee_indices + offset = 0 + for i in committee_indices: + if committee_index == i: + break + committee = spec.get_beacon_committee(state, slot, committee_indices[i]) + offset += len(committee) + return offset diff --git a/tests/core/pyspec/eth2spec/test/helpers/attester_slashings.py b/tests/core/pyspec/eth2spec/test/helpers/attester_slashings.py index 06e904805c..bdda3bf766 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/attester_slashings.py +++ b/tests/core/pyspec/eth2spec/test/helpers/attester_slashings.py @@ -1,4 +1,5 @@ from eth2spec.test.helpers.attestations import get_valid_attestation, sign_attestation, sign_indexed_attestation +from eth2spec.test.helpers.forks import is_post_eip7549 def get_valid_attester_slashing(spec, state, slot=None, signed_1=False, signed_2=False, filter_participant_set=None): @@ -62,3 +63,10 @@ def get_attestation_1_data(spec, att_slashing): def get_attestation_2_data(spec, att_slashing): return att_slashing.attestation_2.data + + +def get_max_attester_slashings(spec): + if is_post_eip7549(spec): + return spec.MAX_ATTESTER_SLASHINGS_EIP7549 + else: + return spec.MAX_ATTESTER_SLASHINGS diff --git a/tests/core/pyspec/eth2spec/test/helpers/constants.py b/tests/core/pyspec/eth2spec/test/helpers/constants.py index 46323278d5..b482b3a027 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/constants.py +++ b/tests/core/pyspec/eth2spec/test/helpers/constants.py @@ -18,6 +18,7 @@ DAS = SpecForkName('das') EIP6110 = SpecForkName('eip6110') EIP7002 = SpecForkName('eip7002') +EIP7549 = SpecForkName('eip7549') WHISK = SpecForkName('whisk') EIP7251 = SpecForkName('eip7251') EIP7594 = SpecForkName('eip7594') @@ -40,6 +41,7 @@ EIP6110, EIP7002, EIP7251, + EIP7549, EIP7594, ) # The forks that have light client specs @@ -61,6 +63,7 @@ EIP6110: DENEB, WHISK: CAPELLA, EIP7002: CAPELLA, + EIP7549: DENEB, EIP7251: DENEB, EIP7594: DENEB, } diff --git a/tests/core/pyspec/eth2spec/test/helpers/forks.py b/tests/core/pyspec/eth2spec/test/helpers/forks.py index 114d13b906..8b03c8fb79 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/forks.py +++ b/tests/core/pyspec/eth2spec/test/helpers/forks.py @@ -1,6 +1,6 @@ from .constants import ( PHASE0, ALTAIR, BELLATRIX, CAPELLA, DENEB, - EIP6110, EIP7002, WHISK, EIP7251, + EIP6110, EIP7002, EIP7251, EIP7549, WHISK, PREVIOUS_FORK_OF, ) @@ -49,6 +49,10 @@ def is_post_eip7251(spec): return is_post_fork(spec.fork, EIP7251) +def is_post_eip7549(spec): + return is_post_fork(spec.fork, EIP7549) + + def is_post_whisk(spec): return is_post_fork(spec.fork, WHISK) diff --git a/tests/core/pyspec/eth2spec/test/helpers/multi_operations.py b/tests/core/pyspec/eth2spec/test/helpers/multi_operations.py index c11bb55842..9943fcdd45 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/multi_operations.py +++ b/tests/core/pyspec/eth2spec/test/helpers/multi_operations.py @@ -13,7 +13,7 @@ ) from eth2spec.test.helpers.proposer_slashings import get_valid_proposer_slashing from eth2spec.test.helpers.attester_slashings import get_valid_attester_slashing_by_indices -from eth2spec.test.helpers.attestations import get_valid_attestation +from eth2spec.test.helpers.attestations import get_valid_attestation, get_max_attestations from eth2spec.test.helpers.deposits import build_deposit, deposit_from_context from eth2spec.test.helpers.voluntary_exits import prepare_signed_exits from eth2spec.test.helpers.bls_to_execution_changes import get_signed_address_change @@ -101,7 +101,7 @@ def get_random_attester_slashings(spec, state, rng, slashed_indices=[]): def get_random_attestations(spec, state, rng): - num_attestations = rng.randrange(1, spec.MAX_ATTESTATIONS) + num_attestations = rng.randrange(1, get_max_attestations(spec)) attestations = [ get_valid_attestation( diff --git a/tests/core/pyspec/eth2spec/test/phase0/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/phase0/sanity/test_blocks.py index d31955e827..e15c3a8f66 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/sanity/test_blocks.py +++ b/tests/core/pyspec/eth2spec/test/phase0/sanity/test_blocks.py @@ -15,6 +15,7 @@ get_valid_attester_slashing_by_indices, get_valid_attester_slashing, get_indexed_attestation_participants, + get_max_attester_slashings, ) from eth2spec.test.helpers.proposer_slashings import get_valid_proposer_slashing, check_proposer_slashing_effect from eth2spec.test.helpers.attestations import get_valid_attestation @@ -30,7 +31,11 @@ compute_sync_committee_participant_reward_and_penalty, ) from eth2spec.test.helpers.constants import PHASE0, MINIMAL -from eth2spec.test.helpers.forks import is_post_altair, is_post_bellatrix, is_post_capella +from eth2spec.test.helpers.forks import ( + is_post_altair, + is_post_bellatrix, + is_post_capella, +) from eth2spec.test.context import ( spec_test, spec_state_test, dump_skipping_message, with_phases, with_all_phases, single_phase, @@ -550,7 +555,7 @@ def test_attester_slashing(spec, state): @with_all_phases @spec_state_test def test_invalid_duplicate_attester_slashing_same_block(spec, state): - if spec.MAX_ATTESTER_SLASHINGS < 2: + if get_max_attester_slashings(spec) < 2: return dump_skipping_message("Skip test if config cannot handle multiple AttesterSlashings per block") attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True) @@ -578,7 +583,7 @@ def test_invalid_duplicate_attester_slashing_same_block(spec, state): @with_all_phases @spec_state_test def test_multiple_attester_slashings_no_overlap(spec, state): - if spec.MAX_ATTESTER_SLASHINGS < 2: + if get_max_attester_slashings(spec) < 2: return dump_skipping_message("Skip test if config cannot handle multiple AttesterSlashings per block") # copy for later balance lookups. @@ -618,7 +623,7 @@ def test_multiple_attester_slashings_no_overlap(spec, state): @with_all_phases @spec_state_test def test_multiple_attester_slashings_partial_overlap(spec, state): - if spec.MAX_ATTESTER_SLASHINGS < 2: + if get_max_attester_slashings(spec) < 2: return dump_skipping_message("Skip test if config cannot handle multiple AttesterSlashings per block") # copy for later balance lookups. diff --git a/tests/core/pyspec/eth2spec/test/phase0/unittests/fork_choice/test_on_attestation.py b/tests/core/pyspec/eth2spec/test/phase0/unittests/fork_choice/test_on_attestation.py index 6e545cef79..128c6bd704 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/unittests/fork_choice/test_on_attestation.py +++ b/tests/core/pyspec/eth2spec/test/phase0/unittests/fork_choice/test_on_attestation.py @@ -2,6 +2,7 @@ from eth2spec.test.helpers.block import build_empty_block_for_next_slot from eth2spec.test.helpers.attestations import get_valid_attestation, sign_attestation from eth2spec.test.helpers.constants import ALL_PHASES +from eth2spec.test.helpers.forks import is_post_eip7549 from eth2spec.test.helpers.state import transition_to, state_transition_and_sign_block, next_epoch, next_slot from eth2spec.test.helpers.fork_choice import get_genesis_forkchoice_store @@ -325,6 +326,9 @@ def test_on_attestation_invalid_attestation(spec, state): attestation = get_valid_attestation(spec, state, slot=block.slot, signed=True) # make invalid by using an invalid committee index - attestation.data.index = spec.MAX_COMMITTEES_PER_SLOT * spec.SLOTS_PER_EPOCH + if is_post_eip7549(spec): + attestation.committee_bits = spec.Bitvector[spec.MAX_COMMITTEES_PER_SLOT]() + else: + attestation.data.index = spec.MAX_COMMITTEES_PER_SLOT * spec.SLOTS_PER_EPOCH run_on_attestation(spec, state, store, attestation, False)