From f34eddb6e91bffb58e977c71c12f297bd96f6a57 Mon Sep 17 00:00:00 2001 From: tersec Date: Mon, 17 Aug 2020 01:09:27 +0000 Subject: [PATCH] fix get_unslashed_attesting_indices() and add official EF rewards tests for it (#1514) --- FixtureAll-mainnet.md | 50 ++++++++++++- beacon_chain/spec/state_transition_epoch.nim | 10 +-- .../spec/state_transition_helpers.nim | 4 +- tests/official/test_fixture_rewards.nim | 70 +++++++++++++++++++ .../test_fixture_state_transition_epoch.nim | 3 +- 5 files changed, 129 insertions(+), 8 deletions(-) create mode 100644 tests/official/test_fixture_rewards.nim diff --git a/FixtureAll-mainnet.md b/FixtureAll-mainnet.md index 6a2022dbf..94a9378c0 100644 --- a/FixtureAll-mainnet.md +++ b/FixtureAll-mainnet.md @@ -138,6 +138,54 @@ OK: 2/2 Fail: 0/2 Skip: 0/2 + [Valid] success_exit_queue OK ``` OK: 9/9 Fail: 0/9 Skip: 0/9 +## Official - Rewards [Preset: mainnet] +```diff ++ Rewards - all_balances_too_low_for_reward [Preset: mainnet] OK ++ Rewards - duplicate_attestations_at_later_slots [Preset: mainnet] OK ++ Rewards - empty [Preset: mainnet] OK ++ Rewards - empty_leak [Preset: mainnet] OK ++ Rewards - full_all_correct [Preset: mainnet] OK ++ Rewards - full_but_partial_participation [Preset: mainnet] OK ++ Rewards - full_but_partial_participation_leak [Preset: mainnet] OK ++ Rewards - full_correct_target_incorrect_head [Preset: mainnet] OK ++ Rewards - full_correct_target_incorrect_head_leak [Preset: mainnet] OK ++ Rewards - full_delay_max_slots [Preset: mainnet] OK ++ Rewards - full_delay_one_slot [Preset: mainnet] OK ++ Rewards - full_half_correct_target_incorrect_head [Preset: mainnet] OK ++ Rewards - full_half_correct_target_incorrect_head_leak [Preset: mainnet] OK ++ Rewards - full_half_incorrect_target_correct_head [Preset: mainnet] OK ++ Rewards - full_half_incorrect_target_correct_head_leak [Preset: mainnet] OK ++ Rewards - full_half_incorrect_target_incorrect_head [Preset: mainnet] OK ++ Rewards - full_half_incorrect_target_incorrect_head_leak [Preset: mainnet] OK ++ Rewards - full_leak [Preset: mainnet] OK ++ Rewards - full_mixed_delay [Preset: mainnet] OK ++ Rewards - full_random_0 [Preset: mainnet] OK ++ Rewards - full_random_1 [Preset: mainnet] OK ++ Rewards - full_random_2 [Preset: mainnet] OK ++ Rewards - full_random_five_epoch_leak [Preset: mainnet] OK ++ Rewards - full_random_leak [Preset: mainnet] OK ++ Rewards - full_random_low_balances [Preset: mainnet] OK ++ Rewards - full_random_misc_balances [Preset: mainnet] OK ++ Rewards - full_random_ten_epoch_leak [Preset: mainnet] OK ++ Rewards - half_full [Preset: mainnet] OK ++ Rewards - half_full_leak [Preset: mainnet] OK ++ Rewards - one_attestation_one_correct [Preset: mainnet] OK ++ Rewards - one_attestation_one_correct_leak [Preset: mainnet] OK ++ Rewards - proposer_not_in_attestations [Preset: mainnet] OK ++ Rewards - quarter_full [Preset: mainnet] OK ++ Rewards - quarter_full_leak [Preset: mainnet] OK ++ Rewards - some_very_low_effective_balances_that_attested [Preset: mainnet] OK ++ Rewards - some_very_low_effective_balances_that_attested_leak [Preset: mainnet] OK ++ Rewards - some_very_low_effective_balances_that_did_not_attest [Preset: mainnet] OK ++ Rewards - some_very_low_effective_balances_that_did_not_attest_leak [Preset: mainnet] OK ++ Rewards - with_exited_validators [Preset: mainnet] OK ++ Rewards - with_exited_validators_leak [Preset: mainnet] OK ++ Rewards - with_not_yet_activated_validators [Preset: mainnet] OK ++ Rewards - with_not_yet_activated_validators_leak [Preset: mainnet] OK ++ Rewards - with_slashed_validators [Preset: mainnet] OK ++ Rewards - with_slashed_validators_leak [Preset: mainnet] OK +``` +OK: 44/44 Fail: 0/44 Skip: 0/44 ## Official - Sanity - Blocks [Preset: mainnet] ```diff + [Invalid] double_same_proposer_slashings_same_block OK @@ -185,4 +233,4 @@ OK: 32/32 Fail: 0/32 Skip: 0/32 OK: 5/5 Fail: 0/5 Skip: 0/5 ---TOTAL--- -OK: 135/135 Fail: 0/135 Skip: 0/135 +OK: 179/179 Fail: 0/179 Skip: 0/179 diff --git a/beacon_chain/spec/state_transition_epoch.nim b/beacon_chain/spec/state_transition_epoch.nim index b9f6a8931..10d7f83dc 100644 --- a/beacon_chain/spec/state_transition_epoch.nim +++ b/beacon_chain/spec/state_transition_epoch.nim @@ -301,7 +301,7 @@ func get_attestation_component_deltas(state: BeaconState, # https://github.com/ethereum/eth2.0-specs/blob/v0.12.2/specs/phase0/beacon-chain.md#components-of-attestation-deltas # These is slightly refactored to calculate total_balance once. -func get_source_deltas( +func get_source_deltas*( state: BeaconState, total_balance: Gwei, cache: var StateCache): tuple[a: seq[Gwei], b: seq[Gwei]] = # Return attester micro-rewards/penalties for source-vote for each validator. @@ -310,7 +310,7 @@ func get_source_deltas( get_attestation_component_deltas( state, matching_source_attestations, total_balance, cache) -func get_target_deltas( +func get_target_deltas*( state: BeaconState, total_balance: Gwei, cache: var StateCache): tuple[a: seq[Gwei], b: seq[Gwei]] = # Return attester micro-rewards/penalties for target-vote for each validator. @@ -319,7 +319,7 @@ func get_target_deltas( get_attestation_component_deltas( state, matching_target_attestations, total_balance, cache) -func get_head_deltas( +func get_head_deltas*( state: BeaconState, total_balance: Gwei, cache: var StateCache): tuple[a: seq[Gwei], b: seq[Gwei]] = # Return attester micro-rewards/penalties for head-vote for each validator. @@ -328,7 +328,7 @@ func get_head_deltas( get_attestation_component_deltas( state, matching_head_attestations, total_balance, cache) -func get_inclusion_delay_deltas( +func get_inclusion_delay_deltas*( state: BeaconState, total_balance: Gwei, cache: var StateCache): seq[Gwei] = # Return proposer and inclusion delay micro-rewards/penalties for each validator. @@ -372,7 +372,7 @@ func get_inclusion_delay_deltas( # Spec constructs both and returns both; this doesn't rewards -func get_inactivity_penalty_deltas( +func get_inactivity_penalty_deltas*( state: BeaconState, total_balance: Gwei, cache: var StateCache): seq[Gwei] = # Return inactivity reward/penalty deltas for each validator. diff --git a/beacon_chain/spec/state_transition_helpers.nim b/beacon_chain/spec/state_transition_helpers.nim index 41b1c90ae..bfcda8f8a 100644 --- a/beacon_chain/spec/state_transition_helpers.nim +++ b/beacon_chain/spec/state_transition_helpers.nim @@ -32,6 +32,8 @@ func get_unslashed_attesting_indices*( state: BeaconState, attestations: openArray[PendingAttestation], cache: var StateCache): HashSet[ValidatorIndex] = result = get_attesting_indices(state, attestations, cache) + var slashedIndices = initHashSet[ValidatorIndex]() for index in result: if state.validators[index].slashed: - result.excl index + slashedIndices.incl index + result.excl slashedIndices diff --git a/tests/official/test_fixture_rewards.nim b/tests/official/test_fixture_rewards.nim new file mode 100644 index 000000000..733022199 --- /dev/null +++ b/tests/official/test_fixture_rewards.nim @@ -0,0 +1,70 @@ +# beacon_chain +# Copyright (c) 2020-Present Status Research & Development GmbH +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +{.used.} + +import + # Standard library + os, unittest, + # Utilities + stew/results, + # Beacon chain internals + ../../beacon_chain/spec/[datatypes, state_transition_epoch], + ../../beacon_chain/ssz, + # Test utilities + ../testutil, + ./fixtures_utils + +const RewardsDir = SszTestsDir/const_preset/"phase0"/"rewards"/"core"/"pyspec_tests" + +# https://github.com/ethereum/eth2.0-specs/tree/v0.12.2/tests/formats/rewards#rewards-tests +type Deltas = object + rewards: List[uint64, Limit VALIDATOR_REGISTRY_LIMIT] + penalties: List[uint64, Limit VALIDATOR_REGISTRY_LIMIT] + +func compareDeltas( + deltas: Deltas, rewardsPenalties: tuple[a: seq[Gwei], b: seq[Gwei]]): + bool = + deltas.rewards.asSeq == rewardsPenalties[0] and + deltas.penalties.asSeq == rewardsPenalties[1] + +proc runTest(identifier: string) = + # We wrap the tests in a proc to avoid running out of globals + # in the future: Nim supports up to 3500 globals + # but unittest with the macro/templates put everything as globals + # https://github.com/nim-lang/Nim/issues/12084#issue-486866402 + let testDir = RewardsDir / identifier + + proc `testImpl _ rewards _ identifier`() = + timedTest "Rewards" & " - " & identifier & preset(): + var + state = newClone(parseTest(testDir/"pre.ssz", SSZ, BeaconState)) + cache = StateCache() + let + total_balance = get_total_active_balance(state[], cache) + sourceDeltas = parseTest(testDir/"source_deltas.ssz", SSZ, Deltas) + targetDeltas = parseTest(testDir/"target_deltas.ssz", SSZ, Deltas) + headDeltas = parseTest(testDir/"head_deltas.ssz", SSZ, Deltas) + inclusionDelayDeltas = + parseTest(testDir/"inclusion_delay_deltas.ssz", SSZ, Deltas) + inactivityPenaltyDeltas = + parseTest(testDir/"inactivity_penalty_deltas.ssz", SSZ, Deltas) + + check: + compareDeltas(sourceDeltas, get_source_deltas(state[], total_balance, cache)) + compareDeltas(targetDeltas, get_target_deltas(state[], total_balance, cache)) + compareDeltas(headDeltas, get_head_deltas(state[], total_balance, cache)) + inclusionDelayDeltas.rewards.asSeq == + get_inclusion_delay_deltas(state[], total_balance, cache) + inactivityPenaltyDeltas.penalties.asSeq == + get_inactivity_penalty_deltas(state[], total_balance, cache) + + `testImpl _ rewards _ identifier`() + +suiteReport "Official - Rewards " & preset(): + for kind, path in walkDir(RewardsDir, true): + runTest(path) diff --git a/tests/official/test_fixture_state_transition_epoch.nim b/tests/official/test_fixture_state_transition_epoch.nim index 4529894db..36067d834 100644 --- a/tests/official/test_fixture_state_transition_epoch.nim +++ b/tests/official/test_fixture_state_transition_epoch.nim @@ -15,6 +15,7 @@ import # Test utilities ../testutil, ./fixtures_utils, + ./test_fixture_rewards, ../helpers/debug_state from ../../beacon_chain/spec/beaconstate import process_registry_updates @@ -60,7 +61,7 @@ runSuite(JustificationFinalizationDir, "Justification & Finalization", process_ # Rewards & Penalties # --------------------------------------------------------------- -# No test upstream +# in test_fixture_rewards # Registry updates # ---------------------------------------------------------------