Merge branch 'dev'

This commit is contained in:
Danny Ryan
2021-11-02 12:04:34 -06:00
25 changed files with 533 additions and 338 deletions

View File

@@ -1 +1 @@
1.1.3
1.1.4

View File

@@ -1,4 +1,7 @@
from eth2spec.test import context
from eth2spec.test.helpers.constants import (
ALL_PHASES,
)
from eth2spec.utils import bls as bls_utils
# We import pytest only when it's present, i.e. when we are running tests.
@@ -29,6 +32,13 @@ def pytest_addoption(parser):
"--preset", action="store", type=str, default="minimal",
help="preset: make the pyspec use the specified preset"
)
parser.addoption(
"--fork", action="append", type=str,
help=(
"fork: make the pyspec only run with the specified phase."
" To run multiple phases, e.g., --fork=phase0 --fork=altair"
)
)
parser.addoption(
"--disable-bls", action="store_true", default=False,
help="bls-default: make tests that are not dependent on BLS run without BLS"
@@ -39,11 +49,31 @@ def pytest_addoption(parser):
)
def _validate_fork_name(forks):
for fork in forks:
if fork not in ALL_PHASES:
raise ValueError(
f'The given --fork argument "{fork}" is not an available fork.'
f' The available forks: {ALL_PHASES}'
)
@fixture(autouse=True)
def preset(request):
context.DEFAULT_TEST_PRESET = request.config.getoption("--preset")
@fixture(autouse=True)
def run_phases(request):
forks = request.config.getoption("--fork", default=None)
if forks:
forks = [fork.lower() for fork in forks]
_validate_fork_name(forks)
context.DEFAULT_PYTEST_FORKS = set(forks)
else:
context.DEFAULT_PYTEST_FORKS = ALL_PHASES
@fixture(autouse=True)
def bls_default(request):
disable_bls = request.config.getoption("--disable-bls")

View File

@@ -22,6 +22,9 @@ from lru import LRU
# Without pytest CLI arg or pyspec-test-generator 'preset' argument, this will be the config to apply.
DEFAULT_TEST_PRESET = MINIMAL
# Without pytest CLI arg or pyspec-test-generator 'run-phase' argument, this will be the config to apply.
DEFAULT_PYTEST_FORKS = ALL_PHASES
# TODO: currently phases are defined as python modules.
# It would be better if they would be more well-defined interfaces for stronger typing.
@@ -351,7 +354,7 @@ def with_phases(phases, other_phases=None):
"""
def decorator(fn):
def wrapper(*args, **kw):
run_phases = phases
run_phases = set(phases).intersection(DEFAULT_PYTEST_FORKS)
# limit phases if one explicitly specified
if 'phase' in kw:

View File

@@ -244,15 +244,6 @@ def run_transition_with_operation(state,
signed_exits = prepare_signed_exits(spec, state, [selected_validator_index])
operation_dict = {'voluntary_exits': signed_exits}
blocks = []
if is_right_before_fork:
# add a block with operation.
block = build_empty_block_for_next_slot(spec, state)
_set_operations_by_dict(block, operation_dict)
signed_block = state_transition_and_sign_block(spec, state, block)
blocks.append(pre_tag(signed_block))
def _check_state():
if operation_type == OperationType.PROPOSER_SLASHING:
slashed_proposer = state.validators[proposer_slashing.signed_header_1.message.proposer_index]
@@ -274,11 +265,19 @@ def run_transition_with_operation(state,
validator = state.validators[selected_validator_index]
assert validator.exit_epoch < post_spec.FAR_FUTURE_EPOCH
if is_right_before_fork:
_check_state()
yield "pre", state
blocks = []
if is_right_before_fork:
# add a block with operation.
block = build_empty_block_for_next_slot(spec, state)
_set_operations_by_dict(block, operation_dict)
signed_block = state_transition_and_sign_block(spec, state, block)
blocks.append(pre_tag(signed_block))
_check_state()
# irregular state transition to handle fork:
_operation_at_slot = operation_dict if is_at_fork else None
state, block = do_altair_fork(state, spec, post_spec, fork_epoch, operation_dict=_operation_at_slot)
@@ -289,7 +288,7 @@ def run_transition_with_operation(state,
# after the fork
if operation_type == OperationType.DEPOSIT:
_transition_until_active(post_spec, state, post_tag, blocks, selected_validator_index)
state = _transition_until_active(post_spec, state, post_tag, blocks, selected_validator_index)
else:
# avoid using the slashed validators as block proposers
ignoring_proposers = [selected_validator_index] if is_slashing_operation else None
@@ -333,3 +332,5 @@ def _transition_until_active(post_spec, state, post_tag, blocks, validator_index
state_transition_across_slots(post_spec, state, to_slot, block_filter=only_at(to_slot))
])
assert post_spec.is_active_validator(state.validators[validator_index], post_spec.get_current_epoch(state))
return state

View File

@@ -1,4 +1,4 @@
from eth2spec.test.context import is_post_altair
from eth2spec.test.context import is_post_altair, is_post_merge
from eth2spec.test.helpers.block_header import sign_block_header
from eth2spec.test.helpers.keys import pubkey_to_privkey
from eth2spec.test.helpers.state import get_balance
@@ -9,7 +9,9 @@ from eth2spec.test.helpers.sync_committee import (
def get_min_slashing_penalty_quotient(spec):
if is_post_altair(spec):
if is_post_merge(spec):
return spec.MIN_SLASHING_PENALTY_QUOTIENT_MERGE
elif is_post_altair(spec):
return spec.MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR
else:
return spec.MIN_SLASHING_PENALTY_QUOTIENT

View File

@@ -2,7 +2,7 @@ from random import Random
from lru import LRU
from eth2spec.phase0.mainnet import VALIDATOR_REGISTRY_LIMIT # equal everywhere, fine to import
from eth2spec.test.context import is_post_altair
from eth2spec.test.context import is_post_altair, is_post_merge
from eth2spec.test.helpers.state import (
next_epoch,
)
@@ -21,6 +21,15 @@ class Deltas(Container):
penalties: List[uint64, VALIDATOR_REGISTRY_LIMIT]
def get_inactivity_penalty_quotient(spec):
if is_post_merge(spec):
return spec.INACTIVITY_PENALTY_QUOTIENT_MERGE
elif is_post_altair(spec):
return spec.INACTIVITY_PENALTY_QUOTIENT_ALTAIR
else:
return spec.INACTIVITY_PENALTY_QUOTIENT
def has_enough_for_reward(spec, state, index):
"""
Check if base_reward will be non-zero.
@@ -45,7 +54,7 @@ def has_enough_for_leak_penalty(spec, state, index):
if is_post_altair(spec):
return (
state.validators[index].effective_balance * state.inactivity_scores[index]
> spec.config.INACTIVITY_SCORE_BIAS * spec.INACTIVITY_PENALTY_QUOTIENT_ALTAIR
> spec.config.INACTIVITY_SCORE_BIAS * get_inactivity_penalty_quotient(spec)
)
else:
return (
@@ -266,7 +275,7 @@ def run_get_inactivity_penalty_deltas(spec, state):
else:
# copied from spec:
penalty_numerator = state.validators[index].effective_balance * state.inactivity_scores[index]
penalty_denominator = spec.config.INACTIVITY_SCORE_BIAS * spec.INACTIVITY_PENALTY_QUOTIENT_ALTAIR
penalty_denominator = spec.config.INACTIVITY_SCORE_BIAS * get_inactivity_penalty_quotient(spec)
assert penalties[index] == penalty_numerator // penalty_denominator

View File

@@ -1,4 +1,3 @@
from eth2spec.utils.ssz.ssz_typing import uint64
from eth2spec.test.helpers.execution_payload import (
build_empty_execution_payload,
get_execution_payload_header,
@@ -173,20 +172,6 @@ def test_bad_random_regular_payload(spec, state):
yield from run_execution_payload_processing(spec, state, execution_payload, valid=False)
@with_merge_and_later
@spec_state_test
def test_bad_number_regular_payload(spec, state):
# pre-state
state = build_state_with_complete_transition(spec, state)
next_slot(spec, state)
# execution payload
execution_payload = build_empty_execution_payload(spec, state)
execution_payload.block_number = execution_payload.block_number + 1
yield from run_execution_payload_processing(spec, state, execution_payload, valid=False)
@with_merge_and_later
@spec_state_test
def test_bad_everything_regular_payload(spec, state):
@@ -197,7 +182,8 @@ def test_bad_everything_regular_payload(spec, state):
# execution payload
execution_payload = build_empty_execution_payload(spec, state)
execution_payload.parent_hash = spec.Hash32()
execution_payload.block_number = execution_payload.block_number + 1
execution_payload.random = spec.Bytes32()
execution_payload.timestamp = 0
yield from run_execution_payload_processing(spec, state, execution_payload, valid=False)
@@ -228,157 +214,3 @@ def test_bad_timestamp_regular_payload(spec, state):
execution_payload.timestamp = execution_payload.timestamp + 1
yield from run_execution_payload_processing(spec, state, execution_payload, valid=False)
@with_merge_and_later
@spec_state_test
def test_gaslimit_zero_first_payload(spec, state):
# pre-state
state = build_state_with_incomplete_transition(spec, state)
next_slot(spec, state)
# execution payload
execution_payload = build_empty_execution_payload(spec, state)
execution_payload.gas_limit = uint64(0)
yield from run_execution_payload_processing(spec, state, execution_payload)
@with_merge_and_later
@spec_state_test
def test_gaslimit_max_first_payload(spec, state):
# pre-state
state = build_state_with_incomplete_transition(spec, state)
next_slot(spec, state)
# execution payload
execution_payload = build_empty_execution_payload(spec, state)
execution_payload.gas_limit = uint64(2**64 - 1)
yield from run_execution_payload_processing(spec, state, execution_payload)
@with_merge_and_later
@spec_state_test
def test_gaslimit_upper_plus_regular_payload(spec, state):
# pre-state
state = build_state_with_complete_transition(spec, state)
next_slot(spec, state)
# execution payload
execution_payload = build_empty_execution_payload(spec, state)
execution_payload.gas_limit = (
execution_payload.gas_limit +
execution_payload.gas_limit // spec.GAS_LIMIT_DENOMINATOR
)
yield from run_execution_payload_processing(spec, state, execution_payload, valid=False)
@with_merge_and_later
@spec_state_test
def test_gaslimit_upper_regular_payload(spec, state):
# pre-state
state = build_state_with_complete_transition(spec, state)
next_slot(spec, state)
# execution payload
execution_payload = build_empty_execution_payload(spec, state)
execution_payload.gas_limit = (
execution_payload.gas_limit +
execution_payload.gas_limit // spec.GAS_LIMIT_DENOMINATOR - uint64(1)
)
yield from run_execution_payload_processing(spec, state, execution_payload)
@with_merge_and_later
@spec_state_test
def test_gaslimit_lower_minus_regular_payload(spec, state):
# pre-state
state = build_state_with_complete_transition(spec, state)
next_slot(spec, state)
# execution payload
execution_payload = build_empty_execution_payload(spec, state)
execution_payload.gas_limit = (
execution_payload.gas_limit -
execution_payload.gas_limit // spec.GAS_LIMIT_DENOMINATOR
)
yield from run_execution_payload_processing(spec, state, execution_payload, valid=False)
@with_merge_and_later
@spec_state_test
def test_gaslimit_lower_regular_payload(spec, state):
# pre-state
state = build_state_with_complete_transition(spec, state)
next_slot(spec, state)
# execution payload
execution_payload = build_empty_execution_payload(spec, state)
execution_payload.gas_limit = (
execution_payload.gas_limit -
execution_payload.gas_limit // spec.GAS_LIMIT_DENOMINATOR + uint64(1)
)
yield from run_execution_payload_processing(spec, state, execution_payload)
@with_merge_and_later
@spec_state_test
def test_gaslimit_minimum_regular_payload(spec, state):
# pre-state
state = build_state_with_complete_transition(spec, state)
next_slot(spec, state)
state.latest_execution_payload_header.gas_limit = spec.MIN_GAS_LIMIT
# execution payload
execution_payload = build_empty_execution_payload(spec, state)
execution_payload.gas_limit = execution_payload.gas_limit
yield from run_execution_payload_processing(spec, state, execution_payload)
@with_merge_and_later
@spec_state_test
def test_gaslimit_minimum_minus_regular_payload(spec, state):
# pre-state
state = build_state_with_complete_transition(spec, state)
next_slot(spec, state)
state.latest_execution_payload_header.gas_limit = spec.MIN_GAS_LIMIT
# execution payload
execution_payload = build_empty_execution_payload(spec, state)
execution_payload.gas_limit = execution_payload.gas_limit - uint64(1)
yield from run_execution_payload_processing(spec, state, execution_payload, valid=False)
@with_merge_and_later
@spec_state_test
def test_gasused_gaslimit_regular_payload(spec, state):
# pre-state
state = build_state_with_complete_transition(spec, state)
next_slot(spec, state)
# execution payload
execution_payload = build_empty_execution_payload(spec, state)
execution_payload.gas_used = execution_payload.gas_limit
yield from run_execution_payload_processing(spec, state, execution_payload)
@with_merge_and_later
@spec_state_test
def test_gasused_gaslimit_plus_regular_payload(spec, state):
# pre-state
state = build_state_with_complete_transition(spec, state)
next_slot(spec, state)
# execution payload
execution_payload = build_empty_execution_payload(spec, state)
execution_payload.gas_used = execution_payload.gas_limit + uint64(1)
yield from run_execution_payload_processing(spec, state, execution_payload, valid=False)

View File

@@ -275,10 +275,38 @@ def test_invalid_current_source_root(spec, state):
state.previous_justified_checkpoint = spec.Checkpoint(epoch=3, root=b'\x01' * 32)
state.current_justified_checkpoint = spec.Checkpoint(epoch=4, root=b'\x32' * 32)
attestation = get_valid_attestation(spec, state, slot=(spec.SLOTS_PER_EPOCH * 3) + 1)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
attestation = get_valid_attestation(spec, state, slot=spec.SLOTS_PER_EPOCH * 5)
# Test logic sanity checks:
assert attestation.data.target.epoch == spec.get_current_epoch(state)
assert state.current_justified_checkpoint.root != state.previous_justified_checkpoint.root
assert attestation.data.source.root == state.current_justified_checkpoint.root
# Make attestation source root invalid: should be current justified, not previous one
attestation.data.source.root = state.previous_justified_checkpoint.root
sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation, False)
@with_all_phases
@spec_state_test
def test_invalid_previous_source_root(spec, state):
next_slots(spec, state, spec.SLOTS_PER_EPOCH * 5)
state.finalized_checkpoint.epoch = 2
state.previous_justified_checkpoint = spec.Checkpoint(epoch=3, root=b'\x01' * 32)
state.current_justified_checkpoint = spec.Checkpoint(epoch=4, root=b'\x32' * 32)
attestation = get_valid_attestation(spec, state, slot=(spec.SLOTS_PER_EPOCH * 4) + 1)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
# Test logic sanity checks:
assert attestation.data.target.epoch == spec.get_previous_epoch(state)
assert state.current_justified_checkpoint.root != state.previous_justified_checkpoint.root
assert attestation.data.source.root == state.previous_justified_checkpoint.root

View File

@@ -1,5 +1,5 @@
from random import Random
from eth2spec.test.context import spec_state_test, with_all_phases, is_post_altair
from eth2spec.test.context import spec_state_test, with_all_phases, is_post_altair, is_post_merge
from eth2spec.test.helpers.epoch_processing import (
run_epoch_processing_with, run_epoch_processing_to
)
@@ -31,7 +31,9 @@ def slash_validators(spec, state, indices, out_epochs):
def get_slashing_multiplier(spec):
if is_post_altair(spec):
if is_post_merge(spec):
return spec.PROPORTIONAL_SLASHING_MULTIPLIER_MERGE
elif is_post_altair(spec):
return spec.PROPORTIONAL_SLASHING_MULTIPLIER_ALTAIR
else:
return spec.PROPORTIONAL_SLASHING_MULTIPLIER

View File

@@ -564,6 +564,7 @@ def test_new_justified_is_later_than_store_justified(spec, state):
@with_all_phases
@spec_state_test
@with_presets([MINIMAL], reason="too slow")
def test_new_finalized_slot_is_not_justified_checkpoint_ancestor(spec, state):
"""
J: Justified
@@ -641,6 +642,7 @@ def test_new_finalized_slot_is_not_justified_checkpoint_ancestor(spec, state):
@with_all_phases
@spec_state_test
@with_presets([MINIMAL], reason="too slow")
def test_new_finalized_slot_is_justified_checkpoint_ancestor(spec, state):
"""
J: Justified

View File

@@ -1,7 +1,7 @@
from eth2spec.test.context import (
spec_state_test,
with_all_phases,
is_post_altair,
is_post_altair, is_post_merge,
)
from eth2spec.test.helpers.constants import MAX_UINT_64
@@ -52,7 +52,9 @@ def test_hysteresis_quotient(spec, state):
@spec_state_test
def test_incentives(spec, state):
# Ensure no ETH is minted in slash_validator
if is_post_altair(spec):
if is_post_merge(spec):
assert spec.MIN_SLASHING_PENALTY_QUOTIENT_MERGE <= spec.WHISTLEBLOWER_REWARD_QUOTIENT
elif is_post_altair(spec):
assert spec.MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR <= spec.WHISTLEBLOWER_REWARD_QUOTIENT
else:
assert spec.MIN_SLASHING_PENALTY_QUOTIENT <= spec.WHISTLEBLOWER_REWARD_QUOTIENT

View File

@@ -180,7 +180,7 @@ class ComplexTestStruct(Container):
A: uint16
B: List[uint16, 128]
C: uint8
D: Bytes[256]
D: ByteList[256]
E: VarTestStruct
F: Vector[FixedTestStruct, 4]
G: Vector[VarTestStruct, 2]