mirror of
https://github.com/ethereum/consensus-specs.git
synced 2026-02-03 05:05:14 -05:00
Merge branch 'dev'
This commit is contained in:
@@ -1 +1 @@
|
||||
1.1.3
|
||||
1.1.4
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user