refactor rewards/penalties tests to use a single structure

This commit is contained in:
Danny Ryan 2020-05-18 16:00:59 -06:00
parent 5da4fe37f8
commit 8060505743
No known key found for this signature in database
GPG Key ID: 2765A792E42CE07A
10 changed files with 504 additions and 822 deletions

View File

@ -25,17 +25,50 @@ def has_enough_for_reward(spec, state, index):
) )
def run_attestation_component_deltas(spec, state, component_delta_fn, matching_att_fn): def run_deltas(spec, state):
""" """
Run ``component_delta_fn``, yielding: Run all deltas functions yielding:
- pre-state ('pre') - pre-state ('pre')
- deltas ('deltas') - source deltas ('source_deltas')
- target deltas ('target_deltas')
- head deltas ('head_deltas')
- inclusion delay deltas ('inclusion_delay_deltas')
- inactivity penalty deltas ('inactivity_penalty_deltas')
""" """
yield 'pre', state yield 'pre', state
yield from run_attestation_component_deltas(
spec,
state,
spec.get_source_deltas,
spec.get_matching_source_attestations,
'source_deltas',
)
yield from run_attestation_component_deltas(
spec,
state,
spec.get_target_deltas,
spec.get_matching_target_attestations,
'target_deltas',
)
yield from run_attestation_component_deltas(
spec,
state,
spec.get_head_deltas,
spec.get_matching_head_attestations,
'head_deltas',
)
yield from run_get_inclusion_delay_deltas(spec, state)
yield from run_get_inactivity_penalty_deltas(spec, state)
def run_attestation_component_deltas(spec, state, component_delta_fn, matching_att_fn, deltas_name):
"""
Run ``component_delta_fn``, yielding:
- deltas ('{``deltas_name``}')
"""
rewards, penalties = component_delta_fn(state) rewards, penalties = component_delta_fn(state)
yield 'deltas', Deltas(rewards=rewards, penalties=penalties) yield deltas_name, Deltas(rewards=rewards, penalties=penalties)
matching_attestations = matching_att_fn(state, spec.get_previous_epoch(state)) matching_attestations = matching_att_fn(state, spec.get_previous_epoch(state))
matching_indices = spec.get_unslashed_attesting_indices(state, matching_attestations) matching_indices = spec.get_unslashed_attesting_indices(state, matching_attestations)
@ -62,6 +95,81 @@ def run_attestation_component_deltas(spec, state, component_delta_fn, matching_a
assert penalties[index] == 0 assert penalties[index] == 0
def run_get_inclusion_delay_deltas(spec, state):
"""
Run ``get_inclusion_delay_deltas``, yielding:
- inclusion delay deltas ('inclusion_delay_deltas')
"""
rewards, penalties = spec.get_inclusion_delay_deltas(state)
yield 'inclusion_delay_deltas', Deltas(rewards=rewards, penalties=penalties)
eligible_attestations = spec.get_matching_source_attestations(state, spec.get_previous_epoch(state))
attesting_indices = spec.get_unslashed_attesting_indices(state, eligible_attestations)
rewarded_indices = set()
rewarded_proposer_indices = set()
# Ensure attesters with enough balance are rewarded for attestations
# Track those that are rewarded and track proposers that should be rewarded
for index in range(len(state.validators)):
if index in attesting_indices and has_enough_for_reward(spec, state, index):
assert rewards[index] > 0
rewarded_indices.add(index)
# Track proposer of earliest included attestation for the validator defined by index
earliest_attestation = min([
a for a in eligible_attestations
if index in spec.get_attesting_indices(state, a.data, a.aggregation_bits)
], key=lambda a: a.inclusion_delay)
rewarded_proposer_indices.add(earliest_attestation.proposer_index)
# Ensure all expected proposers have been rewarded
# Track rewarde indices
proposing_indices = [a.proposer_index for a in eligible_attestations]
for index in proposing_indices:
if index in rewarded_proposer_indices:
assert rewards[index] > 0
rewarded_indices.add(index)
# Ensure all expected non-rewarded indices received no reward
for index in range(len(state.validators)):
assert penalties[index] == 0
if index not in rewarded_indices:
assert rewards[index] == 0
def run_get_inactivity_penalty_deltas(spec, state):
"""
Run ``get_inactivity_penalty_deltas``, yielding:
- inactivity penalty deltas ('inactivity_penalty_deltas')
"""
rewards, penalties = spec.get_inactivity_penalty_deltas(state)
yield 'inactivity_penalty_deltas', Deltas(rewards=rewards, penalties=penalties)
matching_attestations = spec.get_matching_target_attestations(state, spec.get_previous_epoch(state))
matching_attesting_indices = spec.get_unslashed_attesting_indices(state, matching_attestations)
finality_delay = spec.get_previous_epoch(state) - state.finalized_checkpoint.epoch
eligible_indices = spec.get_eligible_validator_indices(state)
for index in range(len(state.validators)):
assert rewards[index] == 0
if index not in eligible_indices:
assert penalties[index] == 0
continue
if finality_delay > spec.MIN_EPOCHS_TO_INACTIVITY_PENALTY:
base_penalty = spec.BASE_REWARDS_PER_EPOCH * spec.get_base_reward(state, index)
if not has_enough_for_reward(spec, state, index):
assert penalties[index] == 0
elif index in matching_attesting_indices:
assert penalties[index] == base_penalty
else:
assert penalties[index] > base_penalty
else:
assert penalties[index] == 0
def set_some_new_deposits(spec, state, rng): def set_some_new_deposits(spec, state, rng):
num_validators = len(state.validators) num_validators = len(state.validators)
# Set ~1/10 to just recently deposited # Set ~1/10 to just recently deposited
@ -102,74 +210,74 @@ def slash_random_validators(spec, state, rng):
spec.slash_validator(state, index) spec.slash_validator(state, index)
def run_test_empty(spec, state, runner): def run_test_empty(spec, state):
# Do not add any attestations to state # Do not add any attestations to state
yield from runner(spec, state) yield from run_deltas(spec, state)
def run_test_full_all_correct(spec, state, runner): def run_test_full_all_correct(spec, state):
prepare_state_with_attestations(spec, state) prepare_state_with_attestations(spec, state)
yield from runner(spec, state) yield from run_deltas(spec, state)
def run_test_full_but_partial_participation(spec, state, runner, rng=Random(5522)): def run_test_full_but_partial_participation(spec, state, rng=Random(5522)):
prepare_state_with_attestations(spec, state) prepare_state_with_attestations(spec, state)
for a in state.previous_epoch_attestations: for a in state.previous_epoch_attestations:
a.aggregation_bits = [rng.choice([True, False]) for _ in a.aggregation_bits] a.aggregation_bits = [rng.choice([True, False]) for _ in a.aggregation_bits]
yield from runner(spec, state) yield from run_deltas(spec, state)
def run_test_partial(spec, state, fraction_filled, runner): def run_test_partial(spec, state, fraction_filled):
prepare_state_with_attestations(spec, state) prepare_state_with_attestations(spec, state)
# Remove portion of attestations # Remove portion of attestations
num_attestations = int(len(state.previous_epoch_attestations) * fraction_filled) num_attestations = int(len(state.previous_epoch_attestations) * fraction_filled)
state.previous_epoch_attestations = state.previous_epoch_attestations[:num_attestations] state.previous_epoch_attestations = state.previous_epoch_attestations[:num_attestations]
yield from runner(spec, state) yield from run_deltas(spec, state)
def run_test_half_full(spec, state, runner): def run_test_half_full(spec, state):
yield from run_test_partial(spec, state, 0.5, runner) yield from run_test_partial(spec, state, 0.5)
def run_test_one_attestation_one_correct(spec, state, runner): def run_test_one_attestation_one_correct(spec, state):
prepare_state_with_attestations(spec, state) prepare_state_with_attestations(spec, state)
# Remove all attestations except for the first one # Remove all attestations except for the first one
state.previous_epoch_attestations = state.previous_epoch_attestations[:1] state.previous_epoch_attestations = state.previous_epoch_attestations[:1]
yield from runner(spec, state) yield from run_deltas(spec, state)
def run_test_with_not_yet_activated_validators(spec, state, runner, rng=Random(5555)): def run_test_with_not_yet_activated_validators(spec, state, rng=Random(5555)):
set_some_new_deposits(spec, state, rng) set_some_new_deposits(spec, state, rng)
prepare_state_with_attestations(spec, state) prepare_state_with_attestations(spec, state)
yield from runner(spec, state) yield from run_deltas(spec, state)
def run_test_with_exited_validators(spec, state, runner, rng=Random(1337)): def run_test_with_exited_validators(spec, state, rng=Random(1337)):
exit_random_validators(spec, state, rng) exit_random_validators(spec, state, rng)
prepare_state_with_attestations(spec, state) prepare_state_with_attestations(spec, state)
yield from runner(spec, state) yield from run_deltas(spec, state)
def run_test_with_slashed_validators(spec, state, runner, rng=Random(3322)): def run_test_with_slashed_validators(spec, state, rng=Random(3322)):
exit_random_validators(spec, state, rng) exit_random_validators(spec, state, rng)
slash_random_validators(spec, state, rng) slash_random_validators(spec, state, rng)
prepare_state_with_attestations(spec, state) prepare_state_with_attestations(spec, state)
yield from runner(spec, state) yield from run_deltas(spec, state)
def run_test_some_very_low_effective_balances_that_attested(spec, state, runner): def run_test_some_very_low_effective_balances_that_attested(spec, state):
state.balances state.balances
prepare_state_with_attestations(spec, state) prepare_state_with_attestations(spec, state)
@ -178,10 +286,10 @@ def run_test_some_very_low_effective_balances_that_attested(spec, state, runner)
for i, index in enumerate(range(5)): for i, index in enumerate(range(5)):
state.validators[index].effective_balance = i state.validators[index].effective_balance = i
yield from runner(spec, state) yield from run_deltas(spec, state)
def run_test_some_very_low_effective_balances_that_did_not_attest(spec, state, runner): def run_test_some_very_low_effective_balances_that_did_not_attest(spec, state):
prepare_state_with_attestations(spec, state) prepare_state_with_attestations(spec, state)
# Remove attestation # Remove attestation
@ -192,10 +300,10 @@ def run_test_some_very_low_effective_balances_that_did_not_attest(spec, state, r
for i, index in enumerate(indices): for i, index in enumerate(indices):
state.validators[index].effective_balance = i state.validators[index].effective_balance = i
yield from runner(spec, state) yield from run_deltas(spec, state)
def run_test_full_fraction_incorrect(spec, state, correct_target, correct_head, fraction_incorrect, runner): def run_test_full_fraction_incorrect(spec, state, correct_target, correct_head, fraction_incorrect):
prepare_state_with_attestations(spec, state) prepare_state_with_attestations(spec, state)
# Make fraction_incorrect of pending attestations have bad target/head as specified # Make fraction_incorrect of pending attestations have bad target/head as specified
@ -206,10 +314,92 @@ def run_test_full_fraction_incorrect(spec, state, correct_target, correct_head,
if not correct_head: if not correct_head:
pending_attestation.data.beacon_block_root = b'\x66' * 32 pending_attestation.data.beacon_block_root = b'\x66' * 32
yield from runner(spec, state) yield from run_deltas(spec, state)
def run_test_full_random(spec, state, runner, rng=Random(8020)): def run_test_full_delay_one_slot(spec, state):
prepare_state_with_attestations(spec, state)
for a in state.previous_epoch_attestations:
a.inclusion_delay += 1
yield from run_deltas(spec, state)
def run_test_full_delay_max_slots(spec, state):
prepare_state_with_attestations(spec, state)
for a in state.previous_epoch_attestations:
a.inclusion_delay += spec.SLOTS_PER_EPOCH
yield from run_deltas(spec, state)
def run_test_full_mixed_delay(spec, state, rng=Random(1234)):
prepare_state_with_attestations(spec, state)
for a in state.previous_epoch_attestations:
a.inclusion_delay = rng.randint(1, spec.SLOTS_PER_EPOCH)
yield from run_deltas(spec, state)
def run_test_proposer_not_in_attestations(spec, state):
prepare_state_with_attestations(spec, state)
# Get an attestation where the proposer is not in the committee
non_proposer_attestations = []
for a in state.previous_epoch_attestations:
if a.proposer_index not in spec.get_unslashed_attesting_indices(state, [a]):
non_proposer_attestations.append(a)
assert any(non_proposer_attestations)
state.previous_epoch_attestations = non_proposer_attestations
yield from run_deltas(spec, state)
def run_test_duplicate_attestations_at_later_slots(spec, state):
prepare_state_with_attestations(spec, state)
# Remove 2/3 of attestations to make it more interesting
num_attestations = int(len(state.previous_epoch_attestations) * 0.33)
state.previous_epoch_attestations = state.previous_epoch_attestations[:num_attestations]
# Get map of the proposer at each slot to make valid-looking duplicate attestations
per_slot_proposers = {
(a.data.slot + a.inclusion_delay): a.proposer_index
for a in state.previous_epoch_attestations
}
max_slot = max([a.data.slot + a.inclusion_delay for a in state.previous_epoch_attestations])
later_attestations = []
for a in state.previous_epoch_attestations:
# Only have proposers for previous epoch so do not create later
# duplicate if slot exceeds the max slot in previous_epoch_attestations
if a.data.slot + a.inclusion_delay >= max_slot:
continue
later_a = a.copy()
later_a.inclusion_delay += 1
later_a.proposer_index = per_slot_proposers[later_a.data.slot + later_a.inclusion_delay]
later_attestations.append(later_a)
assert any(later_attestations)
state.previous_epoch_attestations = sorted(
state.previous_epoch_attestations + later_attestations,
key=lambda a: a.data.slot + a.inclusion_delay
)
yield from run_deltas(spec, state)
def run_test_all_balances_too_low_for_reward(spec, state):
prepare_state_with_attestations(spec, state)
for index in range(len(state.validators)):
state.validators[index].effective_balance = 10
yield from run_deltas(spec, state)
def run_test_full_random(spec, state, rng=Random(8020)):
set_some_new_deposits(spec, state, rng) set_some_new_deposits(spec, state, rng)
exit_random_validators(spec, state, rng) exit_random_validators(spec, state, rng)
slash_random_validators(spec, state, rng) slash_random_validators(spec, state, rng)
@ -228,4 +418,4 @@ def run_test_full_random(spec, state, runner, rng=Random(8020)):
# Random inclusion delay # Random inclusion delay
pending_attestation.inclusion_delay = rng.randint(1, spec.SLOTS_PER_EPOCH) pending_attestation.inclusion_delay = rng.randint(1, spec.SLOTS_PER_EPOCH)
yield from runner(spec, state) yield from run_deltas(spec, state)

View File

@ -1,89 +1,71 @@
from eth2spec.test.context import with_all_phases, spec_state_test from eth2spec.test.context import with_all_phases, spec_state_test
from eth2spec.test.helpers.rewards import run_attestation_component_deltas
import eth2spec.test.helpers.rewards as rewards_helpers import eth2spec.test.helpers.rewards as rewards_helpers
def run_get_source_deltas(spec, state):
"""
Run ``get_source_deltas``, yielding:
- pre-state ('pre')
- deltas ('deltas')
"""
yield from run_attestation_component_deltas(
spec,
state,
spec.get_source_deltas,
spec.get_matching_source_attestations,
)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_empty(spec, state): def test_empty(spec, state):
yield from rewards_helpers.run_test_empty(spec, state, run_get_source_deltas) yield from rewards_helpers.run_test_empty(spec, state)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_full_all_correct(spec, state): def test_full_all_correct(spec, state):
yield from rewards_helpers.run_test_full_all_correct(spec, state, run_get_source_deltas) yield from rewards_helpers.run_test_full_all_correct(spec, state)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_half_full(spec, state): def test_half_full(spec, state):
yield from rewards_helpers.run_test_half_full(spec, state, run_get_source_deltas) yield from rewards_helpers.run_test_half_full(spec, state)
@with_all_phases
@spec_state_test
def test_quarter_full(spec, state):
yield from rewards_helpers.run_test_partial(spec, state, 0.25)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_full_but_partial_participation(spec, state): def test_full_but_partial_participation(spec, state):
yield from rewards_helpers.run_test_full_but_partial_participation(spec, state, run_get_source_deltas) yield from rewards_helpers.run_test_full_but_partial_participation(spec, state)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_one_attestation_one_correct(spec, state): def test_one_attestation_one_correct(spec, state):
yield from rewards_helpers.run_test_one_attestation_one_correct(spec, state, run_get_source_deltas) yield from rewards_helpers.run_test_one_attestation_one_correct(spec, state)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_with_not_yet_activated_validators(spec, state): def test_with_not_yet_activated_validators(spec, state):
yield from rewards_helpers.run_test_with_not_yet_activated_validators(spec, state, run_get_source_deltas) yield from rewards_helpers.run_test_with_not_yet_activated_validators(spec, state)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_with_exited_validators(spec, state): def test_with_exited_validators(spec, state):
yield from rewards_helpers.run_test_with_exited_validators(spec, state, run_get_source_deltas) yield from rewards_helpers.run_test_with_exited_validators(spec, state)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_with_slashed_validators(spec, state): def test_with_slashed_validators(spec, state):
yield from rewards_helpers.run_test_with_slashed_validators(spec, state, run_get_source_deltas) yield from rewards_helpers.run_test_with_slashed_validators(spec, state)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_some_very_low_effective_balances_that_attested(spec, state): def test_some_very_low_effective_balances_that_attested(spec, state):
yield from rewards_helpers.run_test_some_very_low_effective_balances_that_attested( yield from rewards_helpers.run_test_some_very_low_effective_balances_that_attested(spec, state)
spec,
state,
run_get_source_deltas
)
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_some_very_low_effective_balances_that_did_not_attest(spec, state): def test_some_very_low_effective_balances_that_did_not_attest(spec, state):
yield from rewards_helpers.run_test_some_very_low_effective_balances_that_did_not_attest( yield from rewards_helpers.run_test_some_very_low_effective_balances_that_did_not_attest(spec, state)
spec,
state,
run_get_source_deltas,
)
# #
@ -101,7 +83,6 @@ def test_full_half_correct_target_incorrect_head(spec, state):
correct_target=True, correct_target=True,
correct_head=False, correct_head=False,
fraction_incorrect=0.5, fraction_incorrect=0.5,
runner=run_get_source_deltas
) )
@ -113,7 +94,6 @@ def test_full_correct_target_incorrect_head(spec, state):
correct_target=True, correct_target=True,
correct_head=False, correct_head=False,
fraction_incorrect=1.0, fraction_incorrect=1.0,
runner=run_get_source_deltas
) )
@ -125,7 +105,6 @@ def test_full_half_incorrect_target_incorrect_head(spec, state):
correct_target=False, correct_target=False,
correct_head=False, correct_head=False,
fraction_incorrect=0.5, fraction_incorrect=0.5,
runner=run_get_source_deltas
) )
@ -137,11 +116,40 @@ def test_full_half_incorrect_target_correct_head(spec, state):
correct_target=False, correct_target=False,
correct_head=True, correct_head=True,
fraction_incorrect=0.5, fraction_incorrect=0.5,
runner=run_get_source_deltas
) )
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_full_random(spec, state): def test_full_delay_one_slot(spec, state):
yield from rewards_helpers.run_test_full_random(spec, state, run_get_source_deltas) yield from rewards_helpers.run_test_full_delay_one_slot(spec, state)
@with_all_phases
@spec_state_test
def test_full_delay_max_slots(spec, state):
yield from rewards_helpers.run_test_full_delay_max_slots(spec, state)
@with_all_phases
@spec_state_test
def test_full_mixed_delay(spec, state):
yield from rewards_helpers.run_test_full_mixed_delay(spec, state)
@with_all_phases
@spec_state_test
def test_proposer_not_in_attestations(spec, state):
yield from rewards_helpers.run_test_proposer_not_in_attestations(spec, state)
@with_all_phases
@spec_state_test
def test_duplicate_attestations_at_later_slots(spec, state):
yield from rewards_helpers.run_test_duplicate_attestations_at_later_slots(spec, state)
@with_all_phases
@spec_state_test
def test_all_balances_too_low_for_reward(spec, state):
yield from rewards_helpers.run_test_all_balances_too_low_for_reward(spec, state)

View File

@ -1,136 +0,0 @@
from eth2spec.test.context import with_all_phases, spec_state_test
from eth2spec.test.helpers.rewards import run_attestation_component_deltas
import eth2spec.test.helpers.rewards as rewards_helpers
def run_get_head_deltas(spec, state):
"""
Run ``get_head_deltas``, yielding:
- pre-state ('pre')
- deltas ('deltas')
"""
yield from run_attestation_component_deltas(
spec,
state,
spec.get_head_deltas,
spec.get_matching_head_attestations,
)
@with_all_phases
@spec_state_test
def test_empty(spec, state):
yield from rewards_helpers.run_test_empty(spec, state, run_get_head_deltas)
@with_all_phases
@spec_state_test
def test_full_all_correct(spec, state):
yield from rewards_helpers.run_test_full_all_correct(spec, state, run_get_head_deltas)
@with_all_phases
@spec_state_test
def test_half_full(spec, state):
yield from rewards_helpers.run_test_half_full(spec, state, run_get_head_deltas)
@with_all_phases
@spec_state_test
def test_full_but_partial_participation(spec, state):
yield from rewards_helpers.run_test_full_but_partial_participation(spec, state, run_get_head_deltas)
@with_all_phases
@spec_state_test
def test_one_attestation_one_correct(spec, state):
yield from rewards_helpers.run_test_one_attestation_one_correct(spec, state, run_get_head_deltas)
@with_all_phases
@spec_state_test
def test_with_not_yet_activated_validators(spec, state):
yield from rewards_helpers.run_test_with_not_yet_activated_validators(spec, state, run_get_head_deltas)
@with_all_phases
@spec_state_test
def test_with_exited_validators(spec, state):
yield from rewards_helpers.run_test_with_exited_validators(spec, state, run_get_head_deltas)
@with_all_phases
@spec_state_test
def test_with_slashed_validators(spec, state):
yield from rewards_helpers.run_test_with_slashed_validators(spec, state, run_get_head_deltas)
@with_all_phases
@spec_state_test
def test_some_very_low_effective_balances_that_attested(spec, state):
yield from rewards_helpers.run_test_some_very_low_effective_balances_that_attested(spec, state, run_get_head_deltas)
@with_all_phases
@spec_state_test
def test_some_very_low_effective_balances_that_did_not_attest(spec, state):
yield from rewards_helpers.run_test_some_very_low_effective_balances_that_did_not_attest(
spec,
state,
run_get_head_deltas,
)
@with_all_phases
@spec_state_test
def test_full_half_correct_target_incorrect_head(spec, state):
yield from rewards_helpers.run_test_full_fraction_incorrect(
spec, state,
correct_target=True,
correct_head=False,
fraction_incorrect=0.5,
runner=run_get_head_deltas
)
@with_all_phases
@spec_state_test
def test_full_correct_target_incorrect_head(spec, state):
yield from rewards_helpers.run_test_full_fraction_incorrect(
spec, state,
correct_target=True,
correct_head=False,
fraction_incorrect=1.0,
runner=run_get_head_deltas
)
@with_all_phases
@spec_state_test
def test_full_half_incorrect_target_incorrect_head(spec, state):
yield from rewards_helpers.run_test_full_fraction_incorrect(
spec, state,
correct_target=False,
correct_head=False,
fraction_incorrect=0.5,
runner=run_get_head_deltas
)
@with_all_phases
@spec_state_test
def test_full_half_incorrect_target_correct_head(spec, state):
yield from rewards_helpers.run_test_full_fraction_incorrect(
spec, state,
correct_target=False,
correct_head=True,
fraction_incorrect=0.5,
runner=run_get_head_deltas
)
@with_all_phases
@spec_state_test
def test_full_random(spec, state):
yield from rewards_helpers.run_test_full_random(spec, state, run_get_head_deltas)

View File

@ -1,231 +0,0 @@
from eth2spec.test.context import with_all_phases, spec_state_test
from eth2spec.test.helpers.rewards import has_enough_for_reward
from eth2spec.test.helpers.state import next_epoch
from eth2spec.test.helpers.rewards import Deltas
import eth2spec.test.helpers.rewards as rewards_helpers
def run_get_inactivity_penalty_deltas(spec, state):
"""
Run ``get_inactivity_penalty_deltas``, yielding:
- pre-state ('pre')
- deltas ('deltas')
"""
yield 'pre', state
rewards, penalties = spec.get_inactivity_penalty_deltas(state)
yield 'deltas', Deltas(rewards=rewards, penalties=penalties)
matching_attestations = spec.get_matching_target_attestations(state, spec.get_previous_epoch(state))
matching_attesting_indices = spec.get_unslashed_attesting_indices(state, matching_attestations)
finality_delay = spec.get_previous_epoch(state) - state.finalized_checkpoint.epoch
eligible_indices = spec.get_eligible_validator_indices(state)
for index in range(len(state.validators)):
assert rewards[index] == 0
if index not in eligible_indices:
assert penalties[index] == 0
continue
if finality_delay > spec.MIN_EPOCHS_TO_INACTIVITY_PENALTY:
base_penalty = spec.BASE_REWARDS_PER_EPOCH * spec.get_base_reward(state, index)
if not has_enough_for_reward(spec, state, index):
assert penalties[index] == 0
elif index in matching_attesting_indices:
assert penalties[index] == base_penalty
else:
assert penalties[index] > base_penalty
else:
assert penalties[index] == 0
def transition_state_to_leak(spec, state, epochs=None):
if epochs is None:
epochs = spec.MIN_EPOCHS_TO_INACTIVITY_PENALTY
assert epochs >= spec.MIN_EPOCHS_TO_INACTIVITY_PENALTY
for _ in range(epochs):
next_epoch(spec, state)
@with_all_phases
@spec_state_test
def test_empty_no_leak(spec, state):
yield from rewards_helpers.run_test_empty(spec, state, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_empty_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_empty(spec, state, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_full_no_leak(spec, state):
yield from rewards_helpers.run_test_full_all_correct(spec, state, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_full_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_full_all_correct(spec, state, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_half_full_no_leak(spec, state):
yield from rewards_helpers.run_test_half_full(spec, state, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_half_full_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_half_full(spec, state, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_quarter_full_no_leak(spec, state):
yield from rewards_helpers.run_test_partial(spec, state, 0.25, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_quarter_full_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_partial(spec, state, 0.25, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_full_but_partial_participation_no_leak(spec, state):
yield from rewards_helpers.run_test_full_but_partial_participation(spec, state, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_full_but_partial_participation_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_full_but_partial_participation(spec, state, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_with_not_yet_activated_validators_no_leak(spec, state):
yield from rewards_helpers.run_test_with_not_yet_activated_validators(
spec,
state,
run_get_inactivity_penalty_deltas,
)
@with_all_phases
@spec_state_test
def test_with_not_yet_activated_validators_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_with_not_yet_activated_validators(
spec,
state,
run_get_inactivity_penalty_deltas,
)
@with_all_phases
@spec_state_test
def test_with_exited_validators_no_leak(spec, state):
yield from rewards_helpers.run_test_with_exited_validators(spec, state, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_with_exited_validators_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_with_exited_validators(spec, state, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_with_slashed_validators_no_leak(spec, state):
yield from rewards_helpers.run_test_with_slashed_validators(spec, state, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_with_slashed_validators_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_with_slashed_validators(spec, state, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_some_very_low_effective_balances_that_attested_no_leak(spec, state):
yield from rewards_helpers.run_test_some_very_low_effective_balances_that_attested(
spec,
state,
run_get_inactivity_penalty_deltas,
)
@with_all_phases
@spec_state_test
def test_some_very_low_effective_balances_that_attested_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_some_very_low_effective_balances_that_attested(
spec,
state,
run_get_inactivity_penalty_deltas,
)
@with_all_phases
@spec_state_test
def test_some_very_low_effective_balances_that_did_not_attest_no_leak(spec, state):
yield from rewards_helpers.run_test_some_very_low_effective_balances_that_did_not_attest(
spec,
state,
run_get_inactivity_penalty_deltas,
)
@with_all_phases
@spec_state_test
def test_some_very_low_effective_balances_that_did_not_attest_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_some_very_low_effective_balances_that_did_not_attest(
spec,
state,
run_get_inactivity_penalty_deltas,
)
@with_all_phases
@spec_state_test
def test_full_random_no_leak(spec, state):
yield from rewards_helpers.run_test_full_random(spec, state, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_full_random_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_full_random(spec, state, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_full_random_five_epoch_leak(spec, state):
transition_state_to_leak(spec, state, epochs=5)
yield from rewards_helpers.run_test_full_random(spec, state, run_get_inactivity_penalty_deltas)
@with_all_phases
@spec_state_test
def test_full_random_ten_epoch_leak(spec, state):
transition_state_to_leak(spec, state, epochs=10)
yield from rewards_helpers.run_test_full_random(spec, state, run_get_inactivity_penalty_deltas)

View File

@ -1,213 +0,0 @@
from random import Random
from eth2spec.test.context import with_all_phases, spec_state_test
from eth2spec.test.helpers.attestations import prepare_state_with_attestations
from eth2spec.test.helpers.rewards import Deltas, has_enough_for_reward
import eth2spec.test.helpers.rewards as rewards_helpers
def run_get_inclusion_delay_deltas(spec, state):
"""
Run ``get_inclusion_delay_deltas``, yielding:
- pre-state ('pre')
- deltas ('deltas')
"""
yield 'pre', state
rewards, penalties = spec.get_inclusion_delay_deltas(state)
yield 'deltas', Deltas(rewards=rewards, penalties=penalties)
eligible_attestations = spec.get_matching_source_attestations(state, spec.get_previous_epoch(state))
attesting_indices = spec.get_unslashed_attesting_indices(state, eligible_attestations)
rewarded_indices = set()
rewarded_proposer_indices = set()
# Ensure attesters with enough balance are rewarded for attestations
# Track those that are rewarded and track proposers that should be rewarded
for index in range(len(state.validators)):
if index in attesting_indices and has_enough_for_reward(spec, state, index):
assert rewards[index] > 0
rewarded_indices.add(index)
# Track proposer of earliest included attestation for the validator defined by index
earliest_attestation = min([
a for a in eligible_attestations
if index in spec.get_attesting_indices(state, a.data, a.aggregation_bits)
], key=lambda a: a.inclusion_delay)
rewarded_proposer_indices.add(earliest_attestation.proposer_index)
# Ensure all expected proposers have been rewarded
# Track rewarde indices
proposing_indices = [a.proposer_index for a in eligible_attestations]
for index in proposing_indices:
if index in rewarded_proposer_indices:
assert rewards[index] > 0
rewarded_indices.add(index)
# Ensure all expected non-rewarded indices received no reward
for index in range(len(state.validators)):
assert penalties[index] == 0
if index not in rewarded_indices:
assert rewards[index] == 0
@with_all_phases
@spec_state_test
def test_empty(spec, state):
yield from rewards_helpers.run_test_empty(spec, state, run_get_inclusion_delay_deltas)
@with_all_phases
@spec_state_test
def test_full(spec, state):
yield from rewards_helpers.run_test_full_all_correct(spec, state, run_get_inclusion_delay_deltas)
@with_all_phases
@spec_state_test
def test_half_full(spec, state):
yield from rewards_helpers.run_test_half_full(spec, state, run_get_inclusion_delay_deltas)
@with_all_phases
@spec_state_test
def test_quarter_full(spec, state):
yield from rewards_helpers.run_test_partial(spec, state, 0.25, run_get_inclusion_delay_deltas)
@with_all_phases
@spec_state_test
def test_full_but_partial_participation(spec, state):
yield from rewards_helpers.run_test_full_but_partial_participation(spec, state, run_get_inclusion_delay_deltas)
@with_all_phases
@spec_state_test
def test_with_not_yet_activated_validators(spec, state):
yield from rewards_helpers.run_test_with_not_yet_activated_validators(spec, state, run_get_inclusion_delay_deltas)
@with_all_phases
@spec_state_test
def test_with_exited_validators(spec, state):
yield from rewards_helpers.run_test_with_exited_validators(spec, state, run_get_inclusion_delay_deltas)
@with_all_phases
@spec_state_test
def test_with_slashed_validators(spec, state):
yield from rewards_helpers.run_test_with_slashed_validators(spec, state, run_get_inclusion_delay_deltas)
@with_all_phases
@spec_state_test
def test_some_very_low_effective_balances_that_attested(spec, state):
yield from rewards_helpers.run_test_some_very_low_effective_balances_that_attested(
spec,
state,
run_get_inclusion_delay_deltas
)
@with_all_phases
@spec_state_test
def test_full_random(spec, state):
yield from rewards_helpers.run_test_full_random(spec, state, run_get_inclusion_delay_deltas)
@with_all_phases
@spec_state_test
def test_full_delay_one_slot(spec, state):
prepare_state_with_attestations(spec, state)
for a in state.previous_epoch_attestations:
a.inclusion_delay += 1
yield from run_get_inclusion_delay_deltas(spec, state)
@with_all_phases
@spec_state_test
def test_full_delay_max_slots(spec, state):
prepare_state_with_attestations(spec, state)
for a in state.previous_epoch_attestations:
a.inclusion_delay += spec.SLOTS_PER_EPOCH
yield from run_get_inclusion_delay_deltas(spec, state)
@with_all_phases
@spec_state_test
def test_full_mixed_delay(spec, state):
rng = Random(1234)
prepare_state_with_attestations(spec, state)
for a in state.previous_epoch_attestations:
a.inclusion_delay = rng.randint(1, spec.SLOTS_PER_EPOCH)
yield from run_get_inclusion_delay_deltas(spec, state)
@with_all_phases
@spec_state_test
def test_proposer_not_in_attestations(spec, state):
prepare_state_with_attestations(spec, state)
# Get an attestation where the proposer is not in the committee
non_proposer_attestations = []
for a in state.previous_epoch_attestations:
if a.proposer_index not in spec.get_unslashed_attesting_indices(state, [a]):
non_proposer_attestations.append(a)
assert any(non_proposer_attestations)
state.previous_epoch_attestations = non_proposer_attestations
yield from run_get_inclusion_delay_deltas(spec, state)
@with_all_phases
@spec_state_test
def test_duplicate_attestations_at_later_slots(spec, state):
prepare_state_with_attestations(spec, state)
# Remove 2/3 of attestations to make it more interesting
num_attestations = int(len(state.previous_epoch_attestations) * 0.33)
state.previous_epoch_attestations = state.previous_epoch_attestations[:num_attestations]
# Get map of the proposer at each slot to make valid-looking duplicate attestations
per_slot_proposers = {
(a.data.slot + a.inclusion_delay): a.proposer_index
for a in state.previous_epoch_attestations
}
max_slot = max([a.data.slot + a.inclusion_delay for a in state.previous_epoch_attestations])
later_attestations = []
for a in state.previous_epoch_attestations:
# Only have proposers for previous epoch so do not create later
# duplicate if slot exceeds the max slot in previous_epoch_attestations
if a.data.slot + a.inclusion_delay >= max_slot:
continue
later_a = a.copy()
later_a.inclusion_delay += 1
later_a.proposer_index = per_slot_proposers[later_a.data.slot + later_a.inclusion_delay]
later_attestations.append(later_a)
assert any(later_attestations)
state.previous_epoch_attestations = sorted(
state.previous_epoch_attestations + later_attestations,
key=lambda a: a.data.slot + a.inclusion_delay
)
yield from run_get_inclusion_delay_deltas(spec, state)
@with_all_phases
@spec_state_test
def test_all_balances_too_low_for_reward(spec, state):
prepare_state_with_attestations(spec, state)
for index in range(len(state.validators)):
state.validators[index].effective_balance = 10
yield from run_get_inclusion_delay_deltas(spec, state)

View File

@ -1,140 +0,0 @@
from eth2spec.test.context import with_all_phases, spec_state_test
from eth2spec.test.helpers.rewards import run_attestation_component_deltas
import eth2spec.test.helpers.rewards as rewards_helpers
def run_get_target_deltas(spec, state):
"""
Run ``get_target_deltas``, yielding:
- pre-state ('pre')
- deltas ('deltas')
"""
yield from run_attestation_component_deltas(
spec,
state,
spec.get_target_deltas,
spec.get_matching_target_attestations,
)
@with_all_phases
@spec_state_test
def test_empty(spec, state):
yield from rewards_helpers.run_test_empty(spec, state, run_get_target_deltas)
@with_all_phases
@spec_state_test
def test_full_all_correct(spec, state):
yield from rewards_helpers.run_test_full_all_correct(spec, state, run_get_target_deltas)
@with_all_phases
@spec_state_test
def test_half_full(spec, state):
yield from rewards_helpers.run_test_half_full(spec, state, run_get_target_deltas)
@with_all_phases
@spec_state_test
def test_full_but_partial_participation(spec, state):
yield from rewards_helpers.run_test_full_but_partial_participation(spec, state, run_get_target_deltas)
@with_all_phases
@spec_state_test
def test_one_attestation_one_correct(spec, state):
yield from rewards_helpers.run_test_one_attestation_one_correct(spec, state, run_get_target_deltas)
@with_all_phases
@spec_state_test
def test_with_not_yet_activated_validators(spec, state):
yield from rewards_helpers.run_test_with_not_yet_activated_validators(spec, state, run_get_target_deltas)
@with_all_phases
@spec_state_test
def test_with_exited_validators(spec, state):
yield from rewards_helpers.run_test_with_exited_validators(spec, state, run_get_target_deltas)
@with_all_phases
@spec_state_test
def test_with_slashed_validators(spec, state):
yield from rewards_helpers.run_test_with_slashed_validators(spec, state, run_get_target_deltas)
@with_all_phases
@spec_state_test
def test_some_very_low_effective_balances_that_attested(spec, state):
yield from rewards_helpers.run_test_some_very_low_effective_balances_that_attested(
spec,
state,
run_get_target_deltas
)
@with_all_phases
@spec_state_test
def test_some_very_low_effective_balances_that_did_not_attest(spec, state):
yield from rewards_helpers.run_test_some_very_low_effective_balances_that_did_not_attest(
spec,
state,
run_get_target_deltas,
)
@with_all_phases
@spec_state_test
def test_full_half_correct_target_incorrect_head(spec, state):
yield from rewards_helpers.run_test_full_fraction_incorrect(
spec, state,
correct_target=True,
correct_head=False,
fraction_incorrect=0.5,
runner=run_get_target_deltas
)
@with_all_phases
@spec_state_test
def test_full_correct_target_incorrect_head(spec, state):
yield from rewards_helpers.run_test_full_fraction_incorrect(
spec, state,
correct_target=True,
correct_head=False,
fraction_incorrect=1.0,
runner=run_get_target_deltas
)
@with_all_phases
@spec_state_test
def test_full_half_incorrect_target_incorrect_head(spec, state):
yield from rewards_helpers.run_test_full_fraction_incorrect(
spec, state,
correct_target=False,
correct_head=False,
fraction_incorrect=0.5,
runner=run_get_target_deltas
)
@with_all_phases
@spec_state_test
def test_full_half_incorrect_target_correct_head(spec, state):
yield from rewards_helpers.run_test_full_fraction_incorrect(
spec, state,
correct_target=False,
correct_head=True,
fraction_incorrect=0.5,
runner=run_get_target_deltas
)
@with_all_phases
@spec_state_test
def test_full_random(spec, state):
yield from rewards_helpers.run_test_full_random(spec, state, run_get_target_deltas)

View File

@ -0,0 +1,165 @@
from eth2spec.test.context import with_all_phases, spec_state_test
from eth2spec.test.helpers.state import next_epoch
import eth2spec.test.helpers.rewards as rewards_helpers
def transition_state_to_leak(spec, state, epochs=None):
if epochs is None:
epochs = spec.MIN_EPOCHS_TO_INACTIVITY_PENALTY
assert epochs >= spec.MIN_EPOCHS_TO_INACTIVITY_PENALTY
for _ in range(epochs):
next_epoch(spec, state)
@with_all_phases
@spec_state_test
def test_empty_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_empty(spec, state)
@with_all_phases
@spec_state_test
def test_full_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_full_all_correct(spec, state)
@with_all_phases
@spec_state_test
def test_half_full_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_half_full(spec, state)
@with_all_phases
@spec_state_test
def test_quarter_full_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_partial(spec, state, 0.25)
@with_all_phases
@spec_state_test
def test_full_but_partial_participation_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_full_but_partial_participation(spec, state)
@with_all_phases
@spec_state_test
def test_one_attestation_one_correct_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_one_attestation_one_correct(spec, state)
@with_all_phases
@spec_state_test
def test_with_not_yet_activated_validators_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_with_not_yet_activated_validators(spec, state)
@with_all_phases
@spec_state_test
def test_with_exited_validators_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_with_exited_validators(spec, state)
@with_all_phases
@spec_state_test
def test_with_slashed_validators_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_with_slashed_validators(spec, state)
@with_all_phases
@spec_state_test
def test_some_very_low_effective_balances_that_attested_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_some_very_low_effective_balances_that_attested(spec, state)
@with_all_phases
@spec_state_test
def test_some_very_low_effective_balances_that_did_not_attest_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_some_very_low_effective_balances_that_did_not_attest(spec, state)
#
# NOTE: No source incorrect tests
# All PendingAttestations in state have source validated
# We choose to keep this invariant in these tests to not force clients to test with degenerate states
#
@with_all_phases
@spec_state_test
def test_full_half_correct_target_incorrect_head_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_full_fraction_incorrect(
spec, state,
correct_target=True,
correct_head=False,
fraction_incorrect=0.5,
)
@with_all_phases
@spec_state_test
def test_full_correct_target_incorrect_head_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_full_fraction_incorrect(
spec, state,
correct_target=True,
correct_head=False,
fraction_incorrect=1.0,
)
@with_all_phases
@spec_state_test
def test_full_half_incorrect_target_incorrect_head_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_full_fraction_incorrect(
spec, state,
correct_target=False,
correct_head=False,
fraction_incorrect=0.5,
)
@with_all_phases
@spec_state_test
def test_full_half_incorrect_target_correct_head_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_full_fraction_incorrect(
spec, state,
correct_target=False,
correct_head=True,
fraction_incorrect=0.5,
)
@with_all_phases
@spec_state_test
def test_full_random_leak(spec, state):
transition_state_to_leak(spec, state)
yield from rewards_helpers.run_test_full_random(spec, state)
@with_all_phases
@spec_state_test
def test_full_random_five_epoch_leak(spec, state):
transition_state_to_leak(spec, state, epochs=5)
yield from rewards_helpers.run_test_full_random(spec, state)
@with_all_phases
@spec_state_test
def test_full_random_ten_epoch_leak(spec, state):
transition_state_to_leak(spec, state, epochs=10)
yield from rewards_helpers.run_test_full_random(spec, state)

View File

@ -0,0 +1,22 @@
from random import Random
from eth2spec.test.context import with_all_phases, spec_state_test
import eth2spec.test.helpers.rewards as rewards_helpers
@with_all_phases
@spec_state_test
def test_full_random_0(spec, state):
yield from rewards_helpers.run_test_full_random(spec, state, rng=Random(1010))
@with_all_phases
@spec_state_test
def test_full_random_1(spec, state):
yield from rewards_helpers.run_test_full_random(spec, state, rng=Random(2020))
@with_all_phases
@spec_state_test
def test_full_random_2(spec, state):
yield from rewards_helpers.run_test_full_random(spec, state, rng=Random(3030))

View File

@ -1,8 +1,15 @@
# Rewards tests # Rewards tests
The different rewards deltas sub-functions are testing individually with the test handlers, each returning the related `rewards`/`penalties`. All rewards deltas sub-functions are tested for each test case.
There is no "change" factor, the rewards/penalties outputs are pure functions with just the pre-state as input. There is no "change" factor, the rewards/penalties outputs are pure functions with just the pre-state as input.
Hence, the format is shared between each test-handler. (See test condition documentation on how to run the tests.) (See test condition documentation on how to run the tests.)
`Deltas` is defined as:
```python
class Deltas(Container):
rewards: List[uint64, VALIDATOR_REGISTRY_LIMIT]
penalties: List[uint64, VALIDATOR_REGISTRY_LIMIT]
```
## Test case format ## Test case format
@ -22,31 +29,47 @@ A YAML-encoded `BeaconState`, the state before running the rewards sub-function.
Also available as `pre.ssz`. Also available as `pre.ssz`.
### `deltas.yaml` ### `source_deltas.yaml`
A YAML-encoded `Deltas` representing the rewards and penalties returned by the rewards sub-function A YAML-encoded `Deltas` representing the rewards and penalties returned by the rewards the `get_source_deltas` function
Where `Deltas` is defined as: Also available as `source_deltas.ssz`.
```python
class Deltas(Container):
rewards: List[uint64, VALIDATOR_REGISTRY_LIMIT]
penalties: List[uint64, VALIDATOR_REGISTRY_LIMIT]
```
Also available as `deltas.ssz`. ### `target_deltas.yaml`
A YAML-encoded `Deltas` representing the rewards and penalties returned by the rewards the `get_target_deltas` function
Also available as `target_deltas.ssz`.
### `head_deltas.yaml`
A YAML-encoded `Deltas` representing the rewards and penalties returned by the rewards the `get_head_deltas` function
Also available as `head_deltas.ssz`.
### `inclusion_delay_deltas.yaml`
A YAML-encoded `Deltas` representing the rewards and penalties returned by the rewards the `get_inclusion_delay_deltas` function
Also available as `inclusion_delay_deltas.ssz`.
### `inactivity_penalty_deltas.yaml`
A YAML-encoded `Deltas` representing the rewards and penalties returned by the rewards the `get_inactivity_penalty_deltas` function
Also available as `inactivity_penalty_deltas.ssz`.
## Condition ## Condition
A handler of the `rewards` test-runner should process these cases, A handler of the `rewards` test-runner should process these cases,
calling the corresponding rewards deltas function (same name in spec). calling the corresponding rewards deltas function for each set of deltas.
This excludes all other parts of `process_rewards_and_penalties`
The provided pre-state is ready to be input into the designated handler. The provided pre-state is ready to be input into each rewards deltas function.
The provided `deltas` should match the return values of the The provided `deltas` should match the return values of the
handler. Specifically the following must hold true: deltas function. Specifically the following must hold true for each set of deltas:
```python ```python
deltas.rewards == handler(state)[0] deltas.rewards == deltas_function(state)[0]
deltas.penalties == handler(state)[1] deltas.penalties == deltas_function(state)[1]
``` ```

View File

@ -3,11 +3,9 @@ from typing import Iterable
from eth2spec.phase0 import spec as spec_phase0 from eth2spec.phase0 import spec as spec_phase0
from eth2spec.phase1 import spec as spec_phase1 from eth2spec.phase1 import spec as spec_phase1
from eth2spec.test.phase_0.rewards import ( from eth2spec.test.phase_0.rewards import (
test_get_source_deltas, test_basic,
test_get_target_deltas, test_leak,
test_get_head_deltas, test_random,
test_get_inclusion_delay_deltas,
test_get_inactivity_penalty_deltas,
) )
from gen_base import gen_runner, gen_typing from gen_base import gen_runner, gen_typing
from gen_from_tests.gen import generate_from_tests from gen_from_tests.gen import generate_from_tests
@ -37,14 +35,10 @@ def create_provider(handler_name: str, tests_src, config_name: str) -> gen_typin
if __name__ == "__main__": if __name__ == "__main__":
gen_runner.run_generator("epoch_processing", [ gen_runner.run_generator("epoch_processing", [
create_provider('get_source_deltas', test_get_source_deltas, 'minimal'), create_provider('get_deltas', test_basic, 'minimal'),
create_provider('get_source_deltas', test_get_source_deltas, 'mainnet'), create_provider('get_deltas', test_basic, 'mainnet'),
create_provider('get_target_deltas', test_get_target_deltas, 'minimal'), create_provider('get_deltas', test_leak, 'minimal'),
create_provider('get_target_deltas', test_get_target_deltas, 'mainnet'), create_provider('get_deltas', test_leak, 'mainnet'),
create_provider('get_head_deltas', test_get_head_deltas, 'minimal'), create_provider('get_deltas', test_random, 'minimal'),
create_provider('get_head_deltas', test_get_head_deltas, 'mainnet'), create_provider('get_deltas', test_random, 'mainnet'),
create_provider('get_inclusion_delay_deltas', test_get_inclusion_delay_deltas, 'minimal'),
create_provider('get_inclusion_delay_deltas', test_get_inclusion_delay_deltas, 'mainnet'),
create_provider('get_inactivity_penalty_deltas', test_get_inactivity_penalty_deltas, 'minimal'),
create_provider('get_inactivity_penalty_deltas', test_get_inactivity_penalty_deltas, 'mainnet'),
]) ])