Merge pull request #2193 from ethereum/accounting-reform-tests

fix and extend accounting reform tests
This commit is contained in:
Danny Ryan 2021-02-04 10:22:33 -06:00 committed by GitHub
commit ddbd3483cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 300 additions and 41 deletions

View File

@ -7,8 +7,9 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Introduction](#introduction) - [Introduction](#introduction)
- [Custom types](#custom-types)
- [Constants](#constants) - [Constants](#constants)
- [Participation flags](#participation-flags) - [Validator action flags](#validator-action-flags)
- [Participation rewards](#participation-rewards) - [Participation rewards](#participation-rewards)
- [Misc](#misc) - [Misc](#misc)
- [Configuration](#configuration) - [Configuration](#configuration)
@ -55,15 +56,27 @@ This is a patch implementing the first hard fork to the beacon chain, tentativel
and [TODO] reducing the cost of processing chains that have very little or zero participation for a long span of epochs and [TODO] reducing the cost of processing chains that have very little or zero participation for a long span of epochs
* Fork choice rule changes to address weaknesses recently discovered in the existing fork choice * Fork choice rule changes to address weaknesses recently discovered in the existing fork choice
## Custom types
| Name | SSZ equivalent | Description |
| - | - | - |
| `ValidatorFlag` | `uint8` | Bitflags to track validator actions with |
## Constants ## Constants
### Participation flags ### Validator action flags
This is formatted as an enum, with values `2**i` that can be combined as bit-flags.
The `0` value is reserved as default. Remaining bits in `ValidatorFlag` may be used in future hardforks.
**Note**: Unlike Phase0, a `TIMELY_TARGET_FLAG` does not necessarily imply a `TIMELY_SOURCE_FLAG`
due to the varying slot delay requirements of each.
| Name | Value | | Name | Value |
| - | - | | - | - |
| `TIMELY_HEAD_FLAG` | `0` | | `TIMELY_HEAD_FLAG` | `ValidatorFlag(2**0)` (= 1) |
| `TIMELY_SOURCE_FLAG` | `1` | | `TIMELY_SOURCE_FLAG` | `ValidatorFlag(2**1)` (= 2) |
| `TIMELY_TARGET_FLAG` | `2` | | `TIMELY_TARGET_FLAG` | `ValidatorFlag(2**2)` (= 4) |
### Participation rewards ### Participation rewards
@ -80,7 +93,6 @@ The reward fractions add up to 7/8, leaving the remaining 1/8 for proposer rewar
| Name | Value | | Name | Value |
| - | - | | - | - |
| `PARTICIPATION_FLAGS_LENGTH` | `8` |
| `G2_POINT_AT_INFINITY` | `BLSSignature(b'\xc0' + b'\x00' * 95)` | | `G2_POINT_AT_INFINITY` | `BLSSignature(b'\xc0' + b'\x00' * 95)` |
## Configuration ## Configuration
@ -146,8 +158,8 @@ class BeaconState(Container):
# Slashings # Slashings
slashings: Vector[Gwei, EPOCHS_PER_SLASHINGS_VECTOR] # Per-epoch sums of slashed effective balances slashings: Vector[Gwei, EPOCHS_PER_SLASHINGS_VECTOR] # Per-epoch sums of slashed effective balances
# Participation # Participation
previous_epoch_participation: List[Bitvector[PARTICIPATION_FLAGS_LENGTH], VALIDATOR_REGISTRY_LIMIT] previous_epoch_participation: List[ValidatorFlag, VALIDATOR_REGISTRY_LIMIT]
current_epoch_participation: List[Bitvector[PARTICIPATION_FLAGS_LENGTH], VALIDATOR_REGISTRY_LIMIT] current_epoch_participation: List[ValidatorFlag, VALIDATOR_REGISTRY_LIMIT]
# Finality # Finality
justification_bits: Bitvector[JUSTIFICATION_BITS_LENGTH] # Bit set for every recent justified epoch justification_bits: Bitvector[JUSTIFICATION_BITS_LENGTH] # Bit set for every recent justified epoch
previous_justified_checkpoint: Checkpoint previous_justified_checkpoint: Checkpoint
@ -189,7 +201,7 @@ def eth2_fast_aggregate_verify(pubkeys: Sequence[BLSPubkey], message: Bytes32, s
#### `flags_and_numerators` #### `flags_and_numerators`
```python ```python
def get_flags_and_numerators() -> Sequence[Tuple[int, int]]: def get_flags_and_numerators() -> Sequence[Tuple[ValidatorFlag, int]]:
return ( return (
(TIMELY_HEAD_FLAG, TIMELY_HEAD_NUMERATOR), (TIMELY_HEAD_FLAG, TIMELY_HEAD_NUMERATOR),
(TIMELY_SOURCE_FLAG, TIMELY_SOURCE_NUMERATOR), (TIMELY_SOURCE_FLAG, TIMELY_SOURCE_NUMERATOR),
@ -197,7 +209,15 @@ def get_flags_and_numerators() -> Sequence[Tuple[int, int]]:
) )
``` ```
```python
def add_validator_flags(flags: ValidatorFlag, add: ValidatorFlag) -> ValidatorFlag:
return flags | add
```
```python
def has_validator_flags(flags: ValidatorFlag, has: ValidatorFlag) -> bool:
return flags & has == has
```
### Beacon state accessors ### Beacon state accessors
@ -257,7 +277,10 @@ def get_base_reward(state: BeaconState, index: ValidatorIndex) -> Gwei:
#### `get_unslashed_participating_indices` #### `get_unslashed_participating_indices`
```python ```python
def get_unslashed_participating_indices(state: BeaconState, flag: uint8, epoch: Epoch) -> Set[ValidatorIndex]: def get_unslashed_participating_indices(state: BeaconState, flags: ValidatorFlag, epoch: Epoch) -> Set[ValidatorIndex]:
"""
Retrieve the active validator indices of the given epoch, which are not slashed, and have all of the given flags.
"""
assert epoch in (get_previous_epoch(state), get_current_epoch(state)) assert epoch in (get_previous_epoch(state), get_current_epoch(state))
if epoch == get_current_epoch(state): if epoch == get_current_epoch(state):
epoch_participation = state.current_epoch_participation epoch_participation = state.current_epoch_participation
@ -265,7 +288,7 @@ def get_unslashed_participating_indices(state: BeaconState, flag: uint8, epoch:
epoch_participation = state.previous_epoch_participation epoch_participation = state.previous_epoch_participation
participating_indices = [ participating_indices = [
index for index in get_active_validator_indices(state, epoch) index for index in get_active_validator_indices(state, epoch)
if epoch_participation[index][flag] if has_validator_flags(epoch_participation[index], flags)
] ]
return set(filter(lambda index: not state.validators[index].slashed, participating_indices)) return set(filter(lambda index: not state.validators[index].slashed, participating_indices))
``` ```
@ -273,9 +296,11 @@ def get_unslashed_participating_indices(state: BeaconState, flag: uint8, epoch:
#### `get_flag_deltas` #### `get_flag_deltas`
```python ```python
def get_flag_deltas(state: BeaconState, flag: uint8, numerator: uint64) -> Tuple[Sequence[Gwei], Sequence[Gwei]]: def get_flag_deltas(state: BeaconState,
flag: ValidatorFlag,
numerator: uint64) -> Tuple[Sequence[Gwei], Sequence[Gwei]]:
""" """
Computes the rewards and penalties associated with a particular duty, by scanning through the participation Compute the rewards and penalties associated with a particular duty, by scanning through the participation
flags to determine who participated and who did not and assigning them the appropriate rewards and penalties. flags to determine who participated and who did not and assigning them the appropriate rewards and penalties.
""" """
rewards = [Gwei(0)] * len(state.validators) rewards = [Gwei(0)] * len(state.validators)
@ -374,7 +399,7 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None:
# Participation flags # Participation flags
participation_flags = [] participation_flags = []
if is_matching_head and state.slot <= data.slot + MIN_ATTESTATION_INCLUSION_DELAY: if is_matching_head and is_matching_target and state.slot <= data.slot + MIN_ATTESTATION_INCLUSION_DELAY:
participation_flags.append(TIMELY_HEAD_FLAG) participation_flags.append(TIMELY_HEAD_FLAG)
if is_matching_source and state.slot <= data.slot + integer_squareroot(SLOTS_PER_EPOCH): if is_matching_source and state.slot <= data.slot + integer_squareroot(SLOTS_PER_EPOCH):
participation_flags.append(TIMELY_SOURCE_FLAG) participation_flags.append(TIMELY_SOURCE_FLAG)
@ -385,8 +410,8 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None:
proposer_reward_numerator = 0 proposer_reward_numerator = 0
for index in get_attesting_indices(state, data, attestation.aggregation_bits): for index in get_attesting_indices(state, data, attestation.aggregation_bits):
for flag, numerator in get_flags_and_numerators(): for flag, numerator in get_flags_and_numerators():
if flag in participation_flags and not epoch_participation[index][flag]: if flag in participation_flags and not has_validator_flags(epoch_participation[index], flag):
epoch_participation[index][flag] = True epoch_participation[index] = add_validator_flags(epoch_participation[index], flag)
proposer_reward_numerator += get_base_reward(state, index) * numerator proposer_reward_numerator += get_base_reward(state, index) * numerator
# Reward proposer # Reward proposer
@ -432,8 +457,8 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None:
state.validators.append(get_validator_from_deposit(state, deposit)) state.validators.append(get_validator_from_deposit(state, deposit))
state.balances.append(amount) state.balances.append(amount)
# [Added in hf-1] Initialize empty participation flags for new validator # [Added in hf-1] Initialize empty participation flags for new validator
state.previous_epoch_participation.append(Bitvector[PARTICIPATION_FLAGS_LENGTH]()) state.previous_epoch_participation.append(ValidatorFlag(0))
state.current_epoch_participation.append(Bitvector[PARTICIPATION_FLAGS_LENGTH]()) state.current_epoch_participation.append(ValidatorFlag(0))
else: else:
# Increase balance by deposit amount # Increase balance by deposit amount
index = ValidatorIndex(validator_pubkeys.index(pubkey)) index = ValidatorIndex(validator_pubkeys.index(pubkey))
@ -572,5 +597,5 @@ def process_participation_flag_updates(state: BeaconState) -> None:
Call to ``process_participation_flag_updates`` added to ``process_epoch`` in HF1 Call to ``process_participation_flag_updates`` added to ``process_epoch`` in HF1
""" """
state.previous_epoch_participation = state.current_epoch_participation state.previous_epoch_participation = state.current_epoch_participation
state.current_epoch_participation = [Bitvector[PARTICIPATION_FLAGS_LENGTH]() for _ in range(len(state.validators))] state.current_epoch_participation = [ValidatorFlag(0) for _ in range(len(state.validators))]
``` ```

View File

@ -67,8 +67,8 @@ def upgrade_to_lightclient_patch(pre: phase0.BeaconState) -> BeaconState:
# Slashings # Slashings
slashings=pre.slashings, slashings=pre.slashings,
# Attestations # Attestations
previous_epoch_participation=[Bitvector[PARTICIPATION_FLAGS_LENGTH]() for _ in range(len(pre.validators))], previous_epoch_participation=[ValidatorFlag(0) for _ in range(len(pre.validators))],
current_epoch_participation=[Bitvector[PARTICIPATION_FLAGS_LENGTH]() for _ in range(len(pre.validators))], current_epoch_participation=[ValidatorFlag(0) for _ in range(len(pre.validators))],
# Finality # Finality
justification_bits=pre.justification_bits, justification_bits=pre.justification_bits,
previous_justified_checkpoint=pre.previous_justified_checkpoint, previous_justified_checkpoint=pre.previous_justified_checkpoint,

View File

@ -44,11 +44,8 @@ def run_attestation_processing(spec, state, attestation, valid=True):
else: else:
assert len(state.previous_epoch_attestations) == previous_epoch_count + 1 assert len(state.previous_epoch_attestations) == previous_epoch_count + 1
else: else:
for index in spec.get_attesting_indices(state, attestation.data, attestation.aggregation_bits): # After accounting reform, there are cases when processing an attestation does not result in any flag updates
if attestation.data.target.epoch == spec.get_current_epoch(state): pass
assert state.current_epoch_participation[index][spec.TIMELY_TARGET_FLAG]
else:
assert state.previous_epoch_participation[index][spec.TIMELY_TARGET_FLAG]
# yield post-state # yield post-state
yield 'post', state yield 'post', state

View File

@ -6,7 +6,7 @@ from eth2spec.test.context import is_post_lightclient_patch
from eth2spec.test.helpers.attestations import cached_prepare_state_with_attestations from eth2spec.test.helpers.attestations import cached_prepare_state_with_attestations
from eth2spec.test.helpers.deposits import mock_deposit from eth2spec.test.helpers.deposits import mock_deposit
from eth2spec.test.helpers.state import next_epoch from eth2spec.test.helpers.state import next_epoch
from eth2spec.utils.ssz.ssz_typing import Container, uint64, List, Bitvector from eth2spec.utils.ssz.ssz_typing import Container, uint64, List
class Deltas(Container): class Deltas(Container):
@ -314,7 +314,7 @@ def run_test_full_but_partial_participation(spec, state, rng=Random(5522)):
else: else:
for index in range(len(state.validators)): for index in range(len(state.validators)):
if rng.choice([True, False]): if rng.choice([True, False]):
state.previous_epoch_participation[index] = Bitvector[spec.PARTICIPATION_FLAGS_LENGTH]() state.previous_epoch_participation[index] = spec.ValidatorFlag(0)
yield from run_deltas(spec, state) yield from run_deltas(spec, state)
@ -328,7 +328,7 @@ def run_test_partial(spec, state, fraction_filled):
state.previous_epoch_attestations = state.previous_epoch_attestations[:num_attestations] state.previous_epoch_attestations = state.previous_epoch_attestations[:num_attestations]
else: else:
for index in range(int(len(state.validators) * fraction_filled)): for index in range(int(len(state.validators) * fraction_filled)):
state.previous_epoch_participation[index] = Bitvector[spec.PARTICIPATION_FLAGS_LENGTH]() state.previous_epoch_participation[index] = spec.ValidatorFlag(0)
yield from run_deltas(spec, state) yield from run_deltas(spec, state)
@ -394,7 +394,7 @@ def run_test_some_very_low_effective_balances_that_did_not_attest(spec, state):
else: else:
index = 0 index = 0
state.validators[index].effective_balance = 1 state.validators[index].effective_balance = 1
state.previous_epoch_participation[index] = Bitvector[spec.PARTICIPATION_FLAGS_LENGTH]() state.previous_epoch_participation[index] = spec.ValidatorFlag(0)
yield from run_deltas(spec, state) yield from run_deltas(spec, state)
@ -517,11 +517,27 @@ def run_test_full_random(spec, state, rng=Random(8020)):
pending_attestation.inclusion_delay = rng.randint(1, spec.SLOTS_PER_EPOCH) pending_attestation.inclusion_delay = rng.randint(1, spec.SLOTS_PER_EPOCH)
else: else:
for index in range(len(state.validators)): for index in range(len(state.validators)):
# ~1/3 have bad target # ~1/3 have bad head or bad target or not timely enough
state.previous_epoch_participation[index][spec.TIMELY_TARGET_FLAG] = rng.randint(0, 2) != 0 is_timely_correct_head = rng.randint(0, 2) != 0
# ~1/3 have bad head flags = state.previous_epoch_participation[index]
state.previous_epoch_participation[index][spec.TIMELY_HEAD_FLAG] = rng.randint(0, 2) != 0
# ~50% participation
state.previous_epoch_participation[index][spec.TIMELY_SOURCE_FLAG] = rng.choice([True, False])
def set_flag(f, v):
nonlocal flags
if v:
flags |= f
else:
flags &= 0xff ^ f
set_flag(spec.TIMELY_HEAD_FLAG, is_timely_correct_head)
if is_timely_correct_head:
# If timely head, then must be timely target
set_flag(spec.TIMELY_TARGET_FLAG, True)
# If timely head, then must be timely source
set_flag(spec.TIMELY_SOURCE_FLAG, True)
else:
# ~50% of remaining have bad target or not timely enough
set_flag(spec.TIMELY_TARGET_FLAG, rng.choice([True, False]))
# ~50% of remaining have bad source or not timely enough
set_flag(spec.TIMELY_SOURCE_FLAG, rng.choice([True, False]))
state.previous_epoch_participation[index] = flags
yield from run_deltas(spec, state) yield from run_deltas(spec, state)

View File

@ -18,6 +18,7 @@ from eth2spec.test.context import (
with_all_phases_except, with_all_phases_except,
with_configs, with_configs,
spec_state_test, spec_state_test,
always_bls,
) )
from eth2spec.utils.hash_function import hash from eth2spec.utils.hash_function import hash
@ -196,6 +197,7 @@ def test_sync_committee_rewards_duplicate_committee(spec, state):
@with_all_phases_except([PHASE0, PHASE1]) @with_all_phases_except([PHASE0, PHASE1])
@spec_state_test @spec_state_test
@always_bls
def test_invalid_signature_past_block(spec, state): def test_invalid_signature_past_block(spec, state):
committee = spec.get_sync_committee_indices(state, spec.get_current_epoch(state)) committee = spec.get_sync_committee_indices(state, spec.get_current_epoch(state))
@ -237,6 +239,7 @@ def test_invalid_signature_past_block(spec, state):
@with_all_phases_except([PHASE0, PHASE1]) @with_all_phases_except([PHASE0, PHASE1])
@with_configs([MINIMAL], reason="to produce different committee sets") @with_configs([MINIMAL], reason="to produce different committee sets")
@spec_state_test @spec_state_test
@always_bls
def test_invalid_signature_previous_committee(spec, state): def test_invalid_signature_previous_committee(spec, state):
# NOTE: the `state` provided is at genesis and the process to select # NOTE: the `state` provided is at genesis and the process to select
# sync committees currently returns the same committee for the first and second # sync committees currently returns the same committee for the first and second

View File

@ -2,10 +2,13 @@ from eth2spec.test.context import (
spec_state_test, spec_state_test,
always_bls, never_bls, always_bls, never_bls,
with_all_phases, with_all_phases,
with_all_phases_except,
spec_test, spec_test,
low_balances, low_balances,
with_custom_state, with_custom_state,
single_phase) single_phase,
PHASE1,
)
from eth2spec.test.helpers.attestations import ( from eth2spec.test.helpers.attestations import (
run_attestation_processing, run_attestation_processing,
get_valid_attestation, get_valid_attestation,
@ -329,3 +332,212 @@ def test_too_few_aggregation_bits(spec, state):
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, False)
#
# Full correct atttestation contents at different slot inclusions
#
@with_all_phases
@spec_state_test
def test_correct_min_inclusion_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=True)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
yield from run_attestation_processing(spec, state, attestation)
@with_all_phases
@spec_state_test
def test_correct_sqrt_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=True, on_time=False)
next_slots(spec, state, spec.integer_squareroot(spec.SLOTS_PER_EPOCH))
yield from run_attestation_processing(spec, state, attestation)
@with_all_phases
@spec_state_test
def test_correct_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=True, on_time=False)
next_slots(spec, state, spec.SLOTS_PER_EPOCH)
yield from run_attestation_processing(spec, state, attestation)
@with_all_phases
@spec_state_test
def test_correct_after_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=True, on_time=False)
# increment past latest inclusion slot
next_slots(spec, state, spec.SLOTS_PER_EPOCH + 1)
yield from run_attestation_processing(spec, state, attestation, False)
#
# Incorrect head but correct source/target at different slot inclusions
#
@with_all_phases_except([PHASE1])
@spec_state_test
def test_incorrect_head_min_inclusion_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
attestation.data.beacon_block_root = b'\x42' * 32
sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation)
@with_all_phases
@spec_state_test
def test_incorrect_head_sqrt_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False, on_time=False)
next_slots(spec, state, spec.integer_squareroot(spec.SLOTS_PER_EPOCH))
attestation.data.beacon_block_root = b'\x42' * 32
sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation)
@with_all_phases
@spec_state_test
def test_incorrect_head_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False, on_time=False)
next_slots(spec, state, spec.SLOTS_PER_EPOCH)
attestation.data.beacon_block_root = b'\x42' * 32
sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation)
@with_all_phases
@spec_state_test
def test_incorrect_head_after_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False, on_time=False)
# increment past latest inclusion slot
next_slots(spec, state, spec.SLOTS_PER_EPOCH + 1)
attestation.data.beacon_block_root = b'\x42' * 32
sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation, False)
#
# Incorrect head and target but correct source at different slot inclusions
#
# Note: current phase 1 spec checks
# `assert data.beacon_block_root == get_block_root_at_slot(state, compute_previous_slot(state.slot))`
# so this test can't pass that until phase 1 refactor is merged
@with_all_phases_except([PHASE1])
@spec_state_test
def test_incorrect_head_and_target_min_inclusion_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
attestation.data.beacon_block_root = b'\x42' * 32
attestation.data.target.root = b'\x42' * 32
sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation)
@with_all_phases
@spec_state_test
def test_incorrect_head_and_target_sqrt_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False, on_time=False)
next_slots(spec, state, spec.integer_squareroot(spec.SLOTS_PER_EPOCH))
attestation.data.beacon_block_root = b'\x42' * 32
attestation.data.target.root = b'\x42' * 32
sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation)
@with_all_phases
@spec_state_test
def test_incorrect_head_and_target_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False, on_time=False)
next_slots(spec, state, spec.SLOTS_PER_EPOCH)
attestation.data.beacon_block_root = b'\x42' * 32
attestation.data.target.root = b'\x42' * 32
sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation)
@with_all_phases
@spec_state_test
def test_incorrect_head_and_target_after_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False, on_time=False)
# increment past latest inclusion slot
next_slots(spec, state, spec.SLOTS_PER_EPOCH + 1)
attestation.data.beacon_block_root = b'\x42' * 32
attestation.data.target.root = b'\x42' * 32
sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation, False)
#
# Correct head and source but incorrect target at different slot inclusions
#
@with_all_phases_except([PHASE1])
@spec_state_test
def test_incorrect_target_min_inclusion_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
attestation.data.target.root = b'\x42' * 32
sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation)
@with_all_phases
@spec_state_test
def test_incorrect_target_sqrt_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False, on_time=False)
next_slots(spec, state, spec.integer_squareroot(spec.SLOTS_PER_EPOCH))
attestation.data.target.root = b'\x42' * 32
sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation)
@with_all_phases
@spec_state_test
def test_incorrect_target_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False, on_time=False)
next_slots(spec, state, spec.SLOTS_PER_EPOCH)
attestation.data.target.root = b'\x42' * 32
sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation)
@with_all_phases
@spec_state_test
def test_incorrect_target_after_epoch_delay(spec, state):
attestation = get_valid_attestation(spec, state, signed=False, on_time=False)
# increment past latest inclusion slot
next_slots(spec, state, spec.SLOTS_PER_EPOCH + 1)
attestation.data.target.root = b'\x42' * 32
sign_attestation(spec, state, attestation)
yield from run_attestation_processing(spec, state, attestation, False)

View File

@ -78,10 +78,10 @@ def add_mock_attestations(spec, state, epoch, source, target, sufficient_support
else: else:
for i, index in enumerate(committee): for i, index in enumerate(committee):
if aggregation_bits[i]: if aggregation_bits[i]:
epoch_participation[index][spec.TIMELY_HEAD_FLAG] = True epoch_participation[index] |= spec.TIMELY_HEAD_FLAG
epoch_participation[index][spec.TIMELY_SOURCE_FLAG] = True epoch_participation[index] |= spec.TIMELY_SOURCE_FLAG
if not messed_up_target: if not messed_up_target:
epoch_participation[index][spec.TIMELY_TARGET_FLAG] = True epoch_participation[index] |= spec.TIMELY_TARGET_FLAG
def get_checkpoints(spec, epoch): def get_checkpoints(spec, epoch):

View File

@ -29,6 +29,12 @@ def test_full_random_2(spec, state):
yield from rewards_helpers.run_test_full_random(spec, state, rng=Random(3030)) yield from rewards_helpers.run_test_full_random(spec, state, rng=Random(3030))
@with_all_phases
@spec_state_test
def test_full_random_3(spec, state):
yield from rewards_helpers.run_test_full_random(spec, state, rng=Random(4040))
@with_all_phases @with_all_phases
@with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE) @with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE)
@spec_test @spec_test

View File

@ -806,7 +806,7 @@ def test_attestation(spec, state):
assert spec.hash_tree_root(state.previous_epoch_attestations) == pre_current_attestations_root assert spec.hash_tree_root(state.previous_epoch_attestations) == pre_current_attestations_root
else: else:
for index in range(len(state.validators)): for index in range(len(state.validators)):
assert state.current_epoch_participation[index] == spec.Bitvector[spec.PARTICIPATION_FLAGS_LENGTH]() assert state.current_epoch_participation[index] == 0
assert spec.hash_tree_root(state.previous_epoch_participation) == pre_current_epoch_participation_root assert spec.hash_tree_root(state.previous_epoch_participation) == pre_current_epoch_participation_root