Merge branch 'dev' into ci-phasesconfig

This commit is contained in:
Etan Kissling 2022-12-13 15:33:07 +01:00
commit 74883fec7c
No known key found for this signature in database
GPG Key ID: B21DA824C5A3D03D
40 changed files with 780 additions and 501 deletions

View File

@ -10,3 +10,8 @@ MAX_BLS_TO_EXECUTION_CHANGES: 16
# --------------------------------------------------------------- # ---------------------------------------------------------------
# 2**4 (= 16) withdrawals # 2**4 (= 16) withdrawals
MAX_WITHDRAWALS_PER_PAYLOAD: 16 MAX_WITHDRAWALS_PER_PAYLOAD: 16
# Withdrawals processing
# ---------------------------------------------------------------
# 2**14 (= 16384) validators
MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP: 16384

View File

@ -4,5 +4,5 @@
# --------------------------------------------------------------- # ---------------------------------------------------------------
# `uint64(4096)` # `uint64(4096)`
FIELD_ELEMENTS_PER_BLOB: 4096 FIELD_ELEMENTS_PER_BLOB: 4096
# `uint64(2**4)` (= 16) # `uint64(2**2)` (= 4)
MAX_BLOBS_PER_BLOCK: 16 MAX_BLOBS_PER_BLOCK: 4

View File

@ -10,3 +10,8 @@ MAX_BLS_TO_EXECUTION_CHANGES: 16
# --------------------------------------------------------------- # ---------------------------------------------------------------
# [customized] 2**2 (= 4) # [customized] 2**2 (= 4)
MAX_WITHDRAWALS_PER_PAYLOAD: 4 MAX_WITHDRAWALS_PER_PAYLOAD: 4
# Withdrawals processing
# ---------------------------------------------------------------
# [customized] 2**4 (= 16) validators
MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP: 16

View File

@ -4,5 +4,5 @@
# --------------------------------------------------------------- # ---------------------------------------------------------------
# [customized] # [customized]
FIELD_ELEMENTS_PER_BLOB: 4 FIELD_ELEMENTS_PER_BLOB: 4
# `uint64(2**4)` (= 16) # `uint64(2**2)` (= 4)
MAX_BLOBS_PER_BLOCK: 16 MAX_BLOBS_PER_BLOCK: 4

View File

@ -1173,6 +1173,7 @@ setup(
"py_ecc==6.0.0", "py_ecc==6.0.0",
"milagro_bls_binding==1.9.0", "milagro_bls_binding==1.9.0",
"remerkleable==0.1.25", "remerkleable==0.1.25",
"trie==2.0.2",
RUAMEL_YAML_VERSION, RUAMEL_YAML_VERSION,
"lru-dict==1.1.8", "lru-dict==1.1.8",
MARKO_VERSION, MARKO_VERSION,

View File

@ -523,6 +523,7 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None:
if bls.Verify(pubkey, signing_root, deposit.data.signature): if bls.Verify(pubkey, signing_root, deposit.data.signature):
state.validators.append(get_validator_from_deposit(deposit)) state.validators.append(get_validator_from_deposit(deposit))
state.balances.append(amount) state.balances.append(amount)
# [New in Altair]
state.previous_epoch_participation.append(ParticipationFlags(0b0000_0000)) state.previous_epoch_participation.append(ParticipationFlags(0b0000_0000))
state.current_epoch_participation.append(ParticipationFlags(0b0000_0000)) state.current_epoch_participation.append(ParticipationFlags(0b0000_0000))
state.inactivity_scores.append(uint64(0)) state.inactivity_scores.append(uint64(0))

View File

@ -8,11 +8,11 @@
- [Introduction](#introduction) - [Introduction](#introduction)
- [Custom types](#custom-types) - [Custom types](#custom-types)
- [Constants](#constants)
- [Domain types](#domain-types) - [Domain types](#domain-types)
- [Preset](#preset) - [Preset](#preset)
- [Max operations per block](#max-operations-per-block) - [Max operations per block](#max-operations-per-block)
- [Execution](#execution) - [Execution](#execution)
- [Withdrawals processing](#withdrawals-processing)
- [Containers](#containers) - [Containers](#containers)
- [New containers](#new-containers) - [New containers](#new-containers)
- [`Withdrawal`](#withdrawal) - [`Withdrawal`](#withdrawal)
@ -58,8 +58,6 @@ We define the following Python custom types for type hinting and readability:
| - | - | - | | - | - | - |
| `WithdrawalIndex` | `uint64` | an index of a `Withdrawal` | | `WithdrawalIndex` | `uint64` | an index of a `Withdrawal` |
## Constants
### Domain types ### Domain types
| Name | Value | | Name | Value |
@ -80,6 +78,12 @@ We define the following Python custom types for type hinting and readability:
| - | - | - | | - | - | - |
| `MAX_WITHDRAWALS_PER_PAYLOAD` | `uint64(2**4)` (= 16) | Maximum amount of withdrawals allowed in each payload | | `MAX_WITHDRAWALS_PER_PAYLOAD` | `uint64(2**4)` (= 16) | Maximum amount of withdrawals allowed in each payload |
### Withdrawals processing
| Name | Value |
| - | - |
| `MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP` | `16384` (= 2**14 ) |
## Containers ## Containers
### New containers ### New containers
@ -288,7 +292,8 @@ def get_expected_withdrawals(state: BeaconState) -> Sequence[Withdrawal]:
withdrawal_index = state.next_withdrawal_index withdrawal_index = state.next_withdrawal_index
validator_index = state.next_withdrawal_validator_index validator_index = state.next_withdrawal_validator_index
withdrawals: List[Withdrawal] = [] withdrawals: List[Withdrawal] = []
for _ in range(len(state.validators)): bound = min(len(state.validators), MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP)
for _ in range(bound):
validator = state.validators[validator_index] validator = state.validators[validator_index]
balance = state.balances[validator_index] balance = state.balances[validator_index]
if is_fully_withdrawable_validator(validator, balance, epoch): if is_fully_withdrawable_validator(validator, balance, epoch):
@ -312,7 +317,7 @@ def get_expected_withdrawals(state: BeaconState) -> Sequence[Withdrawal]:
validator_index = ValidatorIndex((validator_index + 1) % len(state.validators)) validator_index = ValidatorIndex((validator_index + 1) % len(state.validators))
return withdrawals return withdrawals
``` ```
#### New `process_withdrawals` #### New `process_withdrawals`
```python ```python
@ -323,10 +328,21 @@ def process_withdrawals(state: BeaconState, payload: ExecutionPayload) -> None:
for expected_withdrawal, withdrawal in zip(expected_withdrawals, payload.withdrawals): for expected_withdrawal, withdrawal in zip(expected_withdrawals, payload.withdrawals):
assert withdrawal == expected_withdrawal assert withdrawal == expected_withdrawal
decrease_balance(state, withdrawal.validator_index, withdrawal.amount) decrease_balance(state, withdrawal.validator_index, withdrawal.amount)
if len(expected_withdrawals) > 0:
# Update the next withdrawal index if this block contained withdrawals
if len(expected_withdrawals) != 0:
latest_withdrawal = expected_withdrawals[-1] latest_withdrawal = expected_withdrawals[-1]
state.next_withdrawal_index = WithdrawalIndex(latest_withdrawal.index + 1) state.next_withdrawal_index = WithdrawalIndex(latest_withdrawal.index + 1)
next_validator_index = ValidatorIndex((latest_withdrawal.validator_index + 1) % len(state.validators))
# Update the next validator index to start the next withdrawal sweep
if len(expected_withdrawals) == MAX_WITHDRAWALS_PER_PAYLOAD:
# Next sweep starts after the latest withdrawal's validator index
next_validator_index = ValidatorIndex((expected_withdrawals[-1].validator_index + 1) % len(state.validators))
state.next_withdrawal_validator_index = next_validator_index
else:
# Advance sweep by the max length of the sweep if there was not a full set of withdrawals
next_index = state.next_withdrawal_validator_index + MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP
next_validator_index = ValidatorIndex(next_index % len(state.validators))
state.next_withdrawal_validator_index = next_validator_index state.next_withdrawal_validator_index = next_validator_index
``` ```

View File

@ -63,7 +63,7 @@ This upgrade adds blobs to the beacon chain as part of EIP-4844. This is an exte
| Name | Value | | Name | Value |
| - | - | | - | - |
| `MAX_BLOBS_PER_BLOCK` | `uint64(2**4)` (= 16) | | `MAX_BLOBS_PER_BLOCK` | `uint64(2**2)` (= 4) |
## Configuration ## Configuration
@ -168,8 +168,7 @@ The implementation of `is_data_available` is meant to change with later sharding
Initially, it requires every verifying actor to retrieve the matching `BlobsSidecar`, Initially, it requires every verifying actor to retrieve the matching `BlobsSidecar`,
and validate the sidecar with `validate_blobs_sidecar`. and validate the sidecar with `validate_blobs_sidecar`.
Without the sidecar the block may be processed further optimistically, The block MUST NOT be considered valid until a valid `BlobsSidecar` has been downloaded.
but MUST NOT be considered valid until a valid `BlobsSidecar` has been downloaded.
```python ```python
def is_data_available(slot: Slot, beacon_block_root: Root, blob_kzg_commitments: Sequence[KZGCommitment]) -> bool: def is_data_available(slot: Slot, beacon_block_root: Root, blob_kzg_commitments: Sequence[KZGCommitment]) -> bool:
@ -242,7 +241,7 @@ def process_block(state: BeaconState, block: BeaconBlock) -> None:
process_sync_aggregate(state, block.body.sync_aggregate) process_sync_aggregate(state, block.body.sync_aggregate)
process_blob_kzg_commitments(state, block.body) # [New in EIP-4844] process_blob_kzg_commitments(state, block.body) # [New in EIP-4844]
# New in EIP-4844, note: Can sync optimistically without this condition, see note on `is_data_available` # New in EIP-4844
assert is_data_available(block.slot, hash_tree_root(block), block.body.blob_kzg_commitments) assert is_data_available(block.slot, hash_tree_root(block), block.body.blob_kzg_commitments)
``` ```

View File

@ -230,7 +230,7 @@ Clients MUST keep a record of signed blobs sidecars seen on the epoch range
where `current_epoch` is defined by the current wall-clock time, where `current_epoch` is defined by the current wall-clock time,
and clients MUST support serving requests of blocks on this range. and clients MUST support serving requests of blocks on this range.
Peers that are unable to reply to block requests within the `MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS` Peers that are unable to reply to blobs sidecars requests within the `MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS`
epoch range SHOULD respond with error code `3: ResourceUnavailable`. epoch range SHOULD respond with error code `3: ResourceUnavailable`.
Such peers that are unable to successfully reply to this range of requests MAY get descored Such peers that are unable to successfully reply to this range of requests MAY get descored
or disconnected at any time. or disconnected at any time.

View File

@ -0,0 +1,41 @@
from eth2spec.test.context import (
spec_state_test,
always_bls,
with_phases,
with_altair_and_later,
)
from eth2spec.test.helpers.constants import (
ALTAIR,
)
from eth2spec.test.helpers.deposits import (
run_deposit_processing_with_specific_fork_version,
)
@with_phases([ALTAIR])
@spec_state_test
@always_bls
def test_effective_deposit_with_previous_fork_version(spec, state):
assert state.fork.previous_version != state.fork.current_version
# It's only effective in Altair because the default `fork_version` of `compute_domain` is `GENESIS_FORK_VERSION`.
# Therefore it's just a normal `DepositMessage`.
yield from run_deposit_processing_with_specific_fork_version(
spec,
state,
fork_version=state.fork.previous_version,
)
@with_altair_and_later
@spec_state_test
@always_bls
def test_ineffective_deposit_with_current_fork_version(spec, state):
yield from run_deposit_processing_with_specific_fork_version(
spec,
state,
fork_version=state.fork.current_version,
effective=False,
)

View File

@ -110,7 +110,7 @@ def test_sync_committees_progress_misc_balances_not_genesis(spec, state):
@spec_state_test @spec_state_test
@always_bls @always_bls
@with_presets([MINIMAL], reason="too slow") @with_presets([MINIMAL], reason="too slow")
def test_sync_committees_no_progress_not_boundary(spec, state): def test_sync_committees_no_progress_not_at_period_boundary(spec, state):
assert spec.get_current_epoch(state) == spec.GENESIS_EPOCH assert spec.get_current_epoch(state) == spec.GENESIS_EPOCH
slot_not_at_period_boundary = state.slot + spec.SLOTS_PER_EPOCH slot_not_at_period_boundary = state.slot + spec.SLOTS_PER_EPOCH
transition_to(spec, state, slot_not_at_period_boundary) transition_to(spec, state, slot_not_at_period_boundary)

View File

@ -51,40 +51,40 @@ def run_sync_committee_sanity_test(spec, state, fraction_full=1.0, rng=Random(45
@with_altair_and_later @with_altair_and_later
@spec_state_test @spec_state_test
def test_full_sync_committee_committee(spec, state): def test_sync_committee_committee__full(spec, state):
next_epoch(spec, state) next_epoch(spec, state)
yield from run_sync_committee_sanity_test(spec, state, fraction_full=1.0) yield from run_sync_committee_sanity_test(spec, state, fraction_full=1.0)
@with_altair_and_later @with_altair_and_later
@spec_state_test @spec_state_test
def test_half_sync_committee_committee(spec, state): def test_sync_committee_committee__half(spec, state):
next_epoch(spec, state) next_epoch(spec, state)
yield from run_sync_committee_sanity_test(spec, state, fraction_full=0.5, rng=Random(1212)) yield from run_sync_committee_sanity_test(spec, state, fraction_full=0.5, rng=Random(1212))
@with_altair_and_later @with_altair_and_later
@spec_state_test @spec_state_test
def test_empty_sync_committee_committee(spec, state): def test_sync_committee_committee__empty(spec, state):
next_epoch(spec, state) next_epoch(spec, state)
yield from run_sync_committee_sanity_test(spec, state, fraction_full=0.0) yield from run_sync_committee_sanity_test(spec, state, fraction_full=0.0)
@with_altair_and_later @with_altair_and_later
@spec_state_test @spec_state_test
def test_full_sync_committee_committee_genesis(spec, state): def test_sync_committee_committee_genesis__full(spec, state):
yield from run_sync_committee_sanity_test(spec, state, fraction_full=1.0) yield from run_sync_committee_sanity_test(spec, state, fraction_full=1.0)
@with_altair_and_later @with_altair_and_later
@spec_state_test @spec_state_test
def test_half_sync_committee_committee_genesis(spec, state): def test_sync_committee_committee_genesis__half(spec, state):
yield from run_sync_committee_sanity_test(spec, state, fraction_full=0.5, rng=Random(2323)) yield from run_sync_committee_sanity_test(spec, state, fraction_full=0.5, rng=Random(2323))
@with_altair_and_later @with_altair_and_later
@spec_state_test @spec_state_test
def test_empty_sync_committee_committee_genesis(spec, state): def test_sync_committee_committee_genesis__empty(spec, state):
yield from run_sync_committee_sanity_test(spec, state, fraction_full=0.0) yield from run_sync_committee_sanity_test(spec, state, fraction_full=0.0)

View File

@ -8,10 +8,11 @@ from eth2spec.test.context import (
with_phases, with_phases,
with_state, with_state,
) )
from eth2spec.test.helpers.constants import ALTAIR, BELLATRIX from eth2spec.test.helpers.constants import (
from eth2spec.test.helpers.forks import ( PHASE0, ALTAIR, BELLATRIX,
is_post_capella, is_post_eip4844, ALL_PHASES,
) )
from eth2spec.test.helpers.forks import is_post_fork
@with_phases([ALTAIR]) @with_phases([ALTAIR])
@ -34,32 +35,31 @@ def test_config_override(spec, state):
@with_all_phases @with_all_phases
@spec_state_test_with_matching_config @spec_state_test_with_matching_config
def test_config_override_matching_fork_epochs(spec, state): def test_config_override_matching_fork_epochs(spec, state):
if state.fork.current_version == spec.config.GENESIS_FORK_VERSION: # Fork schedule must be consistent with state fork
return epoch = spec.get_current_epoch(state)
if is_post_fork(spec.fork, ALTAIR):
assert state.fork.current_version == spec.compute_fork_version(epoch)
else:
assert state.fork.current_version == spec.config.GENESIS_FORK_VERSION
assert spec.config.ALTAIR_FORK_EPOCH == spec.GENESIS_EPOCH # Identify state fork
if state.fork.current_version == spec.config.ALTAIR_FORK_VERSION: state_fork = None
return for fork in [fork for fork in ALL_PHASES if is_post_fork(spec.fork, fork)]:
if fork == PHASE0:
fork_version_field = 'GENESIS_FORK_VERSION'
else:
fork_version_field = fork.upper() + '_FORK_VERSION'
if state.fork.current_version == getattr(spec.config, fork_version_field):
state_fork = fork
break
assert state_fork is not None
assert spec.config.BELLATRIX_FORK_EPOCH == spec.GENESIS_EPOCH # Check that all prior forks have already been triggered
if state.fork.current_version == spec.config.BELLATRIX_FORK_VERSION: for fork in [fork for fork in ALL_PHASES if is_post_fork(state_fork, fork)]:
return if fork == PHASE0:
continue
if is_post_capella(spec): fork_epoch_field = fork.upper() + '_FORK_EPOCH'
assert spec.config.CAPELLA_FORK_EPOCH == spec.GENESIS_EPOCH assert getattr(spec.config, fork_epoch_field) <= epoch
if state.fork.current_version == spec.config.CAPELLA_FORK_VERSION:
return
if is_post_eip4844(spec):
assert spec.config.EIP4844_FORK_EPOCH == spec.GENESIS_EPOCH
if state.fork.current_version == spec.config.EIP4844_FORK_VERSION:
return
assert spec.config.SHARDING_FORK_EPOCH == spec.GENESIS_EPOCH
if state.fork.current_version == spec.config.SHARDING_FORK_VERSION:
return
assert False # Fork is missing
@with_phases(phases=[ALTAIR], other_phases=[BELLATRIX]) @with_phases(phases=[ALTAIR], other_phases=[BELLATRIX])

View File

@ -4,55 +4,23 @@ from eth2spec.test.context import (
with_bellatrix_and_later, with_bellatrix_and_later,
) )
from eth2spec.test.helpers.deposits import ( from eth2spec.test.helpers.deposits import (
deposit_from_context, run_deposit_processing_with_specific_fork_version,
run_deposit_processing,
) )
from eth2spec.test.helpers.keys import (
privkeys,
pubkeys,
)
from eth2spec.utils import bls
def _run_deposit_processing_with_specific_fork_version(
spec,
state,
fork_version,
valid,
effective):
validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE
pubkey = pubkeys[validator_index]
privkey = privkeys[validator_index]
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkey)[1:]
deposit_message = spec.DepositMessage(pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount)
domain = spec.compute_domain(domain_type=spec.DOMAIN_DEPOSIT, fork_version=fork_version)
deposit_data = spec.DepositData(
pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount,
signature=bls.Sign(privkey, spec.compute_signing_root(deposit_message, domain))
)
deposit, root, _ = deposit_from_context(spec, [deposit_data], 0)
state.eth1_deposit_index = 0
state.eth1_data.deposit_root = root
state.eth1_data.deposit_count = 1
yield from run_deposit_processing(spec, state, deposit, validator_index, valid=valid, effective=effective)
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_deposit_with_previous_fork_version__valid_ineffective(spec, state): def test_ineffective_deposit_with_previous_fork_version(spec, state):
# Since deposits are valid across forks, the domain is always set with `GENESIS_FORK_VERSION`.
# It's an ineffective deposit because it fails at BLS sig verification.
# NOTE: it was effective in Altair.
assert state.fork.previous_version != state.fork.current_version assert state.fork.previous_version != state.fork.current_version
yield from _run_deposit_processing_with_specific_fork_version( yield from run_deposit_processing_with_specific_fork_version(
spec, spec,
state, state,
fork_version=state.fork.previous_version, fork_version=state.fork.previous_version,
valid=True,
effective=False, effective=False,
) )
@ -60,26 +28,11 @@ def test_deposit_with_previous_fork_version__valid_ineffective(spec, state):
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_deposit_with_genesis_fork_version__valid_effective(spec, state): def test_effective_deposit_with_genesis_fork_version(spec, state):
assert spec.config.GENESIS_FORK_VERSION not in (state.fork.previous_version, state.fork.current_version) assert spec.config.GENESIS_FORK_VERSION not in (state.fork.previous_version, state.fork.current_version)
yield from _run_deposit_processing_with_specific_fork_version( yield from run_deposit_processing_with_specific_fork_version(
spec, spec,
state, state,
fork_version=spec.config.GENESIS_FORK_VERSION, fork_version=spec.config.GENESIS_FORK_VERSION,
valid=True,
effective=True,
)
@with_bellatrix_and_later
@spec_state_test
@always_bls
def test_deposit_with_bad_fork_version__valid_ineffective(spec, state):
yield from _run_deposit_processing_with_specific_fork_version(
spec,
state,
fork_version=spec.Version('0xAaBbCcDd'),
valid=True,
effective=False,
) )

View File

@ -3,6 +3,7 @@ from random import Random
from eth2spec.test.helpers.execution_payload import ( from eth2spec.test.helpers.execution_payload import (
build_empty_execution_payload, build_empty_execution_payload,
build_randomized_execution_payload, build_randomized_execution_payload,
compute_el_block_hash,
get_execution_payload_header, get_execution_payload_header,
build_state_with_incomplete_transition, build_state_with_incomplete_transition,
build_state_with_complete_transition, build_state_with_complete_transition,
@ -104,14 +105,14 @@ def run_bad_execution_test(spec, state):
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
def test_bad_execution_first_payload(spec, state): def test_invalid_bad_execution_first_payload(spec, state):
state = build_state_with_incomplete_transition(spec, state) state = build_state_with_incomplete_transition(spec, state)
yield from run_bad_execution_test(spec, state) yield from run_bad_execution_test(spec, state)
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
def test_bad_execution_regular_payload(spec, state): def test_invalid_bad_execution_regular_payload(spec, state):
state = build_state_with_complete_transition(spec, state) state = build_state_with_complete_transition(spec, state)
yield from run_bad_execution_test(spec, state) yield from run_bad_execution_test(spec, state)
@ -124,18 +125,20 @@ def test_bad_parent_hash_first_payload(spec, state):
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.parent_hash = b'\x55' * 32 execution_payload.parent_hash = b'\x55' * 32
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_execution_payload_processing(spec, state, execution_payload, valid=True) yield from run_execution_payload_processing(spec, state, execution_payload)
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
def test_bad_parent_hash_regular_payload(spec, state): def test_invalid_bad_parent_hash_regular_payload(spec, state):
state = build_state_with_complete_transition(spec, state) state = build_state_with_complete_transition(spec, state)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.parent_hash = spec.Hash32() execution_payload.parent_hash = spec.Hash32()
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_execution_payload_processing(spec, state, execution_payload, valid=False) yield from run_execution_payload_processing(spec, state, execution_payload, valid=False)
@ -145,20 +148,21 @@ def run_bad_prev_randao_test(spec, state):
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.prev_randao = b'\x42' * 32 execution_payload.prev_randao = b'\x42' * 32
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_execution_payload_processing(spec, state, execution_payload, valid=False) yield from run_execution_payload_processing(spec, state, execution_payload, valid=False)
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
def test_bad_prev_randao_first_payload(spec, state): def test_invalid_bad_prev_randao_first_payload(spec, state):
state = build_state_with_incomplete_transition(spec, state) state = build_state_with_incomplete_transition(spec, state)
yield from run_bad_prev_randao_test(spec, state) yield from run_bad_prev_randao_test(spec, state)
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
def test_bad_pre_randao_regular_payload(spec, state): def test_invalid_bad_pre_randao_regular_payload(spec, state):
state = build_state_with_complete_transition(spec, state) state = build_state_with_complete_transition(spec, state)
yield from run_bad_prev_randao_test(spec, state) yield from run_bad_prev_randao_test(spec, state)
@ -170,20 +174,21 @@ def run_bad_everything_test(spec, state):
execution_payload.parent_hash = spec.Hash32() execution_payload.parent_hash = spec.Hash32()
execution_payload.prev_randao = spec.Bytes32() execution_payload.prev_randao = spec.Bytes32()
execution_payload.timestamp = 0 execution_payload.timestamp = 0
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_execution_payload_processing(spec, state, execution_payload, valid=False) yield from run_execution_payload_processing(spec, state, execution_payload, valid=False)
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
def test_bad_everything_first_payload(spec, state): def test_invalid_bad_everything_first_payload(spec, state):
state = build_state_with_incomplete_transition(spec, state) state = build_state_with_incomplete_transition(spec, state)
yield from run_bad_everything_test(spec, state) yield from run_bad_everything_test(spec, state)
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
def test_bad_everything_regular_payload(spec, state): def test_invalid_bad_everything_regular_payload(spec, state):
state = build_state_with_complete_transition(spec, state) state = build_state_with_complete_transition(spec, state)
yield from run_bad_everything_test(spec, state) yield from run_bad_everything_test(spec, state)
@ -198,34 +203,35 @@ def run_bad_timestamp_test(spec, state, is_future):
else: else:
timestamp = execution_payload.timestamp - 1 timestamp = execution_payload.timestamp - 1
execution_payload.timestamp = timestamp execution_payload.timestamp = timestamp
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_execution_payload_processing(spec, state, execution_payload, valid=False) yield from run_execution_payload_processing(spec, state, execution_payload, valid=False)
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
def test_future_timestamp_first_payload(spec, state): def test_invalid_future_timestamp_first_payload(spec, state):
state = build_state_with_incomplete_transition(spec, state) state = build_state_with_incomplete_transition(spec, state)
yield from run_bad_timestamp_test(spec, state, is_future=True) yield from run_bad_timestamp_test(spec, state, is_future=True)
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
def test_future_timestamp_regular_payload(spec, state): def test_invalid_future_timestamp_regular_payload(spec, state):
state = build_state_with_complete_transition(spec, state) state = build_state_with_complete_transition(spec, state)
yield from run_bad_timestamp_test(spec, state, is_future=True) yield from run_bad_timestamp_test(spec, state, is_future=True)
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
def test_past_timestamp_first_payload(spec, state): def test_invalid_past_timestamp_first_payload(spec, state):
state = build_state_with_incomplete_transition(spec, state) state = build_state_with_incomplete_transition(spec, state)
yield from run_bad_timestamp_test(spec, state, is_future=False) yield from run_bad_timestamp_test(spec, state, is_future=False)
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
def test_past_timestamp_regular_payload(spec, state): def test_invalid_past_timestamp_regular_payload(spec, state):
state = build_state_with_complete_transition(spec, state) state = build_state_with_complete_transition(spec, state)
yield from run_bad_timestamp_test(spec, state, is_future=False) yield from run_bad_timestamp_test(spec, state, is_future=False)
@ -235,6 +241,7 @@ def run_non_empty_extra_data_test(spec, state):
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.extra_data = b'\x45' * 12 execution_payload.extra_data = b'\x45' * 12
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_execution_payload_processing(spec, state, execution_payload) yield from run_execution_payload_processing(spec, state, execution_payload)
assert state.latest_execution_payload_header.extra_data == execution_payload.extra_data assert state.latest_execution_payload_header.extra_data == execution_payload.extra_data
@ -263,6 +270,7 @@ def run_non_empty_transactions_test(spec, state):
spec.Transaction(b'\x99' * 128) spec.Transaction(b'\x99' * 128)
for _ in range(num_transactions) for _ in range(num_transactions)
] ]
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_execution_payload_processing(spec, state, execution_payload) yield from run_execution_payload_processing(spec, state, execution_payload)
assert state.latest_execution_payload_header.transactions_root == execution_payload.transactions.hash_tree_root() assert state.latest_execution_payload_header.transactions_root == execution_payload.transactions.hash_tree_root()
@ -288,6 +296,7 @@ def run_zero_length_transaction_test(spec, state):
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.transactions = [spec.Transaction(b'')] execution_payload.transactions = [spec.Transaction(b'')]
assert len(execution_payload.transactions[0]) == 0 assert len(execution_payload.transactions[0]) == 0
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_execution_payload_processing(spec, state, execution_payload) yield from run_execution_payload_processing(spec, state, execution_payload)
assert state.latest_execution_payload_header.transactions_root == execution_payload.transactions.hash_tree_root() assert state.latest_execution_payload_header.transactions_root == execution_payload.transactions.hash_tree_root()
@ -320,27 +329,27 @@ def run_randomized_non_validated_execution_fields_test(spec, state, execution_va
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
def test_randomized_non_validated_execution_fields_first_payload__valid(spec, state): def test_randomized_non_validated_execution_fields_first_payload__execution_valid(spec, state):
state = build_state_with_incomplete_transition(spec, state) state = build_state_with_incomplete_transition(spec, state)
yield from run_randomized_non_validated_execution_fields_test(spec, state) yield from run_randomized_non_validated_execution_fields_test(spec, state)
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
def test_randomized_non_validated_execution_fields_regular_payload__valid(spec, state): def test_randomized_non_validated_execution_fields_regular_payload__execution_valid(spec, state):
state = build_state_with_complete_transition(spec, state) state = build_state_with_complete_transition(spec, state)
yield from run_randomized_non_validated_execution_fields_test(spec, state) yield from run_randomized_non_validated_execution_fields_test(spec, state)
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
def test_randomized_non_validated_execution_fields_first_payload__invalid(spec, state): def test_invalid_randomized_non_validated_execution_fields_first_payload__execution_invalid(spec, state):
state = build_state_with_incomplete_transition(spec, state) state = build_state_with_incomplete_transition(spec, state)
yield from run_randomized_non_validated_execution_fields_test(spec, state, execution_valid=False) yield from run_randomized_non_validated_execution_fields_test(spec, state, execution_valid=False)
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
def test_randomized_non_validated_execution_fields_regular_payload__invalid(spec, state): def test_invalid_randomized_non_validated_execution_fields_regular_payload__execution_invalid(spec, state):
state = build_state_with_complete_transition(spec, state) state = build_state_with_complete_transition(spec, state)
yield from run_randomized_non_validated_execution_fields_test(spec, state, execution_valid=False) yield from run_randomized_non_validated_execution_fields_test(spec, state, execution_valid=False)

View File

@ -18,7 +18,7 @@ def _run_voluntary_exit_processing_test(
state, state,
fork_version, fork_version,
is_before_fork_epoch, is_before_fork_epoch,
valid): valid=True):
# create a fork # create a fork
next_epoch(spec, state) next_epoch(spec, state)
state.fork.epoch = spec.get_current_epoch(state) state.fork.epoch = spec.get_current_epoch(state)
@ -50,7 +50,7 @@ def _run_voluntary_exit_processing_test(
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_voluntary_exit_with_current_fork_version_is_before_fork_epoch__invalid(spec, state): def test_invalid_voluntary_exit_with_current_fork_version_is_before_fork_epoch(spec, state):
yield from _run_voluntary_exit_processing_test( yield from _run_voluntary_exit_processing_test(
spec, spec,
state, state,
@ -63,20 +63,19 @@ def test_voluntary_exit_with_current_fork_version_is_before_fork_epoch__invalid(
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_voluntary_exit_with_current_fork_version_not_is_before_fork_epoch__valid(spec, state): def test_voluntary_exit_with_current_fork_version_not_is_before_fork_epoch(spec, state):
yield from _run_voluntary_exit_processing_test( yield from _run_voluntary_exit_processing_test(
spec, spec,
state, state,
fork_version=state.fork.current_version, fork_version=state.fork.current_version,
is_before_fork_epoch=False, is_before_fork_epoch=False,
valid=True,
) )
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_voluntary_exit_with_previous_fork_version_is_before_fork_epoch__valid(spec, state): def test_voluntary_exit_with_previous_fork_version_is_before_fork_epoch(spec, state):
assert state.fork.previous_version != state.fork.current_version assert state.fork.previous_version != state.fork.current_version
yield from _run_voluntary_exit_processing_test( yield from _run_voluntary_exit_processing_test(
@ -84,14 +83,13 @@ def test_voluntary_exit_with_previous_fork_version_is_before_fork_epoch__valid(s
state, state,
fork_version=state.fork.previous_version, fork_version=state.fork.previous_version,
is_before_fork_epoch=True, is_before_fork_epoch=True,
valid=True,
) )
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_voluntary_exit_with_previous_fork_version_not_is_before_fork_epoch__invalid(spec, state): def test_invalid_voluntary_exit_with_previous_fork_version_not_is_before_fork_epoch(spec, state):
assert state.fork.previous_version != state.fork.current_version assert state.fork.previous_version != state.fork.current_version
yield from _run_voluntary_exit_processing_test( yield from _run_voluntary_exit_processing_test(
@ -106,7 +104,7 @@ def test_voluntary_exit_with_previous_fork_version_not_is_before_fork_epoch__inv
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_voluntary_exit_with_genesis_fork_version_is_before_fork_epoch__invalid(spec, state): def test_invalid_voluntary_exit_with_genesis_fork_version_is_before_fork_epoch(spec, state):
assert spec.config.GENESIS_FORK_VERSION not in (state.fork.previous_version, state.fork.current_version) assert spec.config.GENESIS_FORK_VERSION not in (state.fork.previous_version, state.fork.current_version)
yield from _run_voluntary_exit_processing_test( yield from _run_voluntary_exit_processing_test(
@ -121,7 +119,7 @@ def test_voluntary_exit_with_genesis_fork_version_is_before_fork_epoch__invalid(
@with_bellatrix_and_later @with_bellatrix_and_later
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_voluntary_exit_with_genesis_fork_version_not_is_before_fork_epoch__invalid(spec, state): def test_invalid_voluntary_exit_with_genesis_fork_version_not_is_before_fork_epoch(spec, state):
assert spec.config.GENESIS_FORK_VERSION not in (state.fork.previous_version, state.fork.current_version) assert spec.config.GENESIS_FORK_VERSION not in (state.fork.previous_version, state.fork.current_version)
yield from _run_voluntary_exit_processing_test( yield from _run_voluntary_exit_processing_test(

View File

@ -4,6 +4,9 @@ from eth2spec.test.context import spec_state_test, with_phases, BELLATRIX
from eth2spec.test.helpers.block import ( from eth2spec.test.helpers.block import (
build_empty_block_for_next_slot, build_empty_block_for_next_slot,
) )
from eth2spec.test.helpers.execution_payload import (
compute_el_block_hash,
)
from eth2spec.test.helpers.fork_choice import ( from eth2spec.test.helpers.fork_choice import (
get_genesis_forkchoice_store_and_block, get_genesis_forkchoice_store_and_block,
on_tick_and_append_step, on_tick_and_append_step,
@ -72,6 +75,7 @@ def test_all_valid(spec, state):
def run_func(): def run_func():
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.parent_hash = pow_block.block_hash block.body.execution_payload.parent_hash = pow_block.block_hash
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
signed_block = state_transition_and_sign_block(spec, state, block) signed_block = state_transition_and_sign_block(spec, state, block)
yield from tick_and_add_block(spec, store, signed_block, test_steps, merge_block=True) yield from tick_and_add_block(spec, store, signed_block, test_steps, merge_block=True)
# valid # valid
@ -103,6 +107,7 @@ def test_block_lookup_failed(spec, state):
def run_func(): def run_func():
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.parent_hash = pow_block.block_hash block.body.execution_payload.parent_hash = pow_block.block_hash
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
signed_block = state_transition_and_sign_block(spec, state, block) signed_block = state_transition_and_sign_block(spec, state, block)
yield from tick_and_add_block(spec, store, signed_block, test_steps, valid=False, merge_block=True, yield from tick_and_add_block(spec, store, signed_block, test_steps, valid=False, merge_block=True,
block_not_found=True) block_not_found=True)
@ -136,6 +141,7 @@ def test_too_early_for_merge(spec, state):
def run_func(): def run_func():
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.parent_hash = pow_block.block_hash block.body.execution_payload.parent_hash = pow_block.block_hash
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
signed_block = state_transition_and_sign_block(spec, state, block) signed_block = state_transition_and_sign_block(spec, state, block)
yield from tick_and_add_block(spec, store, signed_block, test_steps, valid=False, merge_block=True) yield from tick_and_add_block(spec, store, signed_block, test_steps, valid=False, merge_block=True)
@ -168,6 +174,7 @@ def test_too_late_for_merge(spec, state):
def run_func(): def run_func():
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.parent_hash = pow_block.block_hash block.body.execution_payload.parent_hash = pow_block.block_hash
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
signed_block = state_transition_and_sign_block(spec, state, block) signed_block = state_transition_and_sign_block(spec, state, block)
yield from tick_and_add_block(spec, store, signed_block, test_steps, valid=False, merge_block=True) yield from tick_and_add_block(spec, store, signed_block, test_steps, valid=False, merge_block=True)

View File

@ -8,6 +8,9 @@ from eth2spec.test.helpers.attestations import (
from eth2spec.test.helpers.block import ( from eth2spec.test.helpers.block import (
build_empty_block_for_next_slot, build_empty_block_for_next_slot,
) )
from eth2spec.test.helpers.execution_payload import (
compute_el_block_hash,
)
from eth2spec.test.helpers.fork_choice import ( from eth2spec.test.helpers.fork_choice import (
get_genesis_forkchoice_store_and_block, get_genesis_forkchoice_store_and_block,
on_tick_and_append_step, on_tick_and_append_step,
@ -33,6 +36,7 @@ def test_from_syncing_to_invalid(spec, state):
fc_store, anchor_block = get_genesis_forkchoice_store_and_block(spec, state) fc_store, anchor_block = get_genesis_forkchoice_store_and_block(spec, state)
op_store = get_optimistic_store(spec, state, anchor_block) op_store = get_optimistic_store(spec, state, anchor_block)
mega_store = MegaStore(spec, fc_store, op_store) mega_store = MegaStore(spec, fc_store, op_store)
block_hashes = {}
yield 'anchor_state', state yield 'anchor_state', state
yield 'anchor_block', anchor_block yield 'anchor_block', anchor_block
@ -46,7 +50,7 @@ def test_from_syncing_to_invalid(spec, state):
# Block 0 # Block 0
block_0 = build_empty_block_for_next_slot(spec, state) block_0 = build_empty_block_for_next_slot(spec, state)
block_0.body.execution_payload.block_hash = spec.hash(bytes('block_0', 'UTF-8')) block_hashes['block_0'] = block_0.body.execution_payload.block_hash
signed_block = state_transition_and_sign_block(spec, state, block_0) signed_block = state_transition_and_sign_block(spec, state, block_0)
yield from add_optimistic_block(spec, mega_store, signed_block, test_steps, status=PayloadStatusV1Status.VALID) yield from add_optimistic_block(spec, mega_store, signed_block, test_steps, status=PayloadStatusV1Status.VALID)
assert spec.get_head(mega_store.fc_store) == mega_store.opt_store.head_block_root assert spec.get_head(mega_store.fc_store) == mega_store.opt_store.head_block_root
@ -57,10 +61,11 @@ def test_from_syncing_to_invalid(spec, state):
signed_blocks_a = [] signed_blocks_a = []
for i in range(3): for i in range(3):
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.block_hash = spec.hash(bytes(f'chain_a_{i}', 'UTF-8'))
block.body.execution_payload.parent_hash = ( block.body.execution_payload.parent_hash = (
spec.hash(bytes(f'chain_a_{i - 1}', 'UTF-8')) if i != 0 else block_0.body.execution_payload.block_hash block_hashes[f'chain_a_{i - 1}'] if i != 0 else block_hashes['block_0']
) )
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
block_hashes[f'chain_a_{i}'] = block.body.execution_payload.block_hash
signed_block = state_transition_and_sign_block(spec, state, block) signed_block = state_transition_and_sign_block(spec, state, block)
yield from add_optimistic_block(spec, mega_store, signed_block, test_steps, status=PayloadStatusV1Status.VALID) yield from add_optimistic_block(spec, mega_store, signed_block, test_steps, status=PayloadStatusV1Status.VALID)
@ -72,10 +77,12 @@ def test_from_syncing_to_invalid(spec, state):
state = state_0.copy() state = state_0.copy()
for i in range(3): for i in range(3):
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.block_hash = spec.hash(bytes(f'chain_b_{i}', 'UTF-8'))
block.body.execution_payload.parent_hash = ( block.body.execution_payload.parent_hash = (
spec.hash(bytes(f'chain_b_{i - 1}', 'UTF-8')) if i != 0 else block_0.body.execution_payload.block_hash block_hashes[f'chain_b_{i - 1}'] if i != 0 else block_hashes['block_0']
) )
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
block_hashes[f'chain_b_{i}'] = block.body.execution_payload.block_hash
signed_block = state_transition_with_full_block(spec, state, True, True, block=block) signed_block = state_transition_with_full_block(spec, state, True, True, block=block)
signed_blocks_b.append(signed_block.copy()) signed_blocks_b.append(signed_block.copy())
yield from add_optimistic_block(spec, mega_store, signed_block, test_steps, yield from add_optimistic_block(spec, mega_store, signed_block, test_steps,
@ -84,8 +91,10 @@ def test_from_syncing_to_invalid(spec, state):
# Now add block 4 to chain `b` with INVALID # Now add block 4 to chain `b` with INVALID
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.block_hash = spec.hash(bytes('chain_b_3', 'UTF-8'))
block.body.execution_payload.parent_hash = signed_blocks_b[-1].message.body.execution_payload.block_hash block.body.execution_payload.parent_hash = signed_blocks_b[-1].message.body.execution_payload.block_hash
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
block_hashes['chain_b_3'] = block.body.execution_payload.block_hash
signed_block = state_transition_and_sign_block(spec, state, block) signed_block = state_transition_and_sign_block(spec, state, block)
payload_status = PayloadStatusV1( payload_status = PayloadStatusV1(
status=PayloadStatusV1Status.INVALID, status=PayloadStatusV1Status.INVALID,

View File

@ -3,6 +3,9 @@ from eth2spec.utils.ssz.ssz_typing import uint256, Bytes32
from eth2spec.test.helpers.block import ( from eth2spec.test.helpers.block import (
build_empty_block_for_next_slot, build_empty_block_for_next_slot,
) )
from eth2spec.test.helpers.execution_payload import (
compute_el_block_hash,
)
from eth2spec.test.helpers.pow_block import ( from eth2spec.test.helpers.pow_block import (
prepare_random_pow_chain, prepare_random_pow_chain,
) )
@ -57,6 +60,7 @@ def test_validate_merge_block_success(spec, state):
pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.parent_hash = pow_chain.head().block_hash block.body.execution_payload.parent_hash = pow_chain.head().block_hash
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
run_validate_merge_block(spec, pow_chain, block) run_validate_merge_block(spec, pow_chain, block)
@ -77,6 +81,7 @@ def test_validate_merge_block_fail_parent_block_lookup(spec, state):
pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.parent_hash = pow_chain.head().block_hash block.body.execution_payload.parent_hash = pow_chain.head().block_hash
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
run_validate_merge_block(spec, pow_chain, block, valid=False) run_validate_merge_block(spec, pow_chain, block, valid=False)
@ -88,6 +93,7 @@ def test_validate_merge_block_fail_after_terminal(spec, state):
pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY + uint256(1) pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY + uint256(1)
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.parent_hash = pow_chain.head().block_hash block.body.execution_payload.parent_hash = pow_chain.head().block_hash
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
run_validate_merge_block(spec, pow_chain, block, valid=False) run_validate_merge_block(spec, pow_chain, block, valid=False)
@ -104,6 +110,7 @@ def test_validate_merge_block_tbh_override_success(spec, state):
pow_chain.head().block_hash = TERMINAL_BLOCK_HASH pow_chain.head().block_hash = TERMINAL_BLOCK_HASH
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.parent_hash = pow_chain.head().block_hash block.body.execution_payload.parent_hash = pow_chain.head().block_hash
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
run_validate_merge_block(spec, pow_chain, block) run_validate_merge_block(spec, pow_chain, block)
@ -119,6 +126,7 @@ def test_validate_merge_block_fail_parent_hash_is_not_tbh(spec, state):
pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.parent_hash = pow_chain.head().block_hash block.body.execution_payload.parent_hash = pow_chain.head().block_hash
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
run_validate_merge_block(spec, pow_chain, block, valid=False) run_validate_merge_block(spec, pow_chain, block, valid=False)
@ -135,6 +143,7 @@ def test_validate_merge_block_terminal_block_hash_fail_activation_not_reached(sp
pow_chain.head().block_hash = TERMINAL_BLOCK_HASH pow_chain.head().block_hash = TERMINAL_BLOCK_HASH
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.parent_hash = pow_chain.head().block_hash block.body.execution_payload.parent_hash = pow_chain.head().block_hash
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
run_validate_merge_block(spec, pow_chain, block, valid=False) run_validate_merge_block(spec, pow_chain, block, valid=False)
@ -150,4 +159,5 @@ def test_validate_merge_block_fail_activation_not_reached_parent_hash_is_not_tbh
pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.parent_hash = pow_chain.head().block_hash block.body.execution_payload.parent_hash = pow_chain.head().block_hash
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
run_validate_merge_block(spec, pow_chain, block, valid=False) run_validate_merge_block(spec, pow_chain, block, valid=False)

View File

@ -131,7 +131,7 @@ def test_success_withdrawable(spec, state):
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_val_index_out_of_range(spec, state): def test_invalid_val_index_out_of_range(spec, state):
# Create for one validator beyond the validator list length # Create for one validator beyond the validator list length
signed_address_change = get_signed_address_change(spec, state, validator_index=len(state.validators)) signed_address_change = get_signed_address_change(spec, state, validator_index=len(state.validators))
@ -140,7 +140,7 @@ def test_fail_val_index_out_of_range(spec, state):
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_already_0x01(spec, state): def test_invalid_already_0x01(spec, state):
# Create for one validator beyond the validator list length # Create for one validator beyond the validator list length
validator_index = len(state.validators) // 2 validator_index = len(state.validators) // 2
validator = state.validators[validator_index] validator = state.validators[validator_index]
@ -152,7 +152,7 @@ def test_fail_already_0x01(spec, state):
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_incorrect_from_bls_pubkey(spec, state): def test_invalid_incorrect_from_bls_pubkey(spec, state):
# Create for one validator beyond the validator list length # Create for one validator beyond the validator list length
validator_index = 2 validator_index = 2
signed_address_change = get_signed_address_change( signed_address_change = get_signed_address_change(
@ -167,7 +167,7 @@ def test_fail_incorrect_from_bls_pubkey(spec, state):
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_fail_bad_signature(spec, state): def test_invalid_bad_signature(spec, state):
signed_address_change = get_signed_address_change(spec, state) signed_address_change = get_signed_address_change(spec, state)
# Mutate signature # Mutate signature
signed_address_change.signature = spec.BLSSignature(b'\x42' * 96) signed_address_change.signature = spec.BLSSignature(b'\x42' * 96)

View File

@ -6,9 +6,10 @@ from eth2spec.test.context import (
with_presets, with_presets,
with_phases, with_phases,
) )
from eth2spec.test.helpers.constants import MINIMAL, CAPELLA from eth2spec.test.helpers.constants import MAINNET, MINIMAL, CAPELLA
from eth2spec.test.helpers.execution_payload import ( from eth2spec.test.helpers.execution_payload import (
build_empty_execution_payload, build_empty_execution_payload,
compute_el_block_hash,
) )
from eth2spec.test.helpers.random import ( from eth2spec.test.helpers.random import (
randomize_state, randomize_state,
@ -33,8 +34,13 @@ def verify_post_state(state, spec, expected_withdrawals,
expected_withdrawals_validator_indices = [withdrawal.validator_index for withdrawal in expected_withdrawals] expected_withdrawals_validator_indices = [withdrawal.validator_index for withdrawal in expected_withdrawals]
assert state.next_withdrawal_index == expected_withdrawals[-1].index + 1 assert state.next_withdrawal_index == expected_withdrawals[-1].index + 1
next_withdrawal_validator_index = (expected_withdrawals_validator_indices[-1] + 1) % len(state.validators)
assert state.next_withdrawal_validator_index == next_withdrawal_validator_index if len(expected_withdrawals) == spec.MAX_WITHDRAWALS_PER_PAYLOAD:
# NOTE: ideally we would also check in the case with
# fewer than maximum withdrawals but that requires the pre-state info
next_withdrawal_validator_index = (expected_withdrawals_validator_indices[-1] + 1) % len(state.validators)
assert state.next_withdrawal_validator_index == next_withdrawal_validator_index
for index in fully_withdrawable_indices: for index in fully_withdrawable_indices:
if index in expected_withdrawals_validator_indices: if index in expected_withdrawals_validator_indices:
assert state.balances[index] == 0 assert state.balances[index] == 0
@ -75,9 +81,13 @@ def run_withdrawals_processing(spec, state, execution_payload, num_expected_with
yield 'post', state yield 'post', state
if len(expected_withdrawals) == 0: if len(expected_withdrawals) == 0:
assert state == pre_state next_withdrawal_validator_index = (
elif len(expected_withdrawals) < spec.MAX_WITHDRAWALS_PER_PAYLOAD: pre_state.next_withdrawal_validator_index + spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP
assert len(spec.get_expected_withdrawals(state)) == 0 )
assert state.next_withdrawal_validator_index == next_withdrawal_validator_index % len(state.validators)
elif len(expected_withdrawals) <= spec.MAX_WITHDRAWALS_PER_PAYLOAD:
bound = min(spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP, spec.MAX_WITHDRAWALS_PER_PAYLOAD)
assert len(spec.get_expected_withdrawals(state)) <= bound
elif len(expected_withdrawals) > spec.MAX_WITHDRAWALS_PER_PAYLOAD: elif len(expected_withdrawals) > spec.MAX_WITHDRAWALS_PER_PAYLOAD:
raise ValueError('len(expected_withdrawals) should not be greater than MAX_WITHDRAWALS_PER_PAYLOAD') raise ValueError('len(expected_withdrawals) should not be greater than MAX_WITHDRAWALS_PER_PAYLOAD')
@ -154,10 +164,14 @@ def test_success_max_per_slot(spec, state):
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@with_presets([MAINNET], reason="too few validators with minimal config")
@spec_state_test @spec_state_test
def test_success_all_fully_withdrawable(spec, state): def test_success_all_fully_withdrawable_in_one_sweep(spec, state):
assert len(state.validators) <= spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP
withdrawal_count = len(state.validators)
fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals( fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals(
spec, state, num_full_withdrawals=len(state.validators)) spec, state, num_full_withdrawals=withdrawal_count)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
@ -169,10 +183,52 @@ def test_success_all_fully_withdrawable(spec, state):
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@with_presets([MINIMAL], reason="too many validators with mainnet config")
@spec_state_test
def test_success_all_fully_withdrawable(spec, state):
assert len(state.validators) > spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP
withdrawal_count = spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP
fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals(
spec, state, num_full_withdrawals=withdrawal_count)
next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state)
yield from run_withdrawals_processing(
spec, state, execution_payload,
fully_withdrawable_indices=fully_withdrawable_indices,
partial_withdrawals_indices=partial_withdrawals_indices)
@with_phases([CAPELLA])
@with_presets([MAINNET], reason="too few validators with minimal config")
@spec_state_test
def test_success_all_partially_withdrawable_in_one_sweep(spec, state):
assert len(state.validators) <= spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP
withdrawal_count = len(state.validators)
fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals(
spec, state, num_partial_withdrawals=withdrawal_count)
next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state)
yield from run_withdrawals_processing(
spec, state, execution_payload,
fully_withdrawable_indices=fully_withdrawable_indices,
partial_withdrawals_indices=partial_withdrawals_indices)
@with_phases([CAPELLA])
@with_presets([MINIMAL], reason="too many validators with mainnet config")
@spec_state_test @spec_state_test
def test_success_all_partially_withdrawable(spec, state): def test_success_all_partially_withdrawable(spec, state):
assert len(state.validators) > spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP
withdrawal_count = spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP
fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals( fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals(
spec, state, num_partial_withdrawals=len(state.validators)) spec, state, num_partial_withdrawals=withdrawal_count)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
@ -189,7 +245,7 @@ def test_success_all_partially_withdrawable(spec, state):
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_non_withdrawable_non_empty_withdrawals(spec, state): def test_invalid_non_withdrawable_non_empty_withdrawals(spec, state):
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
withdrawal = spec.Withdrawal( withdrawal = spec.Withdrawal(
@ -199,115 +255,125 @@ def test_fail_non_withdrawable_non_empty_withdrawals(spec, state):
amount=420, amount=420,
) )
execution_payload.withdrawals.append(withdrawal) execution_payload.withdrawals.append(withdrawal)
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_one_expected_full_withdrawal_and_none_in_withdrawals(spec, state): def test_invalid_one_expected_full_withdrawal_and_none_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=1) prepare_expected_withdrawals(spec, state, num_full_withdrawals=1)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.withdrawals = [] execution_payload.withdrawals = []
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_one_expected_partial_withdrawal_and_none_in_withdrawals(spec, state): def test_invalid_one_expected_partial_withdrawal_and_none_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=1) prepare_expected_withdrawals(spec, state, num_partial_withdrawals=1)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.withdrawals = [] execution_payload.withdrawals = []
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_one_expected_full_withdrawal_and_duplicate_in_withdrawals(spec, state): def test_invalid_one_expected_full_withdrawal_and_duplicate_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=2) prepare_expected_withdrawals(spec, state, num_full_withdrawals=2)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.withdrawals.append(execution_payload.withdrawals[0].copy()) execution_payload.withdrawals.append(execution_payload.withdrawals[0].copy())
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_two_expected_partial_withdrawal_and_duplicate_in_withdrawals(spec, state): def test_invalid_two_expected_partial_withdrawal_and_duplicate_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=2) prepare_expected_withdrawals(spec, state, num_partial_withdrawals=2)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.withdrawals.append(execution_payload.withdrawals[0].copy()) execution_payload.withdrawals.append(execution_payload.withdrawals[0].copy())
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_max_per_slot_full_withdrawals_and_one_less_in_withdrawals(spec, state): def test_invalid_max_per_slot_full_withdrawals_and_one_less_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD) prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.withdrawals = execution_payload.withdrawals[:-1] execution_payload.withdrawals = execution_payload.withdrawals[:-1]
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_max_per_slot_partial_withdrawals_and_one_less_in_withdrawals(spec, state): def test_invalid_max_per_slot_partial_withdrawals_and_one_less_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD) prepare_expected_withdrawals(spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.withdrawals = execution_payload.withdrawals[:-1] execution_payload.withdrawals = execution_payload.withdrawals[:-1]
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_a_lot_fully_withdrawable_too_few_in_withdrawals(spec, state): def test_invalid_a_lot_fully_withdrawable_too_few_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4) prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.withdrawals = execution_payload.withdrawals[:-1] execution_payload.withdrawals = execution_payload.withdrawals[:-1]
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_a_lot_partially_withdrawable_too_few_in_withdrawals(spec, state): def test_invalid_a_lot_partially_withdrawable_too_few_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4) prepare_expected_withdrawals(spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.withdrawals = execution_payload.withdrawals[:-1] execution_payload.withdrawals = execution_payload.withdrawals[:-1]
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_a_lot_mixed_withdrawable_in_queue_too_few_in_withdrawals(spec, state): def test_invalid_a_lot_mixed_withdrawable_in_queue_too_few_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4, prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD,
num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4) num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.withdrawals = execution_payload.withdrawals[:-1] execution_payload.withdrawals = execution_payload.withdrawals[:-1]
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@ -318,67 +384,72 @@ def test_fail_a_lot_mixed_withdrawable_in_queue_too_few_in_withdrawals(spec, sta
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_incorrect_withdrawal_index(spec, state): def test_invalid_incorrect_withdrawal_index(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=1) prepare_expected_withdrawals(spec, state, num_full_withdrawals=1)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.withdrawals[0].index += 1 execution_payload.withdrawals[0].index += 1
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_incorrect_address_full(spec, state): def test_invalid_incorrect_address_full(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=1) prepare_expected_withdrawals(spec, state, num_full_withdrawals=1)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.withdrawals[0].address = b'\xff' * 20 execution_payload.withdrawals[0].address = b'\xff' * 20
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_incorrect_address_partial(spec, state): def test_invalid_incorrect_address_partial(spec, state):
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=1) prepare_expected_withdrawals(spec, state, num_partial_withdrawals=1)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.withdrawals[0].address = b'\xff' * 20 execution_payload.withdrawals[0].address = b'\xff' * 20
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_incorrect_amount_full(spec, state): def test_invalid_incorrect_amount_full(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=1) prepare_expected_withdrawals(spec, state, num_full_withdrawals=1)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.withdrawals[0].amount += 1 execution_payload.withdrawals[0].amount += 1
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_incorrect_amount_partial(spec, state): def test_invalid_incorrect_amount_partial(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=1) prepare_expected_withdrawals(spec, state, num_full_withdrawals=1)
next_slot(spec, state) next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state) execution_payload = build_empty_execution_payload(spec, state)
execution_payload.withdrawals[0].amount += 1 execution_payload.withdrawals[0].amount += 1
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_one_of_many_incorrectly_full(spec, state): def test_invalid_one_of_many_incorrectly_full(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4) prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
next_slot(spec, state) next_slot(spec, state)
@ -390,13 +461,14 @@ def test_fail_one_of_many_incorrectly_full(spec, state):
withdrawal.index += 1 withdrawal.index += 1
withdrawal.address = b'\x99' * 20 withdrawal.address = b'\x99' * 20
withdrawal.amount += 4000000 withdrawal.amount += 4000000
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_one_of_many_incorrectly_partial(spec, state): def test_invalid_one_of_many_incorrectly_partial(spec, state):
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4) prepare_expected_withdrawals(spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
next_slot(spec, state) next_slot(spec, state)
@ -408,13 +480,14 @@ def test_fail_one_of_many_incorrectly_partial(spec, state):
withdrawal.index += 1 withdrawal.index += 1
withdrawal.address = b'\x99' * 20 withdrawal.address = b'\x99' * 20
withdrawal.amount += 4000000 withdrawal.amount += 4000000
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_many_incorrectly_full(spec, state): def test_invalid_many_incorrectly_full(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4) prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
next_slot(spec, state) next_slot(spec, state)
@ -426,13 +499,14 @@ def test_fail_many_incorrectly_full(spec, state):
withdrawal.address = i.to_bytes(20, 'big') withdrawal.address = i.to_bytes(20, 'big')
else: else:
withdrawal.amount += 1 withdrawal.amount += 1
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_fail_many_incorrectly_partial(spec, state): def test_invalid_many_incorrectly_partial(spec, state):
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4) prepare_expected_withdrawals(spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
next_slot(spec, state) next_slot(spec, state)
@ -444,6 +518,7 @@ def test_fail_many_incorrectly_partial(spec, state):
withdrawal.address = i.to_bytes(20, 'big') withdrawal.address = i.to_bytes(20, 'big')
else: else:
withdrawal.amount += 1 withdrawal.amount += 1
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False) yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@ -624,7 +699,7 @@ def test_success_excess_balance_but_no_max_effective_balance(spec, state):
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_success_one_partial_withdrawable_not_yet_active(spec, state): def test_success_one_partial_withdrawable_not_yet_active(spec, state):
validator_index = len(state.validators) // 2 validator_index = min(len(state.validators) // 2, spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP - 1)
state.validators[validator_index].activation_epoch += 4 state.validators[validator_index].activation_epoch += 4
set_validator_partially_withdrawable(spec, state, validator_index) set_validator_partially_withdrawable(spec, state, validator_index)
@ -638,7 +713,7 @@ def test_success_one_partial_withdrawable_not_yet_active(spec, state):
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_success_one_partial_withdrawable_in_exit_queue(spec, state): def test_success_one_partial_withdrawable_in_exit_queue(spec, state):
validator_index = len(state.validators) // 2 validator_index = min(len(state.validators) // 2, spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP - 1)
state.validators[validator_index].exit_epoch = spec.get_current_epoch(state) + 1 state.validators[validator_index].exit_epoch = spec.get_current_epoch(state) + 1
set_validator_partially_withdrawable(spec, state, validator_index) set_validator_partially_withdrawable(spec, state, validator_index)
@ -653,7 +728,7 @@ def test_success_one_partial_withdrawable_in_exit_queue(spec, state):
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_success_one_partial_withdrawable_exited(spec, state): def test_success_one_partial_withdrawable_exited(spec, state):
validator_index = len(state.validators) // 2 validator_index = min(len(state.validators) // 2, spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP - 1)
state.validators[validator_index].exit_epoch = spec.get_current_epoch(state) state.validators[validator_index].exit_epoch = spec.get_current_epoch(state)
set_validator_partially_withdrawable(spec, state, validator_index) set_validator_partially_withdrawable(spec, state, validator_index)
@ -667,7 +742,7 @@ def test_success_one_partial_withdrawable_exited(spec, state):
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_success_one_partial_withdrawable_active_and_slashed(spec, state): def test_success_one_partial_withdrawable_active_and_slashed(spec, state):
validator_index = len(state.validators) // 2 validator_index = min(len(state.validators) // 2, spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP - 1)
state.validators[validator_index].slashed = True state.validators[validator_index].slashed = True
set_validator_partially_withdrawable(spec, state, validator_index) set_validator_partially_withdrawable(spec, state, validator_index)
@ -681,7 +756,7 @@ def test_success_one_partial_withdrawable_active_and_slashed(spec, state):
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_success_one_partial_withdrawable_exited_and_slashed(spec, state): def test_success_one_partial_withdrawable_exited_and_slashed(spec, state):
validator_index = len(state.validators) // 2 validator_index = min(len(state.validators) // 2, spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP - 1)
state.validators[validator_index].slashed = True state.validators[validator_index].slashed = True
state.validators[validator_index].exit_epoch = spec.get_current_epoch(state) state.validators[validator_index].exit_epoch = spec.get_current_epoch(state)
set_validator_partially_withdrawable(spec, state, validator_index) set_validator_partially_withdrawable(spec, state, validator_index)

View File

@ -194,8 +194,8 @@ def test_many_partial_withdrawals_in_epoch_transition(spec, state):
def _perform_valid_withdrawal(spec, state): def _perform_valid_withdrawal(spec, state):
fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals( fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals(
spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4, spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 2,
num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4) num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 2)
next_slot(spec, state) next_slot(spec, state)
pre_next_withdrawal_index = state.next_withdrawal_index pre_next_withdrawal_index = state.next_withdrawal_index
@ -240,7 +240,7 @@ def test_withdrawal_success_two_blocks(spec, state):
@with_phases([CAPELLA]) @with_phases([CAPELLA])
@spec_state_test @spec_state_test
def test_withdrawal_fail_second_block_payload_isnt_compatible(spec, state): def test_invalid_withdrawal_fail_second_block_payload_isnt_compatible(spec, state):
_perform_valid_withdrawal(spec, state) _perform_valid_withdrawal(spec, state)
# Block 2 # Block 2

View File

@ -12,7 +12,7 @@ from eth2spec.utils import bls
from .exceptions import SkippedTest from .exceptions import SkippedTest
from .helpers.constants import ( from .helpers.constants import (
PHASE0, ALTAIR, BELLATRIX, CAPELLA, EIP4844, SHARDING, PHASE0, ALTAIR, BELLATRIX, CAPELLA, EIP4844,
MINIMAL, MAINNET, MINIMAL, MAINNET,
ALL_PHASES, ALL_PHASES,
ALL_FORK_UPGRADES, ALL_FORK_UPGRADES,
@ -259,6 +259,12 @@ def dump_skipping_message(reason: str) -> None:
raise SkippedTest(message) raise SkippedTest(message)
def description(case_description: str):
def entry(fn):
return with_meta_tags({'description': case_description})(fn)
return entry
def spec_test(fn): def spec_test(fn):
# Bls switch must be wrapped by vector_test, # Bls switch must be wrapped by vector_test,
# to fully go through the yielded bls switch data, before setting back the BLS setting. # to fully go through the yielded bls switch data, before setting back the BLS setting.
@ -268,7 +274,7 @@ def spec_test(fn):
return vector_test()(bls_switch(fn)) return vector_test()(bls_switch(fn))
# shorthand for decorating @spectest() @with_state @single_phase # shorthand for decorating @spec_test @with_state @single_phase
def spec_state_test(fn): def spec_state_test(fn):
return spec_test(with_state(single_phase(fn))) return spec_test(with_state(single_phase(fn)))
@ -292,31 +298,16 @@ def _check_current_version(spec, state, version_name):
def config_fork_epoch_overrides(spec, state): def config_fork_epoch_overrides(spec, state):
overrides = {}
if state.fork.current_version == spec.config.GENESIS_FORK_VERSION: if state.fork.current_version == spec.config.GENESIS_FORK_VERSION:
pass return {}
elif _check_current_version(spec, state, ALTAIR):
overrides['ALTAIR_FORK_EPOCH'] = spec.GENESIS_EPOCH for fork in ALL_PHASES:
elif _check_current_version(spec, state, BELLATRIX): if fork != PHASE0 and _check_current_version(spec, state, fork):
overrides['ALTAIR_FORK_EPOCH'] = spec.GENESIS_EPOCH overrides = {}
overrides['BELLATRIX_FORK_EPOCH'] = spec.GENESIS_EPOCH for f in ALL_PHASES:
elif _check_current_version(spec, state, CAPELLA): if f != PHASE0 and is_post_fork(fork, f):
overrides['ALTAIR_FORK_EPOCH'] = spec.GENESIS_EPOCH overrides[f.upper() + '_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['BELLATRIX_FORK_EPOCH'] = spec.GENESIS_EPOCH return overrides
overrides['CAPELLA_FORK_EPOCH'] = spec.GENESIS_EPOCH
elif _check_current_version(spec, state, EIP4844):
overrides['ALTAIR_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['BELLATRIX_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['CAPELLA_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['EIP4844_FORK_EPOCH'] = spec.GENESIS_EPOCH
elif _check_current_version(spec, state, SHARDING):
overrides['ALTAIR_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['BELLATRIX_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['CAPELLA_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['SHARDING_FORK_EPOCH'] = spec.GENESIS_EPOCH
else:
assert False # Fork is missing
return overrides
def with_matching_spec_config(emitted_fork=None): def with_matching_spec_config(emitted_fork=None):

View File

@ -8,6 +8,9 @@ from eth2spec.test.context import (
spec_state_test, spec_state_test,
with_eip4844_and_later, with_eip4844_and_later,
) )
from eth2spec.test.helpers.execution_payload import (
compute_el_block_hash,
)
from eth2spec.test.helpers.sharding import ( from eth2spec.test.helpers.sharding import (
get_sample_opaque_tx, get_sample_opaque_tx,
) )
@ -22,6 +25,7 @@ def test_one_blob(spec, state):
opaque_tx, _, blob_kzg_commitments = get_sample_opaque_tx(spec) opaque_tx, _, blob_kzg_commitments = get_sample_opaque_tx(spec)
block.body.blob_kzg_commitments = blob_kzg_commitments block.body.blob_kzg_commitments = blob_kzg_commitments
block.body.execution_payload.transactions = [opaque_tx] block.body.execution_payload.transactions = [opaque_tx]
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
signed_block = state_transition_and_sign_block(spec, state, block) signed_block = state_transition_and_sign_block(spec, state, block)
yield 'blocks', [signed_block] yield 'blocks', [signed_block]
@ -30,13 +34,14 @@ def test_one_blob(spec, state):
@with_eip4844_and_later @with_eip4844_and_later
@spec_state_test @spec_state_test
def test_multiple_blobs(spec, state): def test_max_blobs(spec, state):
yield 'pre', state yield 'pre', state
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
opaque_tx, _, blob_kzg_commitments = get_sample_opaque_tx(spec, blob_count=5) opaque_tx, _, blob_kzg_commitments = get_sample_opaque_tx(spec, blob_count=spec.MAX_BLOBS_PER_BLOCK)
block.body.blob_kzg_commitments = blob_kzg_commitments block.body.blob_kzg_commitments = blob_kzg_commitments
block.body.execution_payload.transactions = [opaque_tx] block.body.execution_payload.transactions = [opaque_tx]
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
signed_block = state_transition_and_sign_block(spec, state, block) signed_block = state_transition_and_sign_block(spec, state, block)
yield 'blocks', [signed_block] yield 'blocks', [signed_block]

View File

@ -8,6 +8,9 @@ from eth2spec.test.context import (
spec_state_test, spec_state_test,
with_eip4844_and_later, with_eip4844_and_later,
) )
from eth2spec.test.helpers.execution_payload import (
compute_el_block_hash,
)
from eth2spec.test.helpers.sharding import ( from eth2spec.test.helpers.sharding import (
get_sample_opaque_tx, get_sample_opaque_tx,
) )
@ -18,6 +21,7 @@ def _run_validate_blobs_sidecar_test(spec, state, blob_count):
opaque_tx, blobs, blob_kzg_commitments = get_sample_opaque_tx(spec, blob_count=blob_count) opaque_tx, blobs, blob_kzg_commitments = get_sample_opaque_tx(spec, blob_count=blob_count)
block.body.blob_kzg_commitments = blob_kzg_commitments block.body.blob_kzg_commitments = blob_kzg_commitments
block.body.execution_payload.transactions = [opaque_tx] block.body.execution_payload.transactions = [opaque_tx]
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
state_transition_and_sign_block(spec, state, block) state_transition_and_sign_block(spec, state, block)
blobs_sidecar = spec.get_blobs_sidecar(block, blobs) blobs_sidecar = spec.get_blobs_sidecar(block, blobs)
@ -45,5 +49,5 @@ def test_validate_blobs_sidecar_two_blobs(spec, state):
@with_eip4844_and_later @with_eip4844_and_later
@spec_state_test @spec_state_test
def test_validate_blobs_sidecar_ten_blobs(spec, state): def test_validate_blobs_sidecar_max_blobs(spec, state):
_run_validate_blobs_sidecar_test(spec, state, blob_count=10) _run_validate_blobs_sidecar_test(spec, state, blob_count=spec.MAX_BLOBS_PER_BLOCK)

View File

@ -208,25 +208,50 @@ def run_deposit_processing(spec, state, deposit, validator_index, valid=True, ef
if not effective or not bls.KeyValidate(deposit.data.pubkey): if not effective or not bls.KeyValidate(deposit.data.pubkey):
assert len(state.validators) == pre_validator_count assert len(state.validators) == pre_validator_count
assert len(state.balances) == pre_validator_count assert len(state.balances) == pre_validator_count
if validator_index < pre_validator_count: if is_top_up:
assert get_balance(state, validator_index) == pre_balance assert get_balance(state, validator_index) == pre_balance
else: else:
if validator_index < pre_validator_count: if is_top_up:
# top-up # Top-ups do not change effective balance
assert state.validators[validator_index].effective_balance == pre_effective_balance
assert len(state.validators) == pre_validator_count assert len(state.validators) == pre_validator_count
assert len(state.balances) == pre_validator_count assert len(state.balances) == pre_validator_count
else: else:
# new validator # new validator
assert len(state.validators) == pre_validator_count + 1 assert len(state.validators) == pre_validator_count + 1
assert len(state.balances) == pre_validator_count + 1 assert len(state.balances) == pre_validator_count + 1
assert get_balance(state, validator_index) == pre_balance + deposit.data.amount
if is_top_up:
# Top-ups do not change effective balance
assert state.validators[validator_index].effective_balance == pre_effective_balance
else:
effective_balance = min(spec.MAX_EFFECTIVE_BALANCE, deposit.data.amount) effective_balance = min(spec.MAX_EFFECTIVE_BALANCE, deposit.data.amount)
effective_balance -= effective_balance % spec.EFFECTIVE_BALANCE_INCREMENT effective_balance -= effective_balance % spec.EFFECTIVE_BALANCE_INCREMENT
assert state.validators[validator_index].effective_balance == effective_balance assert state.validators[validator_index].effective_balance == effective_balance
assert get_balance(state, validator_index) == pre_balance + deposit.data.amount
assert state.eth1_deposit_index == state.eth1_data.deposit_count assert state.eth1_deposit_index == state.eth1_data.deposit_count
def run_deposit_processing_with_specific_fork_version(
spec,
state,
fork_version,
valid=True,
effective=True):
validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE
pubkey = pubkeys[validator_index]
privkey = privkeys[validator_index]
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkey)[1:]
deposit_message = spec.DepositMessage(pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount)
domain = spec.compute_domain(domain_type=spec.DOMAIN_DEPOSIT, fork_version=fork_version)
deposit_data = spec.DepositData(
pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount,
signature=bls.Sign(privkey, spec.compute_signing_root(deposit_message, domain))
)
deposit, root, _ = deposit_from_context(spec, [deposit_data], 0)
state.eth1_deposit_index = 0
state.eth1_data.deposit_root = root
state.eth1_data.deposit_count = 1
yield from run_deposit_processing(spec, state, deposit, validator_index, valid=valid, effective=effective)

View File

@ -1,68 +1,10 @@
from eth_hash.auto import keccak
from trie import HexaryTrie
from rlp import encode
from rlp.sedes import big_endian_int, Binary, List
from eth2spec.debug.random_value import get_random_bytes_list from eth2spec.debug.random_value import get_random_bytes_list
from eth2spec.test.helpers.forks import is_post_capella from eth2spec.test.helpers.forks import is_post_capella, is_post_eip4844
def build_empty_execution_payload(spec, state, randao_mix=None):
"""
Assuming a pre-state of the same slot, build a valid ExecutionPayload without any transactions.
"""
latest = state.latest_execution_payload_header
timestamp = spec.compute_timestamp_at_slot(state, state.slot)
empty_txs = spec.List[spec.Transaction, spec.MAX_TRANSACTIONS_PER_PAYLOAD]()
if randao_mix is None:
randao_mix = spec.get_randao_mix(state, spec.get_current_epoch(state))
payload = spec.ExecutionPayload(
parent_hash=latest.block_hash,
fee_recipient=spec.ExecutionAddress(),
state_root=latest.state_root, # no changes to the state
receipts_root=b"no receipts here" + b"\x00" * 16, # TODO: root of empty MPT may be better.
logs_bloom=spec.ByteVector[spec.BYTES_PER_LOGS_BLOOM](), # TODO: zeroed logs bloom for empty logs ok?
block_number=latest.block_number + 1,
prev_randao=randao_mix,
gas_limit=latest.gas_limit, # retain same limit
gas_used=0, # empty block, 0 gas
timestamp=timestamp,
extra_data=spec.ByteList[spec.MAX_EXTRA_DATA_BYTES](),
base_fee_per_gas=latest.base_fee_per_gas, # retain same base_fee
block_hash=spec.Hash32(),
transactions=empty_txs,
)
if is_post_capella(spec):
payload.withdrawals = spec.get_expected_withdrawals(state)
# TODO: real RLP + block hash logic would be nice, requires RLP and keccak256 dependency however.
payload.block_hash = spec.Hash32(spec.hash(payload.hash_tree_root() + b"FAKE RLP HASH"))
return payload
def build_randomized_execution_payload(spec, state, rng):
execution_payload = build_empty_execution_payload(spec, state)
execution_payload.fee_recipient = spec.ExecutionAddress(get_random_bytes_list(rng, 20))
execution_payload.state_root = spec.Bytes32(get_random_bytes_list(rng, 32))
execution_payload.receipts_root = spec.Bytes32(get_random_bytes_list(rng, 32))
execution_payload.logs_bloom = spec.ByteVector[spec.BYTES_PER_LOGS_BLOOM](
get_random_bytes_list(rng, spec.BYTES_PER_LOGS_BLOOM)
)
execution_payload.block_number = rng.randint(0, 10e10)
execution_payload.gas_limit = rng.randint(0, 10e10)
execution_payload.gas_used = rng.randint(0, 10e10)
extra_data_length = rng.randint(0, spec.MAX_EXTRA_DATA_BYTES)
execution_payload.extra_data = spec.ByteList[spec.MAX_EXTRA_DATA_BYTES](
get_random_bytes_list(rng, extra_data_length)
)
execution_payload.base_fee_per_gas = rng.randint(0, 2**256 - 1)
execution_payload.block_hash = spec.Hash32(get_random_bytes_list(rng, 32))
num_transactions = rng.randint(0, 100)
execution_payload.transactions = [
spec.Transaction(get_random_bytes_list(rng, rng.randint(0, 1000)))
for _ in range(num_transactions)
]
return execution_payload
def get_execution_payload_header(spec, execution_payload): def get_execution_payload_header(spec, execution_payload):
@ -87,6 +29,174 @@ def get_execution_payload_header(spec, execution_payload):
return payload_header return payload_header
# https://eips.ethereum.org/EIPS/eip-2718
def compute_trie_root_from_indexed_data(data):
"""
Computes the root hash of `patriciaTrie(rlp(Index) => Data)` for a data array.
"""
t = HexaryTrie(db={})
for i, obj in enumerate(data):
k = encode(i, big_endian_int)
t.set(k, obj)
return t.root_hash
# https://eips.ethereum.org/EIPS/eip-4895
# https://eips.ethereum.org/EIPS/eip-4844
def compute_el_header_block_hash(spec,
payload_header,
transactions_trie_root,
withdrawals_trie_root=None):
"""
Computes the RLP execution block hash described by an `ExecutionPayloadHeader`.
"""
execution_payload_header_rlp = [
# parent_hash
(Binary(32, 32), payload_header.parent_hash),
# ommers_hash
(Binary(32, 32), bytes.fromhex("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")),
# coinbase
(Binary(20, 20), payload_header.fee_recipient),
# state_root
(Binary(32, 32), payload_header.state_root),
# txs_root
(Binary(32, 32), transactions_trie_root),
# receipts_root
(Binary(32, 32), payload_header.receipts_root),
# logs_bloom
(Binary(256, 256), payload_header.logs_bloom),
# difficulty
(big_endian_int, 0),
# number
(big_endian_int, payload_header.block_number),
# gas_limit
(big_endian_int, payload_header.gas_limit),
# gas_used
(big_endian_int, payload_header.gas_used),
# timestamp
(big_endian_int, payload_header.timestamp),
# extradata
(Binary(0, 32), payload_header.extra_data),
# prev_randao
(Binary(32, 32), payload_header.prev_randao),
# nonce
(Binary(8, 8), bytes.fromhex("0000000000000000")),
# base_fee_per_gas
(big_endian_int, payload_header.base_fee_per_gas),
]
if is_post_capella(spec):
# withdrawals_root
execution_payload_header_rlp.append((Binary(32, 32), withdrawals_trie_root))
if is_post_eip4844(spec):
# excess_data_gas
execution_payload_header_rlp.append((big_endian_int, payload_header.excess_data_gas))
sedes = List([schema for schema, _ in execution_payload_header_rlp])
values = [value for _, value in execution_payload_header_rlp]
encoded = encode(values, sedes)
return spec.Hash32(keccak(encoded))
# https://eips.ethereum.org/EIPS/eip-4895
def get_withdrawal_rlp(spec, withdrawal):
withdrawal_rlp = [
# index
(big_endian_int, withdrawal.index),
# validator_index
(big_endian_int, withdrawal.validator_index),
# address
(Binary(20, 20), withdrawal.address),
# amount
(big_endian_int, spec.uint256(withdrawal.amount) * (10**9)),
]
sedes = List([schema for schema, _ in withdrawal_rlp])
values = [value for _, value in withdrawal_rlp]
return encode(values, sedes)
def compute_el_block_hash(spec, payload):
transactions_trie_root = compute_trie_root_from_indexed_data(payload.transactions)
if is_post_capella(spec):
withdrawals_encoded = [get_withdrawal_rlp(spec, withdrawal) for withdrawal in payload.withdrawals]
withdrawals_trie_root = compute_trie_root_from_indexed_data(withdrawals_encoded)
else:
withdrawals_trie_root = None
payload_header = get_execution_payload_header(spec, payload)
return compute_el_header_block_hash(
spec,
payload_header,
transactions_trie_root,
withdrawals_trie_root,
)
def build_empty_execution_payload(spec, state, randao_mix=None):
"""
Assuming a pre-state of the same slot, build a valid ExecutionPayload without any transactions.
"""
latest = state.latest_execution_payload_header
timestamp = spec.compute_timestamp_at_slot(state, state.slot)
empty_txs = spec.List[spec.Transaction, spec.MAX_TRANSACTIONS_PER_PAYLOAD]()
if randao_mix is None:
randao_mix = spec.get_randao_mix(state, spec.get_current_epoch(state))
payload = spec.ExecutionPayload(
parent_hash=latest.block_hash,
fee_recipient=spec.ExecutionAddress(),
state_root=latest.state_root, # no changes to the state
receipts_root=spec.Bytes32(bytes.fromhex("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")),
logs_bloom=spec.ByteVector[spec.BYTES_PER_LOGS_BLOOM](), # TODO: zeroed logs bloom for empty logs ok?
block_number=latest.block_number + 1,
prev_randao=randao_mix,
gas_limit=latest.gas_limit, # retain same limit
gas_used=0, # empty block, 0 gas
timestamp=timestamp,
extra_data=spec.ByteList[spec.MAX_EXTRA_DATA_BYTES](),
base_fee_per_gas=latest.base_fee_per_gas, # retain same base_fee
transactions=empty_txs,
)
if is_post_capella(spec):
payload.withdrawals = spec.get_expected_withdrawals(state)
payload.block_hash = compute_el_block_hash(spec, payload)
return payload
def build_randomized_execution_payload(spec, state, rng):
execution_payload = build_empty_execution_payload(spec, state)
execution_payload.fee_recipient = spec.ExecutionAddress(get_random_bytes_list(rng, 20))
execution_payload.state_root = spec.Bytes32(get_random_bytes_list(rng, 32))
execution_payload.receipts_root = spec.Bytes32(get_random_bytes_list(rng, 32))
execution_payload.logs_bloom = spec.ByteVector[spec.BYTES_PER_LOGS_BLOOM](
get_random_bytes_list(rng, spec.BYTES_PER_LOGS_BLOOM)
)
execution_payload.block_number = rng.randint(0, 10e10)
execution_payload.gas_limit = rng.randint(0, 10e10)
execution_payload.gas_used = rng.randint(0, 10e10)
extra_data_length = rng.randint(0, spec.MAX_EXTRA_DATA_BYTES)
execution_payload.extra_data = spec.ByteList[spec.MAX_EXTRA_DATA_BYTES](
get_random_bytes_list(rng, extra_data_length)
)
execution_payload.base_fee_per_gas = rng.randint(0, 2**256 - 1)
num_transactions = rng.randint(0, 100)
execution_payload.transactions = [
spec.Transaction(get_random_bytes_list(rng, rng.randint(0, 1000)))
for _ in range(num_transactions)
]
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)
return execution_payload
def build_state_with_incomplete_transition(spec, state): def build_state_with_incomplete_transition(spec, state):
state = build_state_with_execution_payload_header(spec, state, spec.ExecutionPayloadHeader()) state = build_state_with_execution_payload_header(spec, state, spec.ExecutionPayloadHeader())
assert not spec.is_merge_transition_complete(state) assert not spec.is_merge_transition_complete(state)

View File

@ -1,8 +1,11 @@
from eth2spec.test.helpers.constants import ( from eth2spec.test.helpers.constants import (
ALTAIR, BELLATRIX, CAPELLA, EIP4844, ALTAIR, BELLATRIX, CAPELLA, EIP4844,
) )
from eth2spec.test.helpers.execution_payload import (
compute_el_header_block_hash,
)
from eth2spec.test.helpers.forks import ( from eth2spec.test.helpers.forks import (
is_post_altair, is_post_bellatrix, is_post_altair, is_post_bellatrix, is_post_capella,
) )
from eth2spec.test.helpers.keys import pubkeys from eth2spec.test.helpers.keys import pubkeys
@ -29,7 +32,7 @@ def get_sample_genesis_execution_payload_header(spec,
eth1_block_hash=None): eth1_block_hash=None):
if eth1_block_hash is None: if eth1_block_hash is None:
eth1_block_hash = b'\x55' * 32 eth1_block_hash = b'\x55' * 32
return spec.ExecutionPayloadHeader( payload_header = spec.ExecutionPayloadHeader(
parent_hash=b'\x30' * 32, parent_hash=b'\x30' * 32,
fee_recipient=b'\x42' * 20, fee_recipient=b'\x42' * 20,
state_root=b'\x20' * 32, state_root=b'\x20' * 32,
@ -43,6 +46,21 @@ def get_sample_genesis_execution_payload_header(spec,
transactions_root=spec.Root(b'\x56' * 32), transactions_root=spec.Root(b'\x56' * 32),
) )
transactions_trie_root = bytes.fromhex("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
if is_post_capella(spec):
withdrawals_trie_root = bytes.fromhex("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
else:
withdrawals_trie_root = None
payload_header.block_hash = compute_el_header_block_hash(
spec,
payload_header,
transactions_trie_root,
withdrawals_trie_root,
)
return payload_header
def create_genesis_state(spec, validator_balances, activation_threshold): def create_genesis_state(spec, validator_balances, activation_threshold):
deposit_root = b'\x42' * 32 deposit_root = b'\x42' * 32

View File

@ -36,9 +36,10 @@ def set_validator_partially_withdrawable(spec, state, index, excess_balance=1000
def prepare_expected_withdrawals(spec, state, def prepare_expected_withdrawals(spec, state,
num_full_withdrawals=0, num_partial_withdrawals=0, rng=random.Random(5566)): num_full_withdrawals=0, num_partial_withdrawals=0, rng=random.Random(5566)):
assert num_full_withdrawals + num_partial_withdrawals <= len(state.validators) bound = min(len(state.validators), spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP)
all_validator_indices = list(range(len(state.validators))) assert num_full_withdrawals + num_partial_withdrawals <= bound
sampled_indices = rng.sample(all_validator_indices, num_full_withdrawals + num_partial_withdrawals) eligible_validator_indices = list(range(bound))
sampled_indices = rng.sample(eligible_validator_indices, num_full_withdrawals + num_partial_withdrawals)
fully_withdrawable_indices = rng.sample(sampled_indices, num_full_withdrawals) fully_withdrawable_indices = rng.sample(sampled_indices, num_full_withdrawals)
partial_withdrawals_indices = list(set(sampled_indices).difference(set(fully_withdrawable_indices))) partial_withdrawals_indices = list(set(sampled_indices).difference(set(fully_withdrawable_indices)))

View File

@ -23,7 +23,7 @@ from eth2spec.utils.ssz.ssz_typing import Bitlist
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_success(spec, state): def test_one_basic_attestation(spec, state):
attestation = get_valid_attestation(spec, state, signed=True) attestation = get_valid_attestation(spec, state, signed=True)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
@ -34,7 +34,7 @@ def test_success(spec, state):
@spec_test @spec_test
@with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE) @with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE)
@single_phase @single_phase
def test_success_multi_proposer_index_iterations(spec, state): def test_multi_proposer_index_iterations(spec, state):
next_slots(spec, state, spec.SLOTS_PER_EPOCH * 2) next_slots(spec, state, spec.SLOTS_PER_EPOCH * 2)
attestation = get_valid_attestation(spec, state, signed=True) attestation = get_valid_attestation(spec, state, signed=True)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
@ -44,7 +44,7 @@ def test_success_multi_proposer_index_iterations(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_success_previous_epoch(spec, state): def test_previous_epoch(spec, state):
attestation = get_valid_attestation(spec, state, signed=True) attestation = get_valid_attestation(spec, state, signed=True)
next_epoch_via_block(spec, state) next_epoch_via_block(spec, state)
@ -58,55 +58,55 @@ def test_invalid_attestation_signature(spec, state):
attestation = get_valid_attestation(spec, state) attestation = get_valid_attestation(spec, state)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_empty_participants_zeroes_sig(spec, state): def test_invalid_empty_participants_zeroes_sig(spec, state):
attestation = get_valid_attestation(spec, state, filter_participant_set=lambda comm: []) # 0 participants attestation = get_valid_attestation(spec, state, filter_participant_set=lambda comm: []) # 0 participants
attestation.signature = spec.BLSSignature(b'\x00' * 96) attestation.signature = spec.BLSSignature(b'\x00' * 96)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_empty_participants_seemingly_valid_sig(spec, state): def test_invalid_empty_participants_seemingly_valid_sig(spec, state):
attestation = get_valid_attestation(spec, state, filter_participant_set=lambda comm: []) # 0 participants attestation = get_valid_attestation(spec, state, filter_participant_set=lambda comm: []) # 0 participants
# Special BLS value, valid for zero pubkeys on some (but not all) BLS implementations. # Special BLS value, valid for zero pubkeys on some (but not all) BLS implementations.
attestation.signature = spec.BLSSignature(b'\xc0' + b'\x00' * 95) attestation.signature = spec.BLSSignature(b'\xc0' + b'\x00' * 95)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_before_inclusion_delay(spec, state): def test_invalid_before_inclusion_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=True) attestation = get_valid_attestation(spec, state, signed=True)
# do not increment slot to allow for inclusion delay # do not increment slot to allow for inclusion delay
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_after_epoch_slots(spec, state): def test_invalid_after_epoch_slots(spec, state):
attestation = get_valid_attestation(spec, state, signed=True) attestation = get_valid_attestation(spec, state, signed=True)
# increment past latest inclusion slot # increment past latest inclusion slot
transition_to_slot_via_block(spec, state, state.slot + spec.SLOTS_PER_EPOCH + 1) transition_to_slot_via_block(spec, state, state.slot + spec.SLOTS_PER_EPOCH + 1)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_old_source_epoch(spec, state): def test_invalid_old_source_epoch(spec, state):
next_slots(spec, state, spec.SLOTS_PER_EPOCH * 5) next_slots(spec, state, spec.SLOTS_PER_EPOCH * 5)
state.finalized_checkpoint.epoch = 2 state.finalized_checkpoint.epoch = 2
state.previous_justified_checkpoint.epoch = 3 state.previous_justified_checkpoint.epoch = 3
@ -121,19 +121,19 @@ def test_old_source_epoch(spec, state):
sign_attestation(spec, state, attestation) sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_wrong_index_for_committee_signature(spec, state): def test_invalid_wrong_index_for_committee_signature(spec, state):
attestation = get_valid_attestation(spec, state) attestation = get_valid_attestation(spec, state)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
attestation.data.index += 1 attestation.data.index += 1
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
def reduce_state_committee_count_from_max(spec, state): def reduce_state_committee_count_from_max(spec, state):
@ -148,7 +148,7 @@ def reduce_state_committee_count_from_max(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@never_bls @never_bls
def test_wrong_index_for_slot_0(spec, state): def test_invalid_wrong_index_for_slot_0(spec, state):
reduce_state_committee_count_from_max(spec, state) reduce_state_committee_count_from_max(spec, state)
attestation = get_valid_attestation(spec, state) attestation = get_valid_attestation(spec, state)
@ -157,13 +157,13 @@ def test_wrong_index_for_slot_0(spec, state):
# Invalid index: current committees per slot is less than the max # Invalid index: current committees per slot is less than the max
attestation.data.index = spec.MAX_COMMITTEES_PER_SLOT - 1 attestation.data.index = spec.MAX_COMMITTEES_PER_SLOT - 1
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@never_bls @never_bls
def test_wrong_index_for_slot_1(spec, state): def test_invalid_wrong_index_for_slot_1(spec, state):
reduce_state_committee_count_from_max(spec, state) reduce_state_committee_count_from_max(spec, state)
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
@ -175,7 +175,7 @@ def test_wrong_index_for_slot_1(spec, state):
# Invalid index: off by one # Invalid index: off by one
attestation.data.index = committee_count attestation.data.index = committee_count
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@ -188,12 +188,12 @@ def test_invalid_index(spec, state):
# Invalid index: off by one (with respect to valid range) on purpose # Invalid index: off by one (with respect to valid range) on purpose
attestation.data.index = spec.MAX_COMMITTEES_PER_SLOT attestation.data.index = spec.MAX_COMMITTEES_PER_SLOT
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_mismatched_target_and_slot(spec, state): def test_invalid_mismatched_target_and_slot(spec, state):
next_epoch_via_block(spec, state) next_epoch_via_block(spec, state)
next_epoch_via_block(spec, state) next_epoch_via_block(spec, state)
@ -202,24 +202,24 @@ def test_mismatched_target_and_slot(spec, state):
sign_attestation(spec, state, attestation) sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_old_target_epoch(spec, state): def test_invalid_old_target_epoch(spec, state):
assert spec.MIN_ATTESTATION_INCLUSION_DELAY < spec.SLOTS_PER_EPOCH * 2 assert spec.MIN_ATTESTATION_INCLUSION_DELAY < spec.SLOTS_PER_EPOCH * 2
attestation = get_valid_attestation(spec, state, signed=True) attestation = get_valid_attestation(spec, state, signed=True)
next_slots(spec, state, spec.SLOTS_PER_EPOCH * 2) # target epoch will be too old to handle next_slots(spec, state, spec.SLOTS_PER_EPOCH * 2) # target epoch will be too old to handle
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_future_target_epoch(spec, state): def test_invalid_future_target_epoch(spec, state):
assert spec.MIN_ATTESTATION_INCLUSION_DELAY < spec.SLOTS_PER_EPOCH * 2 assert spec.MIN_ATTESTATION_INCLUSION_DELAY < spec.SLOTS_PER_EPOCH * 2
attestation = get_valid_attestation(spec, state) attestation = get_valid_attestation(spec, state)
@ -236,12 +236,12 @@ def test_future_target_epoch(spec, state):
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_new_source_epoch(spec, state): def test_invalid_new_source_epoch(spec, state):
attestation = get_valid_attestation(spec, state) attestation = get_valid_attestation(spec, state)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
@ -249,12 +249,12 @@ def test_new_source_epoch(spec, state):
sign_attestation(spec, state, attestation) sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_source_root_is_target_root(spec, state): def test_invalid_source_root_is_target_root(spec, state):
attestation = get_valid_attestation(spec, state) attestation = get_valid_attestation(spec, state)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
@ -262,7 +262,7 @@ def test_source_root_is_target_root(spec, state):
sign_attestation(spec, state, attestation) sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@ -289,7 +289,7 @@ def test_invalid_current_source_root(spec, state):
sign_attestation(spec, state, attestation) sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@ -315,12 +315,12 @@ def test_invalid_previous_source_root(spec, state):
sign_attestation(spec, state, attestation) sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_bad_source_root(spec, state): def test_invalid_bad_source_root(spec, state):
attestation = get_valid_attestation(spec, state) attestation = get_valid_attestation(spec, state)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
@ -328,24 +328,24 @@ def test_bad_source_root(spec, state):
sign_attestation(spec, state, attestation) sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_too_many_aggregation_bits(spec, state): def test_invalid_too_many_aggregation_bits(spec, state):
attestation = get_valid_attestation(spec, state, signed=True) attestation = get_valid_attestation(spec, state, signed=True)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
# one too many bits # one too many bits
attestation.aggregation_bits.append(0b0) attestation.aggregation_bits.append(0b0)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_too_few_aggregation_bits(spec, state): def test_invalid_too_few_aggregation_bits(spec, state):
attestation = get_valid_attestation(spec, state) attestation = get_valid_attestation(spec, state)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
@ -357,7 +357,7 @@ def test_too_few_aggregation_bits(spec, state):
# one too few bits # one too few bits
attestation.aggregation_bits = attestation.aggregation_bits[:-1] attestation.aggregation_bits = attestation.aggregation_bits[:-1]
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
# #
@ -366,7 +366,7 @@ def test_too_few_aggregation_bits(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_correct_min_inclusion_delay(spec, state): def test_correct_attestation_included_at_min_inclusion_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=True) attestation = get_valid_attestation(spec, state, signed=True)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
@ -375,7 +375,7 @@ def test_correct_min_inclusion_delay(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_correct_sqrt_epoch_delay(spec, state): def test_correct_attestation_included_at_sqrt_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=True) attestation = get_valid_attestation(spec, state, signed=True)
next_slots(spec, state, spec.integer_squareroot(spec.SLOTS_PER_EPOCH)) next_slots(spec, state, spec.integer_squareroot(spec.SLOTS_PER_EPOCH))
@ -384,7 +384,7 @@ def test_correct_sqrt_epoch_delay(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_correct_epoch_delay(spec, state): def test_correct_attestation_included_at_one_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=True) attestation = get_valid_attestation(spec, state, signed=True)
next_slots(spec, state, spec.SLOTS_PER_EPOCH) next_slots(spec, state, spec.SLOTS_PER_EPOCH)
@ -393,13 +393,13 @@ def test_correct_epoch_delay(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_correct_after_epoch_delay(spec, state): def test_invalid_correct_attestation_included_after_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=True) attestation = get_valid_attestation(spec, state, signed=True)
# increment past latest inclusion slot # increment past latest inclusion slot
next_slots(spec, state, spec.SLOTS_PER_EPOCH + 1) next_slots(spec, state, spec.SLOTS_PER_EPOCH + 1)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
# #
@ -408,7 +408,7 @@ def test_correct_after_epoch_delay(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_incorrect_head_min_inclusion_delay(spec, state): def test_incorrect_head_included_at_min_inclusion_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False) attestation = get_valid_attestation(spec, state, signed=False)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
@ -420,7 +420,7 @@ def test_incorrect_head_min_inclusion_delay(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_incorrect_head_sqrt_epoch_delay(spec, state): def test_incorrect_head_included_at_sqrt_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False) attestation = get_valid_attestation(spec, state, signed=False)
next_slots(spec, state, spec.integer_squareroot(spec.SLOTS_PER_EPOCH)) next_slots(spec, state, spec.integer_squareroot(spec.SLOTS_PER_EPOCH))
@ -432,7 +432,7 @@ def test_incorrect_head_sqrt_epoch_delay(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_incorrect_head_epoch_delay(spec, state): def test_incorrect_head_included_at_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False) attestation = get_valid_attestation(spec, state, signed=False)
next_slots(spec, state, spec.SLOTS_PER_EPOCH) next_slots(spec, state, spec.SLOTS_PER_EPOCH)
@ -444,7 +444,7 @@ def test_incorrect_head_epoch_delay(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_incorrect_head_after_epoch_delay(spec, state): def test_invalid_incorrect_head_included_after_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False) attestation = get_valid_attestation(spec, state, signed=False)
# increment past latest inclusion slot # increment past latest inclusion slot
@ -453,7 +453,7 @@ def test_incorrect_head_after_epoch_delay(spec, state):
attestation.data.beacon_block_root = b'\x42' * 32 attestation.data.beacon_block_root = b'\x42' * 32
sign_attestation(spec, state, attestation) sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
# #
@ -475,7 +475,7 @@ def test_incorrect_head_and_target_min_inclusion_delay(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_incorrect_head_and_target_sqrt_epoch_delay(spec, state): def test_incorrect_head_and_target_included_at_sqrt_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False) attestation = get_valid_attestation(spec, state, signed=False)
next_slots(spec, state, spec.integer_squareroot(spec.SLOTS_PER_EPOCH)) next_slots(spec, state, spec.integer_squareroot(spec.SLOTS_PER_EPOCH))
@ -488,7 +488,7 @@ def test_incorrect_head_and_target_sqrt_epoch_delay(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_incorrect_head_and_target_epoch_delay(spec, state): def test_incorrect_head_and_target_included_at_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False) attestation = get_valid_attestation(spec, state, signed=False)
next_slots(spec, state, spec.SLOTS_PER_EPOCH) next_slots(spec, state, spec.SLOTS_PER_EPOCH)
@ -501,7 +501,7 @@ def test_incorrect_head_and_target_epoch_delay(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_incorrect_head_and_target_after_epoch_delay(spec, state): def test_invalid_incorrect_head_and_target_included_after_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False) attestation = get_valid_attestation(spec, state, signed=False)
# increment past latest inclusion slot # increment past latest inclusion slot
next_slots(spec, state, spec.SLOTS_PER_EPOCH + 1) next_slots(spec, state, spec.SLOTS_PER_EPOCH + 1)
@ -510,7 +510,7 @@ def test_incorrect_head_and_target_after_epoch_delay(spec, state):
attestation.data.target.root = b'\x42' * 32 attestation.data.target.root = b'\x42' * 32
sign_attestation(spec, state, attestation) sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)
# #
@ -519,7 +519,7 @@ def test_incorrect_head_and_target_after_epoch_delay(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_incorrect_target_min_inclusion_delay(spec, state): def test_incorrect_target_included_at_min_inclusion_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False) attestation = get_valid_attestation(spec, state, signed=False)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
@ -531,7 +531,7 @@ def test_incorrect_target_min_inclusion_delay(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_incorrect_target_sqrt_epoch_delay(spec, state): def test_incorrect_target_included_at_sqrt_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False) attestation = get_valid_attestation(spec, state, signed=False)
next_slots(spec, state, spec.integer_squareroot(spec.SLOTS_PER_EPOCH)) next_slots(spec, state, spec.integer_squareroot(spec.SLOTS_PER_EPOCH))
@ -543,7 +543,7 @@ def test_incorrect_target_sqrt_epoch_delay(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_incorrect_target_epoch_delay(spec, state): def test_incorrect_target_included_at_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False) attestation = get_valid_attestation(spec, state, signed=False)
next_slots(spec, state, spec.SLOTS_PER_EPOCH) next_slots(spec, state, spec.SLOTS_PER_EPOCH)
@ -555,7 +555,7 @@ def test_incorrect_target_epoch_delay(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_incorrect_target_after_epoch_delay(spec, state): def test_invalid_incorrect_target_included_after_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False) attestation = get_valid_attestation(spec, state, signed=False)
# increment past latest inclusion slot # increment past latest inclusion slot
next_slots(spec, state, spec.SLOTS_PER_EPOCH + 1) next_slots(spec, state, spec.SLOTS_PER_EPOCH + 1)
@ -563,4 +563,4 @@ def test_incorrect_target_after_epoch_delay(spec, state):
attestation.data.target.root = b'\x42' * 32 attestation.data.target.root = b'\x42' * 32
sign_attestation(spec, state, attestation) sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, valid=False)

View File

@ -91,7 +91,7 @@ def run_attester_slashing_processing(spec, state, attester_slashing, valid=True)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_success_double(spec, state): def test_basic_double(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True)
yield from run_attester_slashing_processing(spec, state, attester_slashing) yield from run_attester_slashing_processing(spec, state, attester_slashing)
@ -99,7 +99,7 @@ def test_success_double(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_success_surround(spec, state): def test_basic_surround(spec, state):
next_epoch_via_block(spec, state) next_epoch_via_block(spec, state)
state.current_justified_checkpoint.epoch += 1 state.current_justified_checkpoint.epoch += 1
@ -119,7 +119,7 @@ def test_success_surround(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_success_already_exited_recent(spec, state): def test_already_exited_recent(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True)
slashed_indices = get_indexed_attestation_participants(spec, attester_slashing.attestation_1) slashed_indices = get_indexed_attestation_participants(spec, attester_slashing.attestation_1)
for index in slashed_indices: for index in slashed_indices:
@ -131,7 +131,7 @@ def test_success_already_exited_recent(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_success_proposer_index_slashed(spec, state): def test_proposer_index_slashed(spec, state):
# Transition past genesis slot because generally doesn't have a proposer # Transition past genesis slot because generally doesn't have a proposer
next_epoch_via_block(spec, state) next_epoch_via_block(spec, state)
@ -147,7 +147,7 @@ def test_success_proposer_index_slashed(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_success_attestation_from_future(spec, state): def test_attestation_from_future(spec, state):
# Transition state to future to enable generation of a "future" attestation # Transition state to future to enable generation of a "future" attestation
future_state = state.copy() future_state = state.copy()
next_epoch_via_block(spec, future_state) next_epoch_via_block(spec, future_state)
@ -165,7 +165,7 @@ def test_success_attestation_from_future(spec, state):
@with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE) @with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE)
@spec_test @spec_test
@single_phase @single_phase
def test_success_low_balances(spec, state): def test_low_balances(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True)
yield from run_attester_slashing_processing(spec, state, attester_slashing) yield from run_attester_slashing_processing(spec, state, attester_slashing)
@ -175,7 +175,7 @@ def test_success_low_balances(spec, state):
@with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE) @with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE)
@spec_test @spec_test
@single_phase @single_phase
def test_success_misc_balances(spec, state): def test_misc_balances(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True)
yield from run_attester_slashing_processing(spec, state, attester_slashing) yield from run_attester_slashing_processing(spec, state, attester_slashing)
@ -185,7 +185,7 @@ def test_success_misc_balances(spec, state):
@with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE) @with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE)
@spec_test @spec_test
@single_phase @single_phase
def test_success_with_effective_balance_disparity(spec, state): def test_with_effective_balance_disparity(spec, state):
# Jitter balances to be different from effective balances # Jitter balances to be different from effective balances
rng = Random(12345) rng = Random(12345)
for i in range(len(state.balances)): for i in range(len(state.balances)):
@ -200,7 +200,7 @@ def test_success_with_effective_balance_disparity(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_success_already_exited_long_ago(spec, state): def test_already_exited_long_ago(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True)
slashed_indices = get_indexed_attestation_participants(spec, attester_slashing.attestation_1) slashed_indices = get_indexed_attestation_participants(spec, attester_slashing.attestation_1)
for index in slashed_indices: for index in slashed_indices:
@ -213,30 +213,30 @@ def test_success_already_exited_long_ago(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_sig_1(spec, state): def test_invalid_incorrect_sig_1(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True)
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_sig_2(spec, state): def test_invalid_incorrect_sig_2(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=False) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=False)
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_sig_1_and_2(spec, state): def test_invalid_incorrect_sig_1_and_2(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=False) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=False)
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_same_data(spec, state): def test_invalid_same_data(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True)
indexed_att_1 = attester_slashing.attestation_1 indexed_att_1 = attester_slashing.attestation_1
@ -244,12 +244,12 @@ def test_same_data(spec, state):
indexed_att_1.data = att_2_data indexed_att_1.data = att_2_data
sign_indexed_attestation(spec, state, attester_slashing.attestation_1) sign_indexed_attestation(spec, state, attester_slashing.attestation_1)
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_no_double_or_surround(spec, state): def test_invalid_no_double_or_surround(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True)
att_1_data = get_attestation_1_data(spec, attester_slashing) att_1_data = get_attestation_1_data(spec, attester_slashing)
@ -257,12 +257,12 @@ def test_no_double_or_surround(spec, state):
sign_indexed_attestation(spec, state, attester_slashing.attestation_1) sign_indexed_attestation(spec, state, attester_slashing.attestation_1)
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_participants_already_slashed(spec, state): def test_invalid_participants_already_slashed(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True)
# set all indices to slashed # set all indices to slashed
@ -270,63 +270,63 @@ def test_participants_already_slashed(spec, state):
for index in validator_indices: for index in validator_indices:
state.validators[index].slashed = True state.validators[index].slashed = True
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_att1_high_index(spec, state): def test_invalid_att1_high_index(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True)
indices = get_indexed_attestation_participants(spec, attester_slashing.attestation_1) indices = get_indexed_attestation_participants(spec, attester_slashing.attestation_1)
indices.append(spec.ValidatorIndex(len(state.validators))) # off by 1 indices.append(spec.ValidatorIndex(len(state.validators))) # off by 1
attester_slashing.attestation_1.attesting_indices = indices attester_slashing.attestation_1.attesting_indices = indices
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_att2_high_index(spec, state): def test_invalid_att2_high_index(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True)
indices = get_indexed_attestation_participants(spec, attester_slashing.attestation_2) indices = get_indexed_attestation_participants(spec, attester_slashing.attestation_2)
indices.append(spec.ValidatorIndex(len(state.validators))) # off by 1 indices.append(spec.ValidatorIndex(len(state.validators))) # off by 1
attester_slashing.attestation_2.attesting_indices = indices attester_slashing.attestation_2.attesting_indices = indices
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_att1_empty_indices(spec, state): def test_invalid_att1_empty_indices(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True)
attester_slashing.attestation_1.attesting_indices = [] attester_slashing.attestation_1.attesting_indices = []
attester_slashing.attestation_1.signature = spec.bls.G2_POINT_AT_INFINITY attester_slashing.attestation_1.signature = spec.bls.G2_POINT_AT_INFINITY
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_att2_empty_indices(spec, state): def test_invalid_att2_empty_indices(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=False) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=False)
attester_slashing.attestation_2.attesting_indices = [] attester_slashing.attestation_2.attesting_indices = []
attester_slashing.attestation_2.signature = spec.bls.G2_POINT_AT_INFINITY attester_slashing.attestation_2.signature = spec.bls.G2_POINT_AT_INFINITY
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_all_empty_indices(spec, state): def test_invalid_all_empty_indices(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=False) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=False)
attester_slashing.attestation_1.attesting_indices = [] attester_slashing.attestation_1.attesting_indices = []
@ -335,13 +335,13 @@ def test_all_empty_indices(spec, state):
attester_slashing.attestation_2.attesting_indices = [] attester_slashing.attestation_2.attesting_indices = []
attester_slashing.attestation_2.signature = spec.bls.G2_POINT_AT_INFINITY attester_slashing.attestation_2.signature = spec.bls.G2_POINT_AT_INFINITY
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_att1_bad_extra_index(spec, state): def test_invalid_att1_bad_extra_index(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True)
indices = get_indexed_attestation_participants(spec, attester_slashing.attestation_1) indices = get_indexed_attestation_participants(spec, attester_slashing.attestation_1)
@ -351,13 +351,13 @@ def test_att1_bad_extra_index(spec, state):
# Do not sign the modified attestation (it's ok to slash if attester signed, not if they did not), # Do not sign the modified attestation (it's ok to slash if attester signed, not if they did not),
# see if the bad extra index is spotted, and slashing is aborted. # see if the bad extra index is spotted, and slashing is aborted.
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_att1_bad_replaced_index(spec, state): def test_invalid_att1_bad_replaced_index(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True)
indices = attester_slashing.attestation_1.attesting_indices indices = attester_slashing.attestation_1.attesting_indices
@ -367,13 +367,13 @@ def test_att1_bad_replaced_index(spec, state):
# Do not sign the modified attestation (it's ok to slash if attester signed, not if they did not), # Do not sign the modified attestation (it's ok to slash if attester signed, not if they did not),
# see if the bad replaced index is spotted, and slashing is aborted. # see if the bad replaced index is spotted, and slashing is aborted.
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_att2_bad_extra_index(spec, state): def test_invalid_att2_bad_extra_index(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True)
indices = attester_slashing.attestation_2.attesting_indices indices = attester_slashing.attestation_2.attesting_indices
@ -383,13 +383,13 @@ def test_att2_bad_extra_index(spec, state):
# Do not sign the modified attestation (it's ok to slash if attester signed, not if they did not), # Do not sign the modified attestation (it's ok to slash if attester signed, not if they did not),
# see if the bad extra index is spotted, and slashing is aborted. # see if the bad extra index is spotted, and slashing is aborted.
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_att2_bad_replaced_index(spec, state): def test_invalid_att2_bad_replaced_index(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True)
indices = attester_slashing.attestation_2.attesting_indices indices = attester_slashing.attestation_2.attesting_indices
@ -399,13 +399,13 @@ def test_att2_bad_replaced_index(spec, state):
# Do not sign the modified attestation (it's ok to slash if attester signed, not if they did not), # Do not sign the modified attestation (it's ok to slash if attester signed, not if they did not),
# see if the bad replaced index is spotted, and slashing is aborted. # see if the bad replaced index is spotted, and slashing is aborted.
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_att1_duplicate_index_normal_signed(spec, state): def test_invalid_att1_duplicate_index_normal_signed(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True)
indices = list(attester_slashing.attestation_1.attesting_indices) indices = list(attester_slashing.attestation_1.attesting_indices)
@ -419,13 +419,13 @@ def test_att1_duplicate_index_normal_signed(spec, state):
attester_slashing.attestation_1.attesting_indices = sorted(indices) attester_slashing.attestation_1.attesting_indices = sorted(indices)
# it will just appear normal, unless the double index is spotted # it will just appear normal, unless the double index is spotted
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_att2_duplicate_index_normal_signed(spec, state): def test_invalid_att2_duplicate_index_normal_signed(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=False) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=False)
indices = list(attester_slashing.attestation_2.attesting_indices) indices = list(attester_slashing.attestation_2.attesting_indices)
@ -439,13 +439,13 @@ def test_att2_duplicate_index_normal_signed(spec, state):
attester_slashing.attestation_2.attesting_indices = sorted(indices) attester_slashing.attestation_2.attesting_indices = sorted(indices)
# it will just appear normal, unless the double index is spotted # it will just appear normal, unless the double index is spotted
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_att1_duplicate_index_double_signed(spec, state): def test_invalid_att1_duplicate_index_double_signed(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True)
indices = list(attester_slashing.attestation_1.attesting_indices) indices = list(attester_slashing.attestation_1.attesting_indices)
@ -454,13 +454,13 @@ def test_att1_duplicate_index_double_signed(spec, state):
attester_slashing.attestation_1.attesting_indices = sorted(indices) attester_slashing.attestation_1.attesting_indices = sorted(indices)
sign_indexed_attestation(spec, state, attester_slashing.attestation_1) # will have one attester signing it double sign_indexed_attestation(spec, state, attester_slashing.attestation_1) # will have one attester signing it double
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_att2_duplicate_index_double_signed(spec, state): def test_invalid_att2_duplicate_index_double_signed(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=False) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=False)
indices = list(attester_slashing.attestation_2.attesting_indices) indices = list(attester_slashing.attestation_2.attesting_indices)
@ -469,12 +469,12 @@ def test_att2_duplicate_index_double_signed(spec, state):
attester_slashing.attestation_2.attesting_indices = sorted(indices) attester_slashing.attestation_2.attesting_indices = sorted(indices)
sign_indexed_attestation(spec, state, attester_slashing.attestation_2) # will have one attester signing it double sign_indexed_attestation(spec, state, attester_slashing.attestation_2) # will have one attester signing it double
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_unsorted_att_1(spec, state): def test_invalid_unsorted_att_1(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True)
indices = attester_slashing.attestation_1.attesting_indices indices = attester_slashing.attestation_1.attesting_indices
@ -482,12 +482,12 @@ def test_unsorted_att_1(spec, state):
indices[1], indices[2] = indices[2], indices[1] # unsort second and third index indices[1], indices[2] = indices[2], indices[1] # unsort second and third index
sign_indexed_attestation(spec, state, attester_slashing.attestation_1) sign_indexed_attestation(spec, state, attester_slashing.attestation_1)
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_unsorted_att_2(spec, state): def test_invalid_unsorted_att_2(spec, state):
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=False) attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=False)
indices = attester_slashing.attestation_2.attesting_indices indices = attester_slashing.attestation_2.attesting_indices
@ -495,4 +495,4 @@ def test_unsorted_att_2(spec, state):
indices[1], indices[2] = indices[2], indices[1] # unsort second and third index indices[1], indices[2] = indices[2], indices[1] # unsort second and third index
sign_indexed_attestation(spec, state, attester_slashing.attestation_2) sign_indexed_attestation(spec, state, attester_slashing.attestation_2)
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, valid=False)

View File

@ -34,7 +34,7 @@ def run_block_header_processing(spec, state, block, prepare_state=True, valid=Tr
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_success_block_header(spec, state): def test_basic_block_header(spec, state):
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
yield from run_block_header_processing(spec, state, block) yield from run_block_header_processing(spec, state, block)
@ -87,7 +87,7 @@ def test_invalid_multiple_blocks_single_slot(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_proposer_slashed(spec, state): def test_invalid_proposer_slashed(spec, state):
# use stub state to get proposer index of next slot # use stub state to get proposer index of next slot
stub_state = deepcopy(state) stub_state = deepcopy(state)
next_slot(spec, stub_state) next_slot(spec, stub_state)

View File

@ -1,13 +1,12 @@
from eth2spec.test.context import spec_state_test, always_bls, with_all_phases from eth2spec.test.context import spec_state_test, always_bls, with_all_phases
from eth2spec.test.helpers.deposits import ( from eth2spec.test.helpers.deposits import (
build_deposit, build_deposit,
deposit_from_context,
prepare_state_and_deposit, prepare_state_and_deposit,
run_deposit_processing, run_deposit_processing,
run_deposit_processing_with_specific_fork_version,
sign_deposit_data, sign_deposit_data,
) )
from eth2spec.test.helpers.keys import privkeys, pubkeys from eth2spec.test.helpers.keys import privkeys, pubkeys
from eth2spec.utils import bls
@with_all_phases @with_all_phases
@ -92,56 +91,29 @@ def test_new_deposit_non_versioned_withdrawal_credentials(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_sig_other_version(spec, state): def test_correct_sig_but_forked_state(spec, state):
validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE
pubkey = pubkeys[validator_index]
privkey = privkeys[validator_index]
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkey)[1:]
# Go through the effort of manually signing, not something normally done. This sig domain will be invalid.
deposit_message = spec.DepositMessage(pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount)
domain = spec.compute_domain(domain_type=spec.DOMAIN_DEPOSIT, fork_version=spec.Version('0xaabbccdd'))
deposit_data = spec.DepositData(
pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount,
signature=bls.Sign(privkey, spec.compute_signing_root(deposit_message, domain))
)
deposit, root, _ = deposit_from_context(spec, [deposit_data], 0)
state.eth1_deposit_index = 0
state.eth1_data.deposit_root = root
state.eth1_data.deposit_count = 1
yield from run_deposit_processing(spec, state, deposit, validator_index, valid=True, effective=False)
@with_all_phases
@spec_state_test
@always_bls
def test_valid_sig_but_forked_state(spec, state):
validator_index = len(state.validators) validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE amount = spec.MAX_EFFECTIVE_BALANCE
# deposits will always be valid, regardless of the current fork # deposits will always be valid, regardless of the current fork
state.fork.current_version = spec.Version('0x1234abcd') state.fork.current_version = spec.Version('0x1234abcd')
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True) deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
yield from run_deposit_processing(spec, state, deposit, validator_index, valid=True, effective=True) yield from run_deposit_processing(spec, state, deposit, validator_index)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_sig_new_deposit(spec, state): def test_incorrect_sig_new_deposit(spec, state):
# fresh deposit = next validator index = validator appended to registry # fresh deposit = next validator index = validator appended to registry
validator_index = len(state.validators) validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE amount = spec.MAX_EFFECTIVE_BALANCE
deposit = prepare_state_and_deposit(spec, state, validator_index, amount) deposit = prepare_state_and_deposit(spec, state, validator_index, amount)
yield from run_deposit_processing(spec, state, deposit, validator_index, valid=True, effective=False) yield from run_deposit_processing(spec, state, deposit, validator_index, effective=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_success_top_up__max_effective_balance(spec, state): def test_top_up__max_effective_balance(spec, state):
validator_index = 0 validator_index = 0
amount = spec.MAX_EFFECTIVE_BALANCE // 4 amount = spec.MAX_EFFECTIVE_BALANCE // 4
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True) deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
@ -157,7 +129,7 @@ def test_success_top_up__max_effective_balance(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_success_top_up__less_effective_balance(spec, state): def test_top_up__less_effective_balance(spec, state):
validator_index = 0 validator_index = 0
amount = spec.MAX_EFFECTIVE_BALANCE // 4 amount = spec.MAX_EFFECTIVE_BALANCE // 4
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True) deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
@ -176,7 +148,7 @@ def test_success_top_up__less_effective_balance(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_success_top_up__zero_balance(spec, state): def test_top_up__zero_balance(spec, state):
validator_index = 0 validator_index = 0
amount = spec.MAX_EFFECTIVE_BALANCE // 4 amount = spec.MAX_EFFECTIVE_BALANCE // 4
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True) deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
@ -196,18 +168,18 @@ def test_success_top_up__zero_balance(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_sig_top_up(spec, state): def test_incorrect_sig_top_up(spec, state):
validator_index = 0 validator_index = 0
amount = spec.MAX_EFFECTIVE_BALANCE // 4 amount = spec.MAX_EFFECTIVE_BALANCE // 4
deposit = prepare_state_and_deposit(spec, state, validator_index, amount) deposit = prepare_state_and_deposit(spec, state, validator_index, amount)
# invalid signatures, in top-ups, are allowed! # invalid signatures, in top-ups, are allowed!
yield from run_deposit_processing(spec, state, deposit, validator_index, valid=True, effective=True) yield from run_deposit_processing(spec, state, deposit, validator_index)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_invalid_withdrawal_credentials_top_up(spec, state): def test_incorrect_withdrawal_credentials_top_up(spec, state):
validator_index = 0 validator_index = 0
amount = spec.MAX_EFFECTIVE_BALANCE // 4 amount = spec.MAX_EFFECTIVE_BALANCE // 4
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(b"junk")[1:] withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(b"junk")[1:]
@ -220,12 +192,12 @@ def test_invalid_withdrawal_credentials_top_up(spec, state):
) )
# inconsistent withdrawal credentials, in top-ups, are allowed! # inconsistent withdrawal credentials, in top-ups, are allowed!
yield from run_deposit_processing(spec, state, deposit, validator_index, valid=True, effective=True) yield from run_deposit_processing(spec, state, deposit, validator_index)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_wrong_deposit_for_deposit_count(spec, state): def test_invalid_wrong_deposit_for_deposit_count(spec, state):
deposit_data_leaves = [spec.DepositData() for _ in range(len(state.validators))] deposit_data_leaves = [spec.DepositData() for _ in range(len(state.validators))]
# build root for deposit_1 # build root for deposit_1
@ -266,7 +238,7 @@ def test_wrong_deposit_for_deposit_count(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_bad_merkle_proof(spec, state): def test_invalid_bad_merkle_proof(spec, state):
validator_index = len(state.validators) validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE amount = spec.MAX_EFFECTIVE_BALANCE
deposit = prepare_state_and_deposit(spec, state, validator_index, amount) deposit = prepare_state_and_deposit(spec, state, validator_index, amount)
@ -307,3 +279,15 @@ def test_key_validate_invalid_decompression(spec, state):
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, pubkey=pubkey, signed=True) deposit = prepare_state_and_deposit(spec, state, validator_index, amount, pubkey=pubkey, signed=True)
yield from run_deposit_processing(spec, state, deposit, validator_index) yield from run_deposit_processing(spec, state, deposit, validator_index)
@with_all_phases
@spec_state_test
@always_bls
def test_ineffective_deposit_with_bad_fork_version(spec, state):
yield from run_deposit_processing_with_specific_fork_version(
spec,
state,
fork_version=spec.Version('0xAaBbCcDd'),
effective=False,
)

View File

@ -34,7 +34,7 @@ def run_proposer_slashing_processing(spec, state, proposer_slashing, valid=True)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_success(spec, state): def test_basic(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True)
yield from run_proposer_slashing_processing(spec, state, proposer_slashing) yield from run_proposer_slashing_processing(spec, state, proposer_slashing)
@ -42,7 +42,7 @@ def test_success(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_success_slashed_and_proposer_index_the_same(spec, state): def test_slashed_and_proposer_index_the_same(spec, state):
# Get proposer for next slot # Get proposer for next slot
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
proposer_index = block.proposer_index proposer_index = block.proposer_index
@ -57,7 +57,7 @@ def test_success_slashed_and_proposer_index_the_same(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_success_block_header_from_future(spec, state): def test_block_header_from_future(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, slot=state.slot + 5, signed_1=True, signed_2=True) proposer_slashing = get_valid_proposer_slashing(spec, state, slot=state.slot + 5, signed_1=True, signed_2=True)
yield from run_proposer_slashing_processing(spec, state, proposer_slashing) yield from run_proposer_slashing_processing(spec, state, proposer_slashing)
@ -66,31 +66,31 @@ def test_success_block_header_from_future(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_sig_1(spec, state): def test_invalid_incorrect_sig_1(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=False, signed_2=True) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=False, signed_2=True)
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_sig_2(spec, state): def test_invalid_incorrect_sig_2(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=False) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=False)
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_sig_1_and_2(spec, state): def test_invalid_incorrect_sig_1_and_2(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=False, signed_2=False) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=False, signed_2=False)
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_sig_1_and_2_swap(spec, state): def test_invalid_incorrect_sig_1_and_2_swap(spec, state):
# Get valid signatures for the slashings # Get valid signatures for the slashings
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True)
@ -98,18 +98,18 @@ def test_invalid_sig_1_and_2_swap(spec, state):
signature_1 = proposer_slashing.signed_header_1.signature signature_1 = proposer_slashing.signed_header_1.signature
proposer_slashing.signed_header_1.signature = proposer_slashing.signed_header_2.signature proposer_slashing.signed_header_1.signature = proposer_slashing.signed_header_2.signature
proposer_slashing.signed_header_2.signature = signature_1 proposer_slashing.signed_header_2.signature = signature_1
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_invalid_proposer_index(spec, state): def test_invalid_incorrect_proposer_index(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True)
# Index just too high (by 1) # Index just too high (by 1)
proposer_slashing.signed_header_1.message.proposer_index = len(state.validators) proposer_slashing.signed_header_1.message.proposer_index = len(state.validators)
proposer_slashing.signed_header_2.message.proposer_index = len(state.validators) proposer_slashing.signed_header_2.message.proposer_index = len(state.validators)
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, valid=False)
@with_all_phases @with_all_phases
@ -125,12 +125,12 @@ def test_invalid_different_proposer_indices(spec, state):
header_2.proposer_index = active_indices[0] header_2.proposer_index = active_indices[0]
proposer_slashing.signed_header_2 = sign_block_header(spec, state, header_2, privkeys[header_2.proposer_index]) proposer_slashing.signed_header_2 = sign_block_header(spec, state, header_2, privkeys[header_2.proposer_index])
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_epochs_are_different(spec, state): def test_invalid_slots_of_different_epochs(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=False) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=False)
# set slots to be in different epochs # set slots to be in different epochs
@ -139,23 +139,23 @@ def test_epochs_are_different(spec, state):
header_2.slot += spec.SLOTS_PER_EPOCH header_2.slot += spec.SLOTS_PER_EPOCH
proposer_slashing.signed_header_2 = sign_block_header(spec, state, header_2, privkeys[proposer_index]) proposer_slashing.signed_header_2 = sign_block_header(spec, state, header_2, privkeys[proposer_index])
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_headers_are_same_sigs_are_same(spec, state): def test_invalid_headers_are_same_sigs_are_same(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=False) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=False)
# set headers to be the same # set headers to be the same
proposer_slashing.signed_header_2 = proposer_slashing.signed_header_1.copy() proposer_slashing.signed_header_2 = proposer_slashing.signed_header_1.copy()
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_headers_are_same_sigs_are_different(spec, state): def test_invalid_headers_are_same_sigs_are_different(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=False) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=False)
# set headers to be the same # set headers to be the same
@ -165,36 +165,36 @@ def test_headers_are_same_sigs_are_different(spec, state):
assert proposer_slashing.signed_header_1.signature != proposer_slashing.signed_header_2.signature assert proposer_slashing.signed_header_1.signature != proposer_slashing.signed_header_2.signature
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_proposer_is_not_activated(spec, state): def test_invalid_proposer_is_not_activated(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True)
# set proposer to be not active yet # set proposer to be not active yet
proposer_index = proposer_slashing.signed_header_1.message.proposer_index proposer_index = proposer_slashing.signed_header_1.message.proposer_index
state.validators[proposer_index].activation_epoch = spec.get_current_epoch(state) + 1 state.validators[proposer_index].activation_epoch = spec.get_current_epoch(state) + 1
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_proposer_is_slashed(spec, state): def test_invalid_proposer_is_slashed(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True)
# set proposer to slashed # set proposer to slashed
proposer_index = proposer_slashing.signed_header_1.message.proposer_index proposer_index = proposer_slashing.signed_header_1.message.proposer_index
state.validators[proposer_index].slashed = True state.validators[proposer_index].slashed = True
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_proposer_is_withdrawn(spec, state): def test_invalid_proposer_is_withdrawn(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True)
# move 1 epoch into future, to allow for past withdrawable epoch # move 1 epoch into future, to allow for past withdrawable epoch
@ -204,4 +204,4 @@ def test_proposer_is_withdrawn(spec, state):
proposer_index = proposer_slashing.signed_header_1.message.proposer_index proposer_index = proposer_slashing.signed_header_1.message.proposer_index
state.validators[proposer_index].withdrawable_epoch = current_epoch - 1 state.validators[proposer_index].withdrawable_epoch = current_epoch - 1
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, valid=False)

View File

@ -14,7 +14,7 @@ from eth2spec.test.helpers.voluntary_exits import (
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_success(spec, state): def test_basic(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
@ -33,7 +33,7 @@ def test_success(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_signature(spec, state): def test_invalid_incorrect_signature(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
@ -46,7 +46,7 @@ def test_invalid_signature(spec, state):
) )
signed_voluntary_exit = sign_voluntary_exit(spec, state, voluntary_exit, 12345) signed_voluntary_exit = sign_voluntary_exit(spec, state, voluntary_exit, 12345)
yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, False) yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, valid=False)
def run_test_success_exit_queue(spec, state): def run_test_success_exit_queue(spec, state):
@ -134,7 +134,7 @@ def test_default_exit_epoch_subsequent_exit(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_validator_exit_in_future(spec, state): def test_invalid_validator_exit_in_future(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
@ -148,12 +148,12 @@ def test_validator_exit_in_future(spec, state):
) )
signed_voluntary_exit = sign_voluntary_exit(spec, state, voluntary_exit, privkey) signed_voluntary_exit = sign_voluntary_exit(spec, state, voluntary_exit, privkey)
yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, False) yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_validator_invalid_validator_index(spec, state): def test_invalid_validator_incorrect_validator_index(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
@ -167,12 +167,12 @@ def test_validator_invalid_validator_index(spec, state):
) )
signed_voluntary_exit = sign_voluntary_exit(spec, state, voluntary_exit, privkey) signed_voluntary_exit = sign_voluntary_exit(spec, state, voluntary_exit, privkey)
yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, False) yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_validator_not_active(spec, state): def test_invalid_validator_not_active(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0] validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validators[validator_index].pubkey] privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
@ -182,12 +182,12 @@ def test_validator_not_active(spec, state):
signed_voluntary_exit = sign_voluntary_exit( signed_voluntary_exit = sign_voluntary_exit(
spec, state, spec.VoluntaryExit(epoch=current_epoch, validator_index=validator_index), privkey) spec, state, spec.VoluntaryExit(epoch=current_epoch, validator_index=validator_index), privkey)
yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, False) yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_validator_already_exited(spec, state): def test_invalid_validator_already_exited(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow validator able to exit # move state forward SHARD_COMMITTEE_PERIOD epochs to allow validator able to exit
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
@ -201,12 +201,12 @@ def test_validator_already_exited(spec, state):
signed_voluntary_exit = sign_voluntary_exit( signed_voluntary_exit = sign_voluntary_exit(
spec, state, spec.VoluntaryExit(epoch=current_epoch, validator_index=validator_index), privkey) spec, state, spec.VoluntaryExit(epoch=current_epoch, validator_index=validator_index), privkey)
yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, False) yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, valid=False)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_validator_not_active_long_enough(spec, state): def test_invalid_validator_not_active_long_enough(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0] validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validators[validator_index].pubkey] privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
@ -219,4 +219,4 @@ def test_validator_not_active_long_enough(spec, state):
spec.config.SHARD_COMMITTEE_PERIOD spec.config.SHARD_COMMITTEE_PERIOD
) )
yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, False) yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, valid=False)

View File

@ -47,20 +47,20 @@ def run_is_valid_genesis_state(spec, state, valid=True):
@spec_test @spec_test
@single_phase @single_phase
@with_presets([MINIMAL], reason="too slow") @with_presets([MINIMAL], reason="too slow")
def test_is_valid_genesis_state_true(spec): def test_full_genesis_deposits(spec):
if is_post_altair(spec): if is_post_altair(spec):
yield 'description', 'meta', get_post_altair_description(spec) yield 'description', 'meta', get_post_altair_description(spec)
state = create_valid_beacon_state(spec) state = create_valid_beacon_state(spec)
yield from run_is_valid_genesis_state(spec, state, valid=True) yield from run_is_valid_genesis_state(spec, state)
@with_all_phases @with_all_phases
@spec_test @spec_test
@single_phase @single_phase
@with_presets([MINIMAL], reason="too slow") @with_presets([MINIMAL], reason="too slow")
def test_is_valid_genesis_state_false_invalid_timestamp(spec): def test_invalid_invalid_timestamp(spec):
if is_post_altair(spec): if is_post_altair(spec):
yield 'description', 'meta', get_post_altair_description(spec) yield 'description', 'meta', get_post_altair_description(spec)
@ -74,21 +74,21 @@ def test_is_valid_genesis_state_false_invalid_timestamp(spec):
@spec_test @spec_test
@single_phase @single_phase
@with_presets([MINIMAL], reason="too slow") @with_presets([MINIMAL], reason="too slow")
def test_is_valid_genesis_state_true_more_balance(spec): def test_extra_balance(spec):
if is_post_altair(spec): if is_post_altair(spec):
yield 'description', 'meta', get_post_altair_description(spec) yield 'description', 'meta', get_post_altair_description(spec)
state = create_valid_beacon_state(spec) state = create_valid_beacon_state(spec)
state.validators[0].effective_balance = spec.MAX_EFFECTIVE_BALANCE + 1 state.validators[0].effective_balance = spec.MAX_EFFECTIVE_BALANCE + 1
yield from run_is_valid_genesis_state(spec, state, valid=True) yield from run_is_valid_genesis_state(spec, state)
@with_all_phases @with_all_phases
@spec_test @spec_test
@single_phase @single_phase
@with_presets([MINIMAL], reason="too slow") @with_presets([MINIMAL], reason="too slow")
def test_is_valid_genesis_state_true_one_more_validator(spec): def test_one_more_validator(spec):
if is_post_altair(spec): if is_post_altair(spec):
yield 'description', 'meta', get_post_altair_description(spec) yield 'description', 'meta', get_post_altair_description(spec)
@ -104,14 +104,14 @@ def test_is_valid_genesis_state_true_one_more_validator(spec):
eth1_timestamp = spec.config.MIN_GENESIS_TIME eth1_timestamp = spec.config.MIN_GENESIS_TIME
state = spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits) state = spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits)
yield from run_is_valid_genesis_state(spec, state, valid=True) yield from run_is_valid_genesis_state(spec, state)
@with_all_phases @with_all_phases
@spec_test @spec_test
@single_phase @single_phase
@with_presets([MINIMAL], reason="too slow") @with_presets([MINIMAL], reason="too slow")
def test_is_valid_genesis_state_false_not_enough_validator(spec): def test_invalid_not_enough_validator_count(spec):
if is_post_altair(spec): if is_post_altair(spec):
yield 'description', 'meta', get_post_altair_description(spec) yield 'description', 'meta', get_post_altair_description(spec)

View File

@ -43,7 +43,7 @@ from eth2spec.test.context import (
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_prev_slot_block_transition(spec, state): def test_invalid_prev_slot_block_transition(spec, state):
# Go to clean slot # Go to clean slot
spec.process_slots(state, state.slot + 1) spec.process_slots(state, state.slot + 1)
# Make a block for it # Make a block for it
@ -64,7 +64,7 @@ def test_prev_slot_block_transition(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_same_slot_block_transition(spec, state): def test_invalid_same_slot_block_transition(spec, state):
# Same slot on top of pre-state, but move out of slot 0 first. # Same slot on top of pre-state, but move out of slot 0 first.
spec.process_slots(state, state.slot + 1) spec.process_slots(state, state.slot + 1)
@ -161,7 +161,7 @@ def process_and_sign_block_without_header_validations(spec, state, block):
@with_phases([PHASE0]) @with_phases([PHASE0])
@spec_state_test @spec_state_test
def test_proposal_for_genesis_slot(spec, state): def test_invalid_proposal_for_genesis_slot(spec, state):
assert state.slot == spec.GENESIS_SLOT assert state.slot == spec.GENESIS_SLOT
yield 'pre', state yield 'pre', state
@ -184,7 +184,7 @@ def test_proposal_for_genesis_slot(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_parent_from_same_slot(spec, state): def test_invalid_parent_from_same_slot(spec, state):
yield 'pre', state yield 'pre', state
parent_block = build_empty_block_for_next_slot(spec, state) parent_block = build_empty_block_for_next_slot(spec, state)
@ -211,7 +211,7 @@ def test_parent_from_same_slot(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_invalid_state_root(spec, state): def test_invalid_incorrect_state_root(spec, state):
yield 'pre', state yield 'pre', state
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
@ -227,7 +227,7 @@ def test_invalid_state_root(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_zero_block_sig(spec, state): def test_invalid_all_zeroed_sig(spec, state):
yield 'pre', state yield 'pre', state
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
@ -241,7 +241,7 @@ def test_zero_block_sig(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_block_sig(spec, state): def test_invalid_incorrect_block_sig(spec, state):
yield 'pre', state yield 'pre', state
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
@ -260,7 +260,7 @@ def test_invalid_block_sig(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_proposer_index_sig_from_expected_proposer(spec, state): def test_invalid_incorrect_proposer_index_sig_from_expected_proposer(spec, state):
yield 'pre', state yield 'pre', state
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
@ -282,7 +282,7 @@ def test_invalid_proposer_index_sig_from_expected_proposer(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_proposer_index_sig_from_proposer_index(spec, state): def test_invalid_incorrect_proposer_index_sig_from_proposer_index(spec, state):
yield 'pre', state yield 'pre', state
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
@ -707,7 +707,7 @@ def test_high_proposer_index(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_expected_deposit_in_block(spec, state): def test_invalid_only_increase_deposit_count(spec, state):
# Make the state expect a deposit, then don't provide it. # Make the state expect a deposit, then don't provide it.
state.eth1_data.deposit_count += 1 state.eth1_data.deposit_count += 1
yield 'pre', state yield 'pre', state

View File

@ -1,5 +1,8 @@
from eth2spec.test.helpers.state import get_state_root from eth2spec.test.helpers.state import get_state_root
from eth2spec.test.context import spec_state_test, with_all_phases from eth2spec.test.context import (
spec_state_test,
with_all_phases,
)
@with_all_phases @with_all_phases

View File

@ -7,6 +7,9 @@ import warnings
from random import Random from random import Random
from typing import Callable from typing import Callable
from eth2spec.test.helpers.execution_payload import (
compute_el_block_hash,
)
from eth2spec.test.helpers.multi_operations import ( from eth2spec.test.helpers.multi_operations import (
build_random_block_from_state_for_next_slot, build_random_block_from_state_for_next_slot,
get_random_bls_to_execution_changes, get_random_bls_to_execution_changes,
@ -234,6 +237,7 @@ def random_block_eip4844(spec, state, signed_blocks, scenario_state, rng=Random(
# TODO: more commitments. blob_kzg_commitments: List[KZGCommitment, MAX_BLOBS_PER_BLOCK] # TODO: more commitments. blob_kzg_commitments: List[KZGCommitment, MAX_BLOBS_PER_BLOCK]
opaque_tx, _, blob_kzg_commitments = get_sample_opaque_tx(spec, blob_count=1) opaque_tx, _, blob_kzg_commitments = get_sample_opaque_tx(spec, blob_count=1)
block.body.execution_payload.transactions = [opaque_tx] block.body.execution_payload.transactions = [opaque_tx]
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
block.body.blob_kzg_commitments = blob_kzg_commitments block.body.blob_kzg_commitments = blob_kzg_commitments
return block return block

View File

@ -11,10 +11,15 @@ if __name__ == "__main__":
'proposer_slashing', 'proposer_slashing',
'voluntary_exit', 'voluntary_exit',
]} ]}
_new_altair_mods = {'sync_aggregate': [ _new_altair_mods = {
'eth2spec.test.altair.block_processing.sync_aggregate.test_process_' + key **{'sync_aggregate': [
for key in ['sync_aggregate', 'sync_aggregate_random'] 'eth2spec.test.altair.block_processing.sync_aggregate.test_process_' + key
]} for key in ['sync_aggregate', 'sync_aggregate_random']
]},
**{key: 'eth2spec.test.altair.block_processing.test_process_' + key for key in [
'deposit',
]}
}
altair_mods = combine_mods(_new_altair_mods, phase_0_mods) altair_mods = combine_mods(_new_altair_mods, phase_0_mods)
_new_bellatrix_mods = {key: 'eth2spec.test.bellatrix.block_processing.test_process_' + key for key in [ _new_bellatrix_mods = {key: 'eth2spec.test.bellatrix.block_processing.test_process_' + key for key in [