From 97b0070774aa37ab0fa38745909016a3c0e4aaf5 Mon Sep 17 00:00:00 2001 From: tersec Date: Sat, 11 Sep 2021 08:01:05 +0000 Subject: [PATCH] add merge SSZ consensus object tests (#2858) * add merge SSZ consensus object tests * add merge attestations, attester slashing, proposer slashing, and voluntary exit test fixtures * throw catchable exception rather than assert on invalid SingleMemberUnion selector * hash_tree_root can assert, because it's trusted data by that point * re-assert on writing, since also trusted data * beta.4 update * implement upgrade_to_merge() --- FixtureAll-mainnet.md | 44 ++- FixtureAll-minimal.md | 44 ++- FixtureSSZConsensus-mainnet.md | 248 ++++++++++++++- FixtureSSZConsensus-minimal.md | 248 ++++++++++++++- beacon_chain/eth1/eth1_monitor.nim | 6 +- beacon_chain/spec/beaconstate.nim | 69 ++++- beacon_chain/spec/datatypes/altair.nim | 3 +- beacon_chain/spec/datatypes/merge.nim | 287 ++++++++++++++++-- beacon_chain/spec/eth2_ssz_serialization.nim | 8 +- beacon_chain/spec/helpers.nim | 2 +- beacon_chain/spec/state_transition_block.nim | 2 +- beacon_chain/spec/validator.nim | 2 +- beacon_chain/ssz/codec.nim | 6 + beacon_chain/ssz/merkleization.nim | 4 + beacon_chain/ssz/ssz_serialization.nim | 7 + beacon_chain/ssz/types.nim | 4 + tests/official/all_fixtures_require_ssz.nim | 3 +- .../merge/all_merge_fixtures_require_ssz.nim | 19 ++ .../test_fixture_operations_attestations.nim | 71 +++++ ..._fixture_operations_attester_slashings.nim | 68 +++++ ..._fixture_operations_proposer_slashings.nim | 70 +++++ ...test_fixture_operations_voluntary_exit.nim | 69 +++++ .../test_fixture_ssz_consensus_objects.nim | 152 ++++++++++ 23 files changed, 1386 insertions(+), 50 deletions(-) create mode 100644 tests/official/merge/all_merge_fixtures_require_ssz.nim create mode 100644 tests/official/merge/test_fixture_operations_attestations.nim create mode 100644 tests/official/merge/test_fixture_operations_attester_slashings.nim create mode 100644 tests/official/merge/test_fixture_operations_proposer_slashings.nim create mode 100644 tests/official/merge/test_fixture_operations_voluntary_exit.nim create mode 100644 tests/official/merge/test_fixture_ssz_consensus_objects.nim diff --git a/FixtureAll-mainnet.md b/FixtureAll-mainnet.md index 813ff6b53..83b4ec148 100644 --- a/FixtureAll-mainnet.md +++ b/FixtureAll-mainnet.md @@ -464,6 +464,48 @@ OK: 1/1 Fail: 0/1 Skip: 0/1 + Testing VoluntaryExit OK ``` OK: 36/36 Fail: 0/36 Skip: 0/36 +## Ethereum Foundation - Merge - SSZ consensus objects [Preset: mainnet] +```diff ++ Testing AggregateAndProof OK ++ Testing Attestation OK ++ Testing AttestationData OK ++ Testing AttesterSlashing OK ++ Testing BeaconBlock OK ++ Testing BeaconBlockBody OK ++ Testing BeaconBlockHeader OK ++ Testing BeaconState OK ++ Testing Checkpoint OK ++ Testing ContributionAndProof OK ++ Testing Deposit OK ++ Testing DepositData OK ++ Testing DepositMessage OK ++ Testing Eth1Block OK ++ Testing Eth1Data OK ++ Testing ExecutionPayload OK ++ Testing ExecutionPayloadHeader OK ++ Testing Fork OK ++ Testing ForkData OK ++ Testing HistoricalBatch OK ++ Testing IndexedAttestation OK ++ Testing LightClientSnapshot OK ++ Testing LightClientUpdate OK ++ Testing PendingAttestation OK ++ Testing ProposerSlashing OK ++ Testing SignedAggregateAndProof OK ++ Testing SignedBeaconBlock OK ++ Testing SignedBeaconBlockHeader OK ++ Testing SignedContributionAndProof OK ++ Testing SignedVoluntaryExit OK ++ Testing SigningData OK ++ Testing SyncAggregate OK ++ Testing SyncAggregatorSelectionData OK ++ Testing SyncCommittee OK ++ Testing SyncCommitteeContribution OK ++ Testing SyncCommitteeMessage OK ++ Testing Validator OK ++ Testing VoluntaryExit OK +``` +OK: 38/38 Fail: 0/38 Skip: 0/38 ## Ethereum Foundation - Phase 0 - Epoch Processing - Effective balance updates [Preset: mainnet] ```diff + Effective balance updates - effective_balance_hysteresis [Preset: mainnet] OK @@ -565,4 +607,4 @@ OK: 1/1 Fail: 0/1 Skip: 0/1 OK: 27/27 Fail: 0/27 Skip: 0/27 ---TOTAL--- -OK: 475/475 Fail: 0/475 Skip: 0/475 +OK: 513/513 Fail: 0/513 Skip: 0/513 diff --git a/FixtureAll-minimal.md b/FixtureAll-minimal.md index 434cb65e1..6c7d7169f 100644 --- a/FixtureAll-minimal.md +++ b/FixtureAll-minimal.md @@ -470,6 +470,48 @@ OK: 5/5 Fail: 0/5 Skip: 0/5 + Testing VoluntaryExit OK ``` OK: 36/36 Fail: 0/36 Skip: 0/36 +## Ethereum Foundation - Merge - SSZ consensus objects [Preset: minimal] +```diff ++ Testing AggregateAndProof OK ++ Testing Attestation OK ++ Testing AttestationData OK ++ Testing AttesterSlashing OK ++ Testing BeaconBlock OK ++ Testing BeaconBlockBody OK ++ Testing BeaconBlockHeader OK ++ Testing BeaconState OK ++ Testing Checkpoint OK ++ Testing ContributionAndProof OK ++ Testing Deposit OK ++ Testing DepositData OK ++ Testing DepositMessage OK ++ Testing Eth1Block OK ++ Testing Eth1Data OK ++ Testing ExecutionPayload OK ++ Testing ExecutionPayloadHeader OK ++ Testing Fork OK ++ Testing ForkData OK ++ Testing HistoricalBatch OK ++ Testing IndexedAttestation OK ++ Testing LightClientSnapshot OK ++ Testing LightClientUpdate OK ++ Testing PendingAttestation OK ++ Testing ProposerSlashing OK ++ Testing SignedAggregateAndProof OK ++ Testing SignedBeaconBlock OK ++ Testing SignedBeaconBlockHeader OK ++ Testing SignedContributionAndProof OK ++ Testing SignedVoluntaryExit OK ++ Testing SigningData OK ++ Testing SyncAggregate OK ++ Testing SyncAggregatorSelectionData OK ++ Testing SyncCommittee OK ++ Testing SyncCommitteeContribution OK ++ Testing SyncCommitteeMessage OK ++ Testing Validator OK ++ Testing VoluntaryExit OK +``` +OK: 38/38 Fail: 0/38 Skip: 0/38 ## Ethereum Foundation - Phase 0 - Epoch Processing - Effective balance updates [Preset: minimal] ```diff + Effective balance updates - effective_balance_hysteresis [Preset: minimal] OK @@ -575,4 +617,4 @@ OK: 1/1 Fail: 0/1 Skip: 0/1 OK: 27/27 Fail: 0/27 Skip: 0/27 ---TOTAL--- -OK: 481/481 Fail: 0/481 Skip: 0/481 +OK: 519/519 Fail: 0/519 Skip: 0/519 diff --git a/FixtureSSZConsensus-mainnet.md b/FixtureSSZConsensus-mainnet.md index c940d7a73..52a9db80b 100644 --- a/FixtureSSZConsensus-mainnet.md +++ b/FixtureSSZConsensus-mainnet.md @@ -2,6 +2,14 @@ FixtureSSZConsensus-mainnet === ## ```diff ++ Ethereum Foundation - Altair - Transition - normal_transition [Preset: mainnet] OK ++ Ethereum Foundation - Altair - Transition - transition_missing_first_post_block [Preset: m OK ++ Ethereum Foundation - Altair - Transition - transition_missing_last_pre_fork_block [Preset OK ++ Ethereum Foundation - Altair - Transition - transition_only_blocks_post_fork [Preset: main OK ++ Ethereum Foundation - Altair - Transition - transition_with_finality [Preset: mainnet] OK ++ Ethereum Foundation - Altair - Transition - transition_with_no_attestations_until_after_fo OK ++ Ethereum Foundation - Altair - Transition - transition_with_random_half_participation [Pre OK ++ Ethereum Foundation - Altair - Transition - transition_with_random_three_quarters_particip OK + Rewards - all_balances_too_low_for_reward [Preset: mainnet] OK + Rewards - duplicate_attestations_at_later_slots [Preset: mainnet] OK + Rewards - empty [Preset: mainnet] OK @@ -58,6 +66,20 @@ FixtureSSZConsensus-mainnet + Slots - slots_2 OK + [Invalid] bad_merkle_proof OK + [Invalid] wrong_deposit_for_deposit_count OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - double_same_proposer_slashings_ OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - double_similar_proposer_slashin OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - double_validator_exit_same_bloc OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - duplicate_attester_slashing [Pr OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - expected_deposit_in_block [Pres OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - invalid_block_sig [Preset: main OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - invalid_proposer_index_sig_from OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - invalid_proposer_index_sig_from OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - invalid_state_root [Preset: mai OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - parent_from_same_slot [Preset: OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - prev_slot_block_transition [Pre OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - same_slot_block_transition [Pre OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - slash_and_exit_same_index [Pres OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - zero_block_sig [Preset: mainnet OK + [Invalid] Ethereum Foundation - Phase 0 - Sanity - Blocks - double_same_proposer_slashings OK + [Invalid] Ethereum Foundation - Phase 0 - Sanity - Blocks - double_similar_proposer_slashi OK + [Invalid] Ethereum Foundation - Phase 0 - Sanity - Blocks - double_validator_exit_same_blo OK @@ -111,6 +133,13 @@ FixtureSSZConsensus-mainnet + [Invalid] invalid_sig_1_and_2_swap OK + [Invalid] invalid_sig_2 OK + [Invalid] invalid_signature OK ++ [Invalid] invalid_signature_bad_domain OK ++ [Invalid] invalid_signature_extra_participant OK ++ [Invalid] invalid_signature_infinite_signature_with_all_participants OK ++ [Invalid] invalid_signature_infinite_signature_with_single_participant OK ++ [Invalid] invalid_signature_missing_participant OK ++ [Invalid] invalid_signature_no_participants OK ++ [Invalid] invalid_signature_past_block OK + [Invalid] invalid_slot_block_header OK + [Invalid] mismatched_target_and_slot OK + [Invalid] new_source_epoch OK @@ -147,6 +176,50 @@ FixtureSSZConsensus-mainnet + [Valid] new_deposit_under_max OK + [Valid] success_top_up OK + [Valid] valid_sig_but_forked_state OK ++ [Valid] Ethereum Foundation - Altair - Finality - finality_no_updates_at_genesis [Preset OK ++ [Valid] Ethereum Foundation - Altair - Finality - finality_rule_1 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Finality - finality_rule_2 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Finality - finality_rule_3 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Finality - finality_rule_4 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_0 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_1 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_10 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_11 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_12 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_13 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_14 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_15 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_2 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_3 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_4 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_5 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_6 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_7 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_8 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_9 [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - attestation [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - attester_slashing [Preset: main OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - balance_driven_status_transitio OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - deposit_in_block [Preset: mainn OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - deposit_top_up [Preset: mainnet OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - empty_block_transition [Preset: OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - empty_epoch_transition [Preset: OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - full_random_operations_0 [Prese OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - full_random_operations_1 [Prese OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - full_random_operations_2 [Prese OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - full_random_operations_3 [Prese OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - high_proposer_index [Preset: ma OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - historical_batch [Preset: mainn OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - multiple_attester_slashings_no_ OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - multiple_attester_slashings_par OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - multiple_different_proposer_sla OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - multiple_different_validator_ex OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - proposer_after_inactive_index [ OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - proposer_self_slashing [Preset: OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - proposer_slashing [Preset: main OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - skipped_slots [Preset: mainnet] OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - slash_and_exit_diff_index [Pres OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - voluntary_exit [Preset: mainnet OK + [Valid] Ethereum Foundation - Phase 0 - Finality - finality_no_updates_at_genesis [Prese OK + [Valid] Ethereum Foundation - Phase 0 - Finality - finality_rule_1 [Preset: mainnet] OK + [Valid] Ethereum Foundation - Phase 0 - Finality - finality_rule_2 [Preset: mainnet] OK @@ -204,6 +277,12 @@ FixtureSSZConsensus-mainnet + [Valid] incorrect_target_epoch_delay OK + [Valid] incorrect_target_min_inclusion_delay OK + [Valid] incorrect_target_sqrt_epoch_delay OK ++ [Valid] random_all_but_one_participating_with_duplicates OK ++ [Valid] random_high_participation_with_duplicates OK ++ [Valid] random_low_participation_with_duplicates OK ++ [Valid] random_misc_balances_and_half_participation_with_duplicates OK ++ [Valid] random_only_one_participant_with_duplicates OK ++ [Valid] random_with_exits_with_duplicates OK + [Valid] success OK + [Valid] success_already_exited_long_ago OK + [Valid] success_already_exited_recent OK @@ -220,8 +299,131 @@ FixtureSSZConsensus-mainnet + [Valid] success_slashed_and_proposer_index_the_same OK + [Valid] success_surround OK + [Valid] success_with_effective_balance_disparity OK ++ [Valid] sync_committee_rewards_duplicate_committee_full_participation OK ++ [Valid] sync_committee_rewards_duplicate_committee_half_participation OK ++ [Valid] sync_committee_rewards_duplicate_committee_no_participation OK ++ [Valid] sync_committee_rewards_empty_participants OK ++ [Valid] sync_committee_rewards_not_full_participants OK ++ [Valid] sync_committee_with_nonparticipating_exited_member OK ++ [Valid] sync_committee_with_nonparticipating_withdrawable_member OK ++ [Valid] sync_committee_with_participating_exited_member OK ++ [Valid] sync_committee_with_participating_withdrawable_member OK ++ altair_fork_random_0 OK ++ altair_fork_random_1 OK ++ altair_fork_random_2 OK ++ altair_fork_random_3 OK ++ altair_fork_random_duplicate_attestations OK ++ altair_fork_random_low_balances OK ++ altair_fork_random_misc_balances OK ++ altair_fork_random_mismatched_attestations OK ++ fork_base_state OK ++ fork_many_next_epoch OK ++ fork_next_epoch OK ++ fork_next_epoch_with_block OK ++ fork_random_low_balances OK ++ fork_random_misc_balances OK ``` -OK: 218/218 Fail: 0/218 Skip: 0/218 +OK: 320/320 Fail: 0/320 Skip: 0/320 +## Ethereum Foundation - Altair - Epoch Processing - Effective balance updates [Preset: mainnet] +```diff ++ Effective balance updates - effective_balance_hysteresis [Preset: mainnet] OK +``` +OK: 1/1 Fail: 0/1 Skip: 0/1 +## Ethereum Foundation - Altair - Epoch Processing - Eth1 data reset [Preset: mainnet] +```diff ++ Eth1 data reset - eth1_vote_no_reset [Preset: mainnet] OK ++ Eth1 data reset - eth1_vote_reset [Preset: mainnet] OK +``` +OK: 2/2 Fail: 0/2 Skip: 0/2 +## Ethereum Foundation - Altair - Epoch Processing - Historical roots update [Preset: mainnet] +```diff ++ Historical roots update - historical_root_accumulator [Preset: mainnet] OK +``` +OK: 1/1 Fail: 0/1 Skip: 0/1 +## Ethereum Foundation - Altair - Epoch Processing - Inactivity [Preset: mainnet] +```diff ++ Inactivity - all_zero_inactivity_scores_empty_participation [Preset: mainnet] OK ++ Inactivity - all_zero_inactivity_scores_empty_participation_leaking [Preset: mainnet] OK ++ Inactivity - all_zero_inactivity_scores_full_participation [Preset: mainnet] OK ++ Inactivity - all_zero_inactivity_scores_full_participation_leaking [Preset: mainnet] OK ++ Inactivity - all_zero_inactivity_scores_random_participation [Preset: mainnet] OK ++ Inactivity - all_zero_inactivity_scores_random_participation_leaking [Preset: mainnet] OK ++ Inactivity - genesis [Preset: mainnet] OK ++ Inactivity - genesis_random_scores [Preset: mainnet] OK ++ Inactivity - random_inactivity_scores_empty_participation [Preset: mainnet] OK ++ Inactivity - random_inactivity_scores_empty_participation_leaking [Preset: mainnet] OK ++ Inactivity - random_inactivity_scores_full_participation [Preset: mainnet] OK ++ Inactivity - random_inactivity_scores_full_participation_leaking [Preset: mainnet] OK ++ Inactivity - random_inactivity_scores_random_participation [Preset: mainnet] OK ++ Inactivity - random_inactivity_scores_random_participation_leaking [Preset: mainnet] OK ++ Inactivity - some_exited_full_random_leaking [Preset: mainnet] OK ++ Inactivity - some_slashed_full_random [Preset: mainnet] OK ++ Inactivity - some_slashed_full_random_leaking [Preset: mainnet] OK ++ Inactivity - some_slashed_zero_scores_full_participation [Preset: mainnet] OK ++ Inactivity - some_slashed_zero_scores_full_participation_leaking [Preset: mainnet] OK +``` +OK: 19/19 Fail: 0/19 Skip: 0/19 +## Ethereum Foundation - Altair - Epoch Processing - Justification & Finalization [Preset: mainnet] +```diff ++ Justification & Finalization - 123_ok_support [Preset: mainnet] OK ++ Justification & Finalization - 123_poor_support [Preset: mainnet] OK ++ Justification & Finalization - 12_ok_support [Preset: mainnet] OK ++ Justification & Finalization - 12_ok_support_messed_target [Preset: mainnet] OK ++ Justification & Finalization - 12_poor_support [Preset: mainnet] OK ++ Justification & Finalization - 234_ok_support [Preset: mainnet] OK ++ Justification & Finalization - 234_poor_support [Preset: mainnet] OK ++ Justification & Finalization - 23_ok_support [Preset: mainnet] OK ++ Justification & Finalization - 23_poor_support [Preset: mainnet] OK ++ Justification & Finalization - balance_threshold_with_exited_validators [Preset: mainnet] OK +``` +OK: 10/10 Fail: 0/10 Skip: 0/10 +## Ethereum Foundation - Altair - Epoch Processing - Participation flag updates [Preset: mainnet] +```diff ++ Participation flag updates - all_zeroed [Preset: mainnet] OK ++ Participation flag updates - current_epoch_zeroed [Preset: mainnet] OK ++ Participation flag updates - current_filled [Preset: mainnet] OK ++ Participation flag updates - filled [Preset: mainnet] OK ++ Participation flag updates - previous_epoch_zeroed [Preset: mainnet] OK ++ Participation flag updates - previous_filled [Preset: mainnet] OK ++ Participation flag updates - random_0 [Preset: mainnet] OK ++ Participation flag updates - random_1 [Preset: mainnet] OK ++ Participation flag updates - random_2 [Preset: mainnet] OK ++ Participation flag updates - random_genesis [Preset: mainnet] OK +``` +OK: 10/10 Fail: 0/10 Skip: 0/10 +## Ethereum Foundation - Altair - Epoch Processing - RANDAO mixes reset [Preset: mainnet] +```diff ++ RANDAO mixes reset - updated_randao_mixes [Preset: mainnet] OK +``` +OK: 1/1 Fail: 0/1 Skip: 0/1 +## Ethereum Foundation - Altair - Epoch Processing - Registry updates [Preset: mainnet] +```diff ++ Registry updates - activation_queue_activation_and_ejection__1 [Preset: mainnet] OK ++ Registry updates - activation_queue_activation_and_ejection__churn_limit [Preset: mainnet] OK ++ Registry updates - activation_queue_activation_and_ejection__exceed_churn_limit [Preset: m OK ++ Registry updates - activation_queue_efficiency_min [Preset: mainnet] OK ++ Registry updates - activation_queue_no_activation_no_finality [Preset: mainnet] OK ++ Registry updates - activation_queue_sorting [Preset: mainnet] OK ++ Registry updates - activation_queue_to_activated_if_finalized [Preset: mainnet] OK ++ Registry updates - add_to_activation_queue [Preset: mainnet] OK ++ Registry updates - ejection [Preset: mainnet] OK ++ Registry updates - ejection_past_churn_limit_min [Preset: mainnet] OK +``` +OK: 10/10 Fail: 0/10 Skip: 0/10 +## Ethereum Foundation - Altair - Epoch Processing - Slashings [Preset: mainnet] +```diff ++ Slashings - low_penalty [Preset: mainnet] OK ++ Slashings - max_penalties [Preset: mainnet] OK ++ Slashings - minimal_penalty [Preset: mainnet] OK ++ Slashings - scaled_penalties [Preset: mainnet] OK ++ Slashings - slashings_with_random_state [Preset: mainnet] OK +``` +OK: 5/5 Fail: 0/5 Skip: 0/5 +## Ethereum Foundation - Altair - Epoch Processing - Slashings reset [Preset: mainnet] +```diff ++ Slashings reset - flush_slashings [Preset: mainnet] OK +``` +OK: 1/1 Fail: 0/1 Skip: 0/1 ## Ethereum Foundation - Altair - SSZ consensus objects [Preset: mainnet] ```diff + Testing AggregateAndProof OK @@ -262,6 +464,48 @@ OK: 218/218 Fail: 0/218 Skip: 0/218 + Testing VoluntaryExit OK ``` OK: 36/36 Fail: 0/36 Skip: 0/36 +## Ethereum Foundation - Merge - SSZ consensus objects [Preset: mainnet] +```diff ++ Testing AggregateAndProof OK ++ Testing Attestation OK ++ Testing AttestationData OK ++ Testing AttesterSlashing OK ++ Testing BeaconBlock OK ++ Testing BeaconBlockBody OK ++ Testing BeaconBlockHeader OK ++ Testing BeaconState OK ++ Testing Checkpoint OK ++ Testing ContributionAndProof OK ++ Testing Deposit OK ++ Testing DepositData OK ++ Testing DepositMessage OK ++ Testing Eth1Block OK ++ Testing Eth1Data OK ++ Testing ExecutionPayload OK ++ Testing ExecutionPayloadHeader OK ++ Testing Fork OK ++ Testing ForkData OK ++ Testing HistoricalBatch OK ++ Testing IndexedAttestation OK ++ Testing LightClientSnapshot OK ++ Testing LightClientUpdate OK ++ Testing PendingAttestation OK ++ Testing ProposerSlashing OK ++ Testing SignedAggregateAndProof OK ++ Testing SignedBeaconBlock OK ++ Testing SignedBeaconBlockHeader OK ++ Testing SignedContributionAndProof OK ++ Testing SignedVoluntaryExit OK ++ Testing SigningData OK ++ Testing SyncAggregate OK ++ Testing SyncAggregatorSelectionData OK ++ Testing SyncCommittee OK ++ Testing SyncCommitteeContribution OK ++ Testing SyncCommitteeMessage OK ++ Testing Validator OK ++ Testing VoluntaryExit OK +``` +OK: 38/38 Fail: 0/38 Skip: 0/38 ## Ethereum Foundation - Phase 0 - Epoch Processing - Effective balance updates [Preset: mainnet] ```diff + Effective balance updates - effective_balance_hysteresis [Preset: mainnet] OK @@ -363,4 +607,4 @@ OK: 1/1 Fail: 0/1 Skip: 0/1 OK: 27/27 Fail: 0/27 Skip: 0/27 ---TOTAL--- -OK: 313/313 Fail: 0/313 Skip: 0/313 +OK: 513/513 Fail: 0/513 Skip: 0/513 diff --git a/FixtureSSZConsensus-minimal.md b/FixtureSSZConsensus-minimal.md index f81a22a04..4d6a1e6e7 100644 --- a/FixtureSSZConsensus-minimal.md +++ b/FixtureSSZConsensus-minimal.md @@ -58,6 +58,20 @@ FixtureSSZConsensus-minimal + Slots - slots_2 OK + [Invalid] bad_merkle_proof OK + [Invalid] wrong_deposit_for_deposit_count OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - double_same_proposer_slashings_ OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - double_similar_proposer_slashin OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - double_validator_exit_same_bloc OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - duplicate_attester_slashing [Pr OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - expected_deposit_in_block [Pres OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - invalid_block_sig [Preset: mini OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - invalid_proposer_index_sig_from OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - invalid_proposer_index_sig_from OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - invalid_state_root [Preset: min OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - parent_from_same_slot [Preset: OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - prev_slot_block_transition [Pre OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - same_slot_block_transition [Pre OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - slash_and_exit_same_index [Pres OK ++ [Invalid] Ethereum Foundation - Altair - Sanity - Blocks - zero_block_sig [Preset: minimal OK + [Invalid] Ethereum Foundation - Phase 0 - Sanity - Blocks - double_same_proposer_slashings OK + [Invalid] Ethereum Foundation - Phase 0 - Sanity - Blocks - double_similar_proposer_slashi OK + [Invalid] Ethereum Foundation - Phase 0 - Sanity - Blocks - double_validator_exit_same_blo OK @@ -111,6 +125,14 @@ FixtureSSZConsensus-minimal + [Invalid] invalid_sig_1_and_2_swap OK + [Invalid] invalid_sig_2 OK + [Invalid] invalid_signature OK ++ [Invalid] invalid_signature_bad_domain OK ++ [Invalid] invalid_signature_extra_participant OK ++ [Invalid] invalid_signature_infinite_signature_with_all_participants OK ++ [Invalid] invalid_signature_infinite_signature_with_single_participant OK ++ [Invalid] invalid_signature_missing_participant OK ++ [Invalid] invalid_signature_no_participants OK ++ [Invalid] invalid_signature_past_block OK ++ [Invalid] invalid_signature_previous_committee OK + [Invalid] invalid_slot_block_header OK + [Invalid] mismatched_target_and_slot OK + [Invalid] new_source_epoch OK @@ -147,6 +169,55 @@ FixtureSSZConsensus-minimal + [Valid] new_deposit_under_max OK + [Valid] success_top_up OK + [Valid] valid_sig_but_forked_state OK ++ [Valid] Ethereum Foundation - Altair - Finality - finality_no_updates_at_genesis [Preset OK ++ [Valid] Ethereum Foundation - Altair - Finality - finality_rule_1 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Finality - finality_rule_2 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Finality - finality_rule_3 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Finality - finality_rule_4 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_0 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_1 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_10 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_11 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_12 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_13 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_14 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_15 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_2 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_3 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_4 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_5 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_6 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_7 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_8 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Random - randomized_9 [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - attestation [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - attester_slashing [Preset: mini OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - balance_driven_status_transitio OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - deposit_in_block [Preset: minim OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - deposit_top_up [Preset: minimal OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - empty_block_transition [Preset: OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - empty_block_transition_large_va OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - empty_epoch_transition [Preset: OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - empty_epoch_transition_large_va OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - empty_epoch_transition_not_fina OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - eth1_data_votes_consensus [Pres OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - eth1_data_votes_no_consensus [P OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - full_random_operations_0 [Prese OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - full_random_operations_1 [Prese OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - full_random_operations_2 [Prese OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - full_random_operations_3 [Prese OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - high_proposer_index [Preset: mi OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - historical_batch [Preset: minim OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - multiple_attester_slashings_no_ OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - multiple_attester_slashings_par OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - multiple_different_proposer_sla OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - multiple_different_validator_ex OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - proposer_after_inactive_index [ OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - proposer_self_slashing [Preset: OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - proposer_slashing [Preset: mini OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - skipped_slots [Preset: minimal] OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - slash_and_exit_diff_index [Pres OK ++ [Valid] Ethereum Foundation - Altair - Sanity - Blocks - voluntary_exit [Preset: minimal OK + [Valid] Ethereum Foundation - Phase 0 - Finality - finality_no_updates_at_genesis [Prese OK + [Valid] Ethereum Foundation - Phase 0 - Finality - finality_rule_1 [Preset: minimal] OK + [Valid] Ethereum Foundation - Phase 0 - Finality - finality_rule_2 [Preset: minimal] OK @@ -209,6 +280,14 @@ FixtureSSZConsensus-minimal + [Valid] incorrect_target_epoch_delay OK + [Valid] incorrect_target_min_inclusion_delay OK + [Valid] incorrect_target_sqrt_epoch_delay OK ++ [Valid] proposer_in_committee_with_participation OK ++ [Valid] proposer_in_committee_without_participation OK ++ [Valid] random_all_but_one_participating_without_duplicates OK ++ [Valid] random_high_participation_without_duplicates OK ++ [Valid] random_low_participation_without_duplicates OK ++ [Valid] random_misc_balances_and_half_participation_without_duplicates OK ++ [Valid] random_only_one_participant_without_duplicates OK ++ [Valid] random_with_exits_without_duplicates OK + [Valid] success OK + [Valid] success_already_exited_long_ago OK + [Valid] success_already_exited_recent OK @@ -226,8 +305,131 @@ FixtureSSZConsensus-minimal + [Valid] success_slashed_and_proposer_index_the_same OK + [Valid] success_surround OK + [Valid] success_with_effective_balance_disparity OK ++ [Valid] sync_committee_rewards_empty_participants OK ++ [Valid] sync_committee_rewards_nonduplicate_committee OK ++ [Valid] sync_committee_rewards_not_full_participants OK ++ [Valid] sync_committee_with_nonparticipating_exited_member OK ++ [Valid] sync_committee_with_nonparticipating_withdrawable_member OK ++ [Valid] sync_committee_with_participating_exited_member OK ++ [Valid] sync_committee_with_participating_withdrawable_member OK ++ [Valid] valid_signature_future_committee OK ``` -OK: 224/224 Fail: 0/224 Skip: 0/224 +OK: 311/311 Fail: 0/311 Skip: 0/311 +## Ethereum Foundation - Altair - Epoch Processing - Effective balance updates [Preset: minimal] +```diff ++ Effective balance updates - effective_balance_hysteresis [Preset: minimal] OK +``` +OK: 1/1 Fail: 0/1 Skip: 0/1 +## Ethereum Foundation - Altair - Epoch Processing - Eth1 data reset [Preset: minimal] +```diff ++ Eth1 data reset - eth1_vote_no_reset [Preset: minimal] OK ++ Eth1 data reset - eth1_vote_reset [Preset: minimal] OK +``` +OK: 2/2 Fail: 0/2 Skip: 0/2 +## Ethereum Foundation - Altair - Epoch Processing - Historical roots update [Preset: minimal] +```diff ++ Historical roots update - historical_root_accumulator [Preset: minimal] OK +``` +OK: 1/1 Fail: 0/1 Skip: 0/1 +## Ethereum Foundation - Altair - Epoch Processing - Inactivity [Preset: minimal] +```diff ++ Inactivity - all_zero_inactivity_scores_empty_participation [Preset: minimal] OK ++ Inactivity - all_zero_inactivity_scores_empty_participation_leaking [Preset: minimal] OK ++ Inactivity - all_zero_inactivity_scores_full_participation [Preset: minimal] OK ++ Inactivity - all_zero_inactivity_scores_full_participation_leaking [Preset: minimal] OK ++ Inactivity - all_zero_inactivity_scores_random_participation [Preset: minimal] OK ++ Inactivity - all_zero_inactivity_scores_random_participation_leaking [Preset: minimal] OK ++ Inactivity - genesis [Preset: minimal] OK ++ Inactivity - genesis_random_scores [Preset: minimal] OK ++ Inactivity - random_inactivity_scores_empty_participation [Preset: minimal] OK ++ Inactivity - random_inactivity_scores_empty_participation_leaking [Preset: minimal] OK ++ Inactivity - random_inactivity_scores_full_participation [Preset: minimal] OK ++ Inactivity - random_inactivity_scores_full_participation_leaking [Preset: minimal] OK ++ Inactivity - random_inactivity_scores_random_participation [Preset: minimal] OK ++ Inactivity - random_inactivity_scores_random_participation_leaking [Preset: minimal] OK ++ Inactivity - some_exited_full_random_leaking [Preset: minimal] OK ++ Inactivity - some_slashed_full_random [Preset: minimal] OK ++ Inactivity - some_slashed_full_random_leaking [Preset: minimal] OK ++ Inactivity - some_slashed_zero_scores_full_participation [Preset: minimal] OK ++ Inactivity - some_slashed_zero_scores_full_participation_leaking [Preset: minimal] OK +``` +OK: 19/19 Fail: 0/19 Skip: 0/19 +## Ethereum Foundation - Altair - Epoch Processing - Justification & Finalization [Preset: minimal] +```diff ++ Justification & Finalization - 123_ok_support [Preset: minimal] OK ++ Justification & Finalization - 123_poor_support [Preset: minimal] OK ++ Justification & Finalization - 12_ok_support [Preset: minimal] OK ++ Justification & Finalization - 12_ok_support_messed_target [Preset: minimal] OK ++ Justification & Finalization - 12_poor_support [Preset: minimal] OK ++ Justification & Finalization - 234_ok_support [Preset: minimal] OK ++ Justification & Finalization - 234_poor_support [Preset: minimal] OK ++ Justification & Finalization - 23_ok_support [Preset: minimal] OK ++ Justification & Finalization - 23_poor_support [Preset: minimal] OK ++ Justification & Finalization - balance_threshold_with_exited_validators [Preset: minimal] OK +``` +OK: 10/10 Fail: 0/10 Skip: 0/10 +## Ethereum Foundation - Altair - Epoch Processing - Participation flag updates [Preset: minimal] +```diff ++ Participation flag updates - all_zeroed [Preset: minimal] OK ++ Participation flag updates - current_epoch_zeroed [Preset: minimal] OK ++ Participation flag updates - current_filled [Preset: minimal] OK ++ Participation flag updates - filled [Preset: minimal] OK ++ Participation flag updates - large_random [Preset: minimal] OK ++ Participation flag updates - previous_epoch_zeroed [Preset: minimal] OK ++ Participation flag updates - previous_filled [Preset: minimal] OK ++ Participation flag updates - random_0 [Preset: minimal] OK ++ Participation flag updates - random_1 [Preset: minimal] OK ++ Participation flag updates - random_2 [Preset: minimal] OK ++ Participation flag updates - random_genesis [Preset: minimal] OK ++ Participation flag updates - slightly_larger_random [Preset: minimal] OK +``` +OK: 12/12 Fail: 0/12 Skip: 0/12 +## Ethereum Foundation - Altair - Epoch Processing - RANDAO mixes reset [Preset: minimal] +```diff ++ RANDAO mixes reset - updated_randao_mixes [Preset: minimal] OK +``` +OK: 1/1 Fail: 0/1 Skip: 0/1 +## Ethereum Foundation - Altair - Epoch Processing - Registry updates [Preset: minimal] +```diff ++ Registry updates - activation_queue_activation_and_ejection__1 [Preset: minimal] OK ++ Registry updates - activation_queue_activation_and_ejection__churn_limit [Preset: minimal] OK ++ Registry updates - activation_queue_activation_and_ejection__exceed_churn_limit [Preset: m OK ++ Registry updates - activation_queue_activation_and_ejection__exceed_scaled_churn_limit [Pr OK ++ Registry updates - activation_queue_activation_and_ejection__scaled_churn_limit [Preset: m OK ++ Registry updates - activation_queue_efficiency_min [Preset: minimal] OK ++ Registry updates - activation_queue_efficiency_scaled [Preset: minimal] OK ++ Registry updates - activation_queue_no_activation_no_finality [Preset: minimal] OK ++ Registry updates - activation_queue_sorting [Preset: minimal] OK ++ Registry updates - activation_queue_to_activated_if_finalized [Preset: minimal] OK ++ Registry updates - add_to_activation_queue [Preset: minimal] OK ++ Registry updates - ejection [Preset: minimal] OK ++ Registry updates - ejection_past_churn_limit_min [Preset: minimal] OK ++ Registry updates - ejection_past_churn_limit_scaled [Preset: minimal] OK +``` +OK: 14/14 Fail: 0/14 Skip: 0/14 +## Ethereum Foundation - Altair - Epoch Processing - Slashings [Preset: minimal] +```diff ++ Slashings - low_penalty [Preset: minimal] OK ++ Slashings - max_penalties [Preset: minimal] OK ++ Slashings - minimal_penalty [Preset: minimal] OK ++ Slashings - scaled_penalties [Preset: minimal] OK ++ Slashings - slashings_with_random_state [Preset: minimal] OK +``` +OK: 5/5 Fail: 0/5 Skip: 0/5 +## Ethereum Foundation - Altair - Epoch Processing - Slashings reset [Preset: minimal] +```diff ++ Slashings reset - flush_slashings [Preset: minimal] OK +``` +OK: 1/1 Fail: 0/1 Skip: 0/1 +## Ethereum Foundation - Altair - Epoch Processing - Sync committee updates [Preset: minimal] +```diff ++ Sync committee updates - sync_committees_no_progress_not_boundary [Preset: minimal] OK ++ Sync committee updates - sync_committees_progress_genesis [Preset: minimal] OK ++ Sync committee updates - sync_committees_progress_misc_balances_genesis [Preset: minimal] OK ++ Sync committee updates - sync_committees_progress_misc_balances_not_genesis [Preset: minim OK ++ Sync committee updates - sync_committees_progress_not_genesis [Preset: minimal] OK +``` +OK: 5/5 Fail: 0/5 Skip: 0/5 ## Ethereum Foundation - Altair - SSZ consensus objects [Preset: minimal] ```diff + Testing AggregateAndProof OK @@ -268,6 +470,48 @@ OK: 224/224 Fail: 0/224 Skip: 0/224 + Testing VoluntaryExit OK ``` OK: 36/36 Fail: 0/36 Skip: 0/36 +## Ethereum Foundation - Merge - SSZ consensus objects [Preset: minimal] +```diff ++ Testing AggregateAndProof OK ++ Testing Attestation OK ++ Testing AttestationData OK ++ Testing AttesterSlashing OK ++ Testing BeaconBlock OK ++ Testing BeaconBlockBody OK ++ Testing BeaconBlockHeader OK ++ Testing BeaconState OK ++ Testing Checkpoint OK ++ Testing ContributionAndProof OK ++ Testing Deposit OK ++ Testing DepositData OK ++ Testing DepositMessage OK ++ Testing Eth1Block OK ++ Testing Eth1Data OK ++ Testing ExecutionPayload OK ++ Testing ExecutionPayloadHeader OK ++ Testing Fork OK ++ Testing ForkData OK ++ Testing HistoricalBatch OK ++ Testing IndexedAttestation OK ++ Testing LightClientSnapshot OK ++ Testing LightClientUpdate OK ++ Testing PendingAttestation OK ++ Testing ProposerSlashing OK ++ Testing SignedAggregateAndProof OK ++ Testing SignedBeaconBlock OK ++ Testing SignedBeaconBlockHeader OK ++ Testing SignedContributionAndProof OK ++ Testing SignedVoluntaryExit OK ++ Testing SigningData OK ++ Testing SyncAggregate OK ++ Testing SyncAggregatorSelectionData OK ++ Testing SyncCommittee OK ++ Testing SyncCommitteeContribution OK ++ Testing SyncCommitteeMessage OK ++ Testing Validator OK ++ Testing VoluntaryExit OK +``` +OK: 38/38 Fail: 0/38 Skip: 0/38 ## Ethereum Foundation - Phase 0 - Epoch Processing - Effective balance updates [Preset: minimal] ```diff + Effective balance updates - effective_balance_hysteresis [Preset: minimal] OK @@ -373,4 +617,4 @@ OK: 1/1 Fail: 0/1 Skip: 0/1 OK: 27/27 Fail: 0/27 Skip: 0/27 ---TOTAL--- -OK: 323/323 Fail: 0/323 Skip: 0/323 +OK: 519/519 Fail: 0/519 Skip: 0/519 diff --git a/beacon_chain/eth1/eth1_monitor.nim b/beacon_chain/eth1/eth1_monitor.nim index 0ff92132a..624eb0654 100644 --- a/beacon_chain/eth1/eth1_monitor.nim +++ b/beacon_chain/eth1/eth1_monitor.nim @@ -425,15 +425,15 @@ proc newBlock*(p: Web3DataProviderRef, parentHash: executableData.parent_hash.data.encodeQuantityHex, miner: executableData.coinbase.data.encodeQuantityHex, stateRoot: executableData.state_root.data.encodeQuantityHex, - number: executableData.number.encodeQuantity, + number: executableData.block_number.encodeQuantity, gasLimit: executableData.gas_limit.encodeQuantity, gasUsed: executableData.gas_used.encodeQuantity, timestamp: executableData.timestamp.encodeQuantity, receiptsRoot: executableData.receipt_root.data.encodeQuantityHex, logsBloom: executableData.logs_bloom.data.encodeQuantityHex, blockHash: executableData.block_hash.data.encodeQuantityHex, - transactions: List[string, MAX_EXECUTION_TRANSACTIONS].init( - mapIt(executableData.transactions, it.encodeOpaqueTransaction)))) + transactions: List[string, MAX_TRANSACTIONS_PER_PAYLOAD].init( + mapIt(executableData.transactions, it.value.encodeOpaqueTransaction)))) template readJsonField(j: JsonNode, fieldName: string, ValueType: type): untyped = var res: ValueType diff --git a/beacon_chain/spec/beaconstate.nim b/beacon_chain/spec/beaconstate.nim index 028dfcd6c..75190920e 100644 --- a/beacon_chain/spec/beaconstate.nim +++ b/beacon_chain/spec/beaconstate.nim @@ -169,7 +169,7 @@ proc slash_validator*( when state is phase0.BeaconState: decrease_balance(state, slashed_index, validator.effective_balance div MIN_SLASHING_PENALTY_QUOTIENT) - elif state is altair.BeaconState: + elif state is altair.BeaconState or state is merge.BeaconState: decrease_balance(state, slashed_index, validator.effective_balance div MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR) else: @@ -190,7 +190,7 @@ proc slash_validator*( proposer_reward = when state is phase0.BeaconState: whistleblower_reward div PROPOSER_REWARD_QUOTIENT - elif state is altair.BeaconState: + elif state is altair.BeaconState or state is merge.BeaconState: whistleblower_reward * PROPOSER_WEIGHT div WEIGHT_DENOMINATOR else: raiseAssert "invalid BeaconState type" @@ -552,7 +552,7 @@ func check_attestation_index( ok() # https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.4/specs/altair/beacon-chain.md#get_attestation_participation_flag_indices -func get_attestation_participation_flag_indices(state: altair.BeaconState, +func get_attestation_participation_flag_indices(state: altair.BeaconState | merge.BeaconState, data: AttestationData, inclusion_delay: uint64): seq[int] = ## Return the flag indices that are satisfied by an attestation. @@ -598,13 +598,13 @@ func get_total_active_balance*(state: SomeBeaconState, cache: var StateCache): G # https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.4/specs/altair/beacon-chain.md#get_base_reward_per_increment func get_base_reward_per_increment*( - state: altair.BeaconState, cache: var StateCache): Gwei = + state: altair.BeaconState | merge.BeaconState, cache: var StateCache): Gwei = EFFECTIVE_BALANCE_INCREMENT * BASE_REWARD_FACTOR div integer_squareroot(get_total_active_balance(state, cache)) # https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.4/specs/altair/beacon-chain.md#get_base_reward func get_base_reward( - state: altair.BeaconState, index: ValidatorIndex, + state: altair.BeaconState | merge.BeaconState, index: ValidatorIndex, base_reward_per_increment: Gwei): Gwei = ## Return the base reward for the validator defined by ``index`` with respect ## to the current ``state``. @@ -708,7 +708,7 @@ proc process_attestation*( addPendingAttestation(state.current_epoch_attestations) else: addPendingAttestation(state.previous_epoch_attestations) - elif state is altair.BeaconState: + elif state is altair.BeaconState or state is merge.BeaconState: doAssert base_reward_per_increment > 0.Gwei if attestation.data.target.epoch == get_current_epoch(state): updateParticipationFlags(state.current_epoch_participation) @@ -859,3 +859,60 @@ proc upgrade_to_altair*(cfg: RuntimeConfig, pre: phase0.BeaconState): ref altair post[].next_sync_committee = get_next_sync_committee(post[]) post + +# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.4/specs/merge/fork.md#upgrading-the-state +func upgrade_to_merge*(cfg: RuntimeConfig, pre: altair.BeaconState): + ref merge.BeaconState = + let epoch = get_current_epoch(pre) + (ref merge.BeaconState)( + # Versioning + genesis_time: pre.genesis_time, + genesis_validators_root: pre.genesis_validators_root, + slot: pre.slot, + fork: Fork( + previous_version: pre.fork.current_version, + current_version: cfg.MERGE_FORK_VERSION, + epoch: epoch, + ), + + # History + latest_block_header: pre.latest_block_header, + block_roots: pre.block_roots, + state_roots: pre.state_roots, + historical_roots: pre.historical_roots, + + # Eth1 + eth1_data: pre.eth1_data, + eth1_data_votes: pre.eth1_data_votes, + eth1_deposit_index: pre.eth1_deposit_index, + + # Registry + validators: pre.validators, + balances: pre.balances, + + # Randomness + randao_mixes: pre.randao_mixes, + + # Slashings + slashings: pre.slashings, + + # Participation + previous_epoch_participation: pre.previous_epoch_participation, + current_epoch_participation: pre.current_epoch_participation, + + # Finality + justification_bits: pre.justification_bits, + previous_justified_checkpoint: pre.previous_justified_checkpoint, + current_justified_checkpoint: pre.current_justified_checkpoint, + finalized_checkpoint: pre.finalized_checkpoint, + + # Inactivity + inactivity_scores: pre.inactivity_scores, + + # Sync + current_sync_committee: pre.current_sync_committee, + next_sync_committee: pre.next_sync_committee, + + # Execution-layer + latest_execution_payload_header: ExecutionPayloadHeader() + ) diff --git a/beacon_chain/spec/datatypes/altair.nim b/beacon_chain/spec/datatypes/altair.nim index 1861a2375..738128b89 100644 --- a/beacon_chain/spec/datatypes/altair.nim +++ b/beacon_chain/spec/datatypes/altair.nim @@ -244,14 +244,13 @@ type data*: BeaconState root*: Eth2Digest # hash_tree_root(data) - # HF1 implies knowledge of phase 0, and this saves creating some other + # Altair implies phase 0 knowledge, and this saves creating some other # module to merge such knowledge. Another approach is to have imported # set of phase 0/HF1 symbols be independently combined by each module, # when necessary, but that spreads such detailed abstraction knowledge # more widely through codebase than strictly required. Do not export a # phase 0 version of symbols; anywhere which specially handles it will # have to do so itself. - SomeBeaconState* = BeaconState | phase0.BeaconState SomeHashedBeaconState* = HashedBeaconState | phase0.HashedBeaconState # https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#beaconblock diff --git a/beacon_chain/spec/datatypes/merge.nim b/beacon_chain/spec/datatypes/merge.nim index 7e39d1593..b8f2fcf2d 100644 --- a/beacon_chain/spec/datatypes/merge.nim +++ b/beacon_chain/spec/datatypes/merge.nim @@ -5,11 +5,6 @@ # * 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. -# TODO Careful, not nil analysis is broken / incomplete and the semantics will -# likely change in future versions of the language: -# https://github.com/nim-lang/RFCs/issues/250 -{.experimental: "notnil".} - {.push raises: [Defect].} import @@ -18,20 +13,22 @@ import json_serialization, json_serialization/types as jsonTypes, ../../ssz/types as sszTypes, ../digest, + ./phase0, ./altair, #web3/ethtypes, nimcrypto/utils const - # https://github.com/ethereum/consensus-specs/blob/e895c29f3f42382a0c913f3d0fd33522d7db9e87/specs/merge/beacon-chain.md#execution + # https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.4/specs/merge/beacon-chain.md#execution MAX_BYTES_PER_OPAQUE_TRANSACTION* = 1048576 - MAX_EXECUTION_TRANSACTIONS* = 16384 - BYTES_PER_LOGS_BLOOM* = 256 - - EVM_BLOCK_ROOTS_SIZE* = 8 + MAX_TRANSACTIONS_PER_PAYLOAD* = 16384 + BYTES_PER_LOGS_BLOOM = 256 + GAS_LIMIT_DENOMINATOR = 1024 + MIN_GAS_LIMIT = 5000 type - # https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/beacon-chain.md#custom-types + # https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.4/specs/merge/beacon-chain.md#custom-types OpaqueTransaction* = List[byte, Limit MAX_BYTES_PER_OPAQUE_TRANSACTION] + Transaction* = SingleMemberUnion[OpaqueTransaction] EthAddress* = object data*: array[20, byte] # TODO there's a network_metadata type, but the import hierarchy's inconvenient @@ -39,34 +36,269 @@ type BloomLogs* = object data*: array[BYTES_PER_LOGS_BLOOM, byte] - # https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/beacon-chain.md#executionpayload + # https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.4/specs/merge/beacon-chain.md#executionpayload ExecutionPayload* = object - block_hash*: Eth2Digest # Hash of execution block parent_hash*: Eth2Digest - coinbase*: EthAddress + coinbase*: EthAddress # 'beneficiary' in the yellow paper state_root*: Eth2Digest - number*: uint64 + receipt_root*: Eth2Digest # 'receipts root' in the yellow paper + logs_bloom*: BloomLogs + random*: Eth2Digest # 'difficulty' in the yellow paper + block_number*: uint64 # 'number' in the yellow paper gas_limit*: uint64 gas_used*: uint64 timestamp*: uint64 - receipt_root*: Eth2Digest - logs_bloom*: BloomLogs - transactions*: List[OpaqueTransaction, MAX_EXECUTION_TRANSACTIONS] + base_fee_per_gas*: Eth2Digest # base fee introduced in EIP-1559, little-endian serialized - # https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/beacon-chain.md#executionpayloadheader + # Extra payload fields + block_hash*: Eth2Digest # Hash of execution block + transactions*: List[Transaction, MAX_TRANSACTIONS_PER_PAYLOAD] + + # https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.4/specs/merge/beacon-chain.md#executionpayloadheader ExecutionPayloadHeader* = object - block_hash*: Eth2Digest # Hash of execution block parent_hash*: Eth2Digest coinbase*: EthAddress state_root*: Eth2Digest - number*: uint64 + receipt_root*: Eth2Digest + logs_bloom*: BloomLogs + random*: Eth2Digest + block_number*: uint64 gas_limit*: uint64 gas_used*: uint64 timestamp*: uint64 - receipt_root*: Eth2Digest - logs_bloom*: BloomLogs + base_fee_per_gas*: Eth2Digest # base fee introduced in EIP-1559, little-endian serialized + + # Extra payload fields + block_hash*: Eth2Digest # Hash of execution block transactions_root*: Eth2Digest + # https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.4/specs/merge/beacon-chain.md#beaconstate + BeaconState* = object + # Versioning + genesis_time*: uint64 + genesis_validators_root*: Eth2Digest + slot*: Slot + fork*: Fork + + # History + latest_block_header*: BeaconBlockHeader ##\ + ## `latest_block_header.state_root == ZERO_HASH` temporarily + + block_roots*: HashArray[Limit SLOTS_PER_HISTORICAL_ROOT, Eth2Digest] ##\ + ## Needed to process attestations, older to newer + + state_roots*: HashArray[Limit SLOTS_PER_HISTORICAL_ROOT, Eth2Digest] + historical_roots*: HashList[Eth2Digest, Limit HISTORICAL_ROOTS_LIMIT] + + # Eth1 + eth1_data*: Eth1Data + eth1_data_votes*: + HashList[Eth1Data, Limit(EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH)] + eth1_deposit_index*: uint64 + + # Registry + validators*: HashList[Validator, Limit VALIDATOR_REGISTRY_LIMIT] + balances*: HashList[uint64, Limit VALIDATOR_REGISTRY_LIMIT] + + # Randomness + randao_mixes*: HashArray[Limit EPOCHS_PER_HISTORICAL_VECTOR, Eth2Digest] + + # Slashings + slashings*: HashArray[Limit EPOCHS_PER_SLASHINGS_VECTOR, uint64] ##\ + ## Per-epoch sums of slashed effective balances + + # Participation + previous_epoch_participation*: + HashList[ParticipationFlags, Limit VALIDATOR_REGISTRY_LIMIT] + current_epoch_participation*: + HashList[ParticipationFlags, Limit VALIDATOR_REGISTRY_LIMIT] + + # Finality + justification_bits*: uint8 ##\ + ## Bit set for every recent justified epoch + ## Model a Bitvector[4] as a one-byte uint, which should remain consistent + ## with ssz/hashing. + + previous_justified_checkpoint*: Checkpoint ##\ + ## Previous epoch snapshot + + current_justified_checkpoint*: Checkpoint + finalized_checkpoint*: Checkpoint + + # Inactivity + inactivity_scores*: HashList[uint64, Limit VALIDATOR_REGISTRY_LIMIT] + + # Sync + current_sync_committee*: SyncCommittee + next_sync_committee*: SyncCommittee + + # Execution + latest_execution_payload_header*: ExecutionPayloadHeader # [New in Merge] + + SomeBeaconState* = BeaconState | altair.BeaconState | phase0.BeaconState + + # https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#beaconblock + BeaconBlock* = object + ## For each slot, a proposer is chosen from the validator pool to propose + ## a new block. Once the block as been proposed, it is transmitted to + ## validators that will have a chance to vote on it through attestations. + ## Each block collects attestations, or votes, on past blocks, thus a chain + ## is formed. + + slot*: Slot + proposer_index*: uint64 + + parent_root*: Eth2Digest ##\ + ## Root hash of the previous block + + state_root*: Eth2Digest ##\ + ## The state root, _after_ this block has been processed + + body*: BeaconBlockBody + + SigVerifiedBeaconBlock* = object + ## A BeaconBlock that contains verified signatures + ## but that has not been verified for state transition + slot*: Slot + proposer_index*: uint64 + + parent_root*: Eth2Digest ##\ + ## Root hash of the previous block + + state_root*: Eth2Digest ##\ + ## The state root, _after_ this block has been processed + + body*: SigVerifiedBeaconBlockBody + + TrustedBeaconBlock* = object + ## When we receive blocks from outside sources, they are untrusted and go + ## through several layers of validation. Blocks that have gone through + ## validations can be trusted to be well-formed, with a correct signature, + ## having a parent and applying cleanly to the state that their parent + ## left them with. + ## + ## When loading such blocks from the database, to rewind states for example, + ## it is expensive to redo the validations (in particular, the signature + ## checks), thus `TrustedBlock` uses a `TrustedSig` type to mark that these + ## checks can be skipped. + ## + ## TODO this could probably be solved with some type trickery, but there + ## too many bugs in nim around generics handling, and we've used up + ## the trickery budget in the serialization library already. Until + ## then, the type must be manually kept compatible with its untrusted + ## cousin. + slot*: Slot + proposer_index*: uint64 + parent_root*: Eth2Digest ##\ + state_root*: Eth2Digest ##\ + body*: TrustedBeaconBlockBody + + # https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.4/specs/merge/beacon-chain.md#beaconblockbody + BeaconBlockBody* = object + randao_reveal*: ValidatorSig + eth1_data*: Eth1Data ##\ + ## Eth1 data vote + + graffiti*: GraffitiBytes ##\ + ## Arbitrary data + + # Operations + proposer_slashings*: List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS] + attester_slashings*: List[AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS] + attestations*: List[Attestation, Limit MAX_ATTESTATIONS] + deposits*: List[Deposit, Limit MAX_DEPOSITS] + voluntary_exits*: List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS] + sync_aggregate*: SyncAggregate + + # Execution + execution_payload*: ExecutionPayload # [New in Merge] + + SigVerifiedBeaconBlockBody* = object + ## A BeaconBlock body with signatures verified + ## including: + ## - Randao reveal + ## - Attestations + ## - ProposerSlashing (SignedBeaconBlockHeader) + ## - AttesterSlashing (IndexedAttestation) + ## - SignedVoluntaryExits + ## + ## - ETH1Data (Deposits) can contain invalid BLS signatures + ## + ## The block state transition has NOT been verified + randao_reveal*: ValidatorSig + eth1_data*: Eth1Data ##\ + ## Eth1 data vote + + graffiti*: GraffitiBytes ##\ + ## Arbitrary data + + # Operations + proposer_slashings*: List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS] + attester_slashings*: List[AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS] + attestations*: List[Attestation, Limit MAX_ATTESTATIONS] + deposits*: List[Deposit, Limit MAX_DEPOSITS] + voluntary_exits*: List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS] + sync_aggregate*: SyncAggregate + + # Execution + execution_payload*: ExecutionPayload # [New in Merge] + + TrustedBeaconBlockBody* = object + ## A full verified block + randao_reveal*: ValidatorSig + eth1_data*: Eth1Data ##\ + ## Eth1 data vote + + graffiti*: GraffitiBytes ##\ + ## Arbitrary data + + # Operations + proposer_slashings*: List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS] + attester_slashings*: List[AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS] + attestations*: List[Attestation, Limit MAX_ATTESTATIONS] + deposits*: List[Deposit, Limit MAX_DEPOSITS] + voluntary_exits*: List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS] + sync_aggregate*: SyncAggregate + + # Execution + execution_payload*: ExecutionPayload # [New in Merge] + + # https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.4/specs/phase0/beacon-chain.md#signedbeaconblock + SignedBeaconBlock* = object + message*: BeaconBlock + signature*: ValidatorSig + + root* {.dontSerialize.}: Eth2Digest # cached root of signed beacon block + + SigVerifiedSignedBeaconBlock* = object + ## A SignedBeaconBlock with signatures verified + ## including: + ## - Block signature + ## - BeaconBlockBody + ## - Randao reveal + ## - Attestations + ## - ProposerSlashing (SignedBeaconBlockHeader) + ## - AttesterSlashing (IndexedAttestation) + ## - SignedVoluntaryExits + ## + ## - ETH1Data (Deposits) can contain invalid BLS signatures + ## + ## The block state transition has NOT been verified + message*: SigVerifiedBeaconBlock + signature*: TrustedSig + + root* {.dontSerialize.}: Eth2Digest # cached root of signed beacon block + + TrustedSignedBeaconBlock* = object + message*: TrustedBeaconBlock + signature*: TrustedSig + + root* {.dontSerialize.}: Eth2Digest # cached root of signed beacon block + + SomeSignedBeaconBlock* = SignedBeaconBlock | SigVerifiedSignedBeaconBlock | TrustedSignedBeaconBlock + SomeBeaconBlock* = BeaconBlock | SigVerifiedBeaconBlock | TrustedBeaconBlock + SomeBeaconBlockBody* = BeaconBlockBody | SigVerifiedBeaconBlockBody | TrustedBeaconBlockBody + # Empirically derived from Catalyst responses; doesn't seem to match merge # spec per commit 1fb9a6dd32b581c912d672634882d7e2eb2775cd from 2021-04-22 # {"jsonrpc":"2.0","id":1,"result":{"blockHash":"0x35139e42d930c640eee446944f7f8b345771b69dfa10120895057f48680ea27d","parentHash":"0x3a3fdfc9ab6e17ff530b57bc21494da3848ebbeaf9343545fded7a18d221ffec","miner":"0x1000000000000000000000000000000000000000","stateRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","number":"0x1","gasLimit":"0x2fefd8","gasUsed":"0x0","timestamp":"0x6087e796","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","transactions":[]}} @@ -81,7 +313,7 @@ type timestamp*: string receiptsRoot*: string logsBloom*: string - transactions*: List[string, MAX_EXECUTION_TRANSACTIONS] + transactions*: List[string, MAX_TRANSACTIONS_PER_PAYLOAD] BlockParams* = object parentHash*: string @@ -111,7 +343,6 @@ proc readValue*(r: var JsonReader, a: var EthAddress) {.raises: [Defect, IOError except ValueError: raiseUnexpectedValue(r, "Hex string expected") -# https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/beacon-chain.md#is_transition_completed -func is_transition_completed*(state: auto): bool = - # Rayonism starts post-merge - true +# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.4/specs/merge/beacon-chain.md#is_merge_complete +func is_merge_complete(state: merge.BeaconState): bool = + state.latest_execution_payload_header != default(ExecutionPayloadHeader) diff --git a/beacon_chain/spec/eth2_ssz_serialization.nim b/beacon_chain/spec/eth2_ssz_serialization.nim index 96efa6c47..64b29b8e4 100644 --- a/beacon_chain/spec/eth2_ssz_serialization.nim +++ b/beacon_chain/spec/eth2_ssz_serialization.nim @@ -13,7 +13,7 @@ import ./ssz_codec, ../ssz/ssz_serialization, - ./datatypes/[phase0, altair], + ./datatypes/[phase0, altair, merge], ./eth2_merkleization export phase0, altair, ssz_codec, ssz_serialization, eth2_merkleization @@ -39,6 +39,12 @@ template readSszBytes*( template readSszBytes*( data: openArray[byte], val: var altair.TrustedSignedBeaconBlock, updateRoot = true) = readAndUpdateRoot(data, val, updateRoot) +template readSszBytes*( + data: openArray[byte], val: var merge.SignedBeaconBlock, updateRoot = true) = + readAndUpdateRoot(data, val, updateRoot) +template readSszBytes*( + data: openArray[byte], val: var merge.TrustedSignedBeaconBlock, updateRoot = true) = + readAndUpdateRoot(data, val, updateRoot) template readSszBytes*( data: openArray[byte], val: var auto, updateRoot: bool) = diff --git a/beacon_chain/spec/helpers.nim b/beacon_chain/spec/helpers.nim index 9c4d138b2..1b404864a 100644 --- a/beacon_chain/spec/helpers.nim +++ b/beacon_chain/spec/helpers.nim @@ -15,7 +15,7 @@ import # Third-party stew/[byteutils, endians2], # Internal - ./datatypes/[phase0, altair], + ./datatypes/[phase0, altair, merge], ./eth2_merkleization, ./ssz_codec # TODO although eth2_merkleization already exports ssz_codec, *sometimes* code diff --git a/beacon_chain/spec/state_transition_block.nim b/beacon_chain/spec/state_transition_block.nim index 1debd44b6..dc2873fe7 100644 --- a/beacon_chain/spec/state_transition_block.nim +++ b/beacon_chain/spec/state_transition_block.nim @@ -23,7 +23,7 @@ import std/[algorithm, intsets, options, sequtils, sets, tables], chronicles, metrics, ../extras, - ./datatypes/[phase0, altair], + ./datatypes/[phase0, altair, merge], "."/[beaconstate, eth2_merkleization, helpers, validator, signatures], ../../nbench/bench_lab diff --git a/beacon_chain/spec/validator.nim b/beacon_chain/spec/validator.nim index 33d7119c6..e097dd6e5 100644 --- a/beacon_chain/spec/validator.nim +++ b/beacon_chain/spec/validator.nim @@ -10,7 +10,7 @@ import std/[options, math, tables], - ./datatypes/[phase0, altair], + ./datatypes/[phase0, altair, merge], ./helpers export phase0, altair diff --git a/beacon_chain/ssz/codec.nim b/beacon_chain/ssz/codec.nim index cbccf0187..1babb36bf 100644 --- a/beacon_chain/ssz/codec.nim +++ b/beacon_chain/ssz/codec.nim @@ -169,6 +169,12 @@ func readSszValue*[T](input: openArray[byte], readSszValue(input.toOpenArray(offset, input.len - 1), val[resultLen - 1]) + elif val is SingleMemberUnion: + readSszValue(input.toOpenArray(0, 0), val.selector) + if val.selector != 0'u8: + raise newException(MalformedSszError, "SingleMemberUnion selector must be 0") + readSszValue(input.toOpenArray(1, input.len - 1), val.value) + elif val is UintN|bool: val = fromSszBytes(T, input) diff --git a/beacon_chain/ssz/merkleization.nim b/beacon_chain/ssz/merkleization.nim index 77f39ef50..eaaee18e5 100644 --- a/beacon_chain/ssz/merkleization.nim +++ b/beacon_chain/ssz/merkleization.nim @@ -545,6 +545,10 @@ func hashTreeRootAux[T](x: T): Eth2Digest = chunkedHashTreeRootForBasicTypes(markleizer, x) elif T is BitArray: hashTreeRootAux(x.bytes) + elif T is SingleMemberUnion: + doAssert x.selector == 0'u8 + merkleizeFields(Limit 2): + addField hashTreeRoot(toSszType(x.value)) elif T is array|object|tuple: trs "MERKLEIZING FIELDS" const totalFields = when T is array: len(x) diff --git a/beacon_chain/ssz/ssz_serialization.nim b/beacon_chain/ssz/ssz_serialization.nim index 6a3e42568..f59e7175d 100644 --- a/beacon_chain/ssz/ssz_serialization.nim +++ b/beacon_chain/ssz/ssz_serialization.nim @@ -150,6 +150,10 @@ proc writeVarSizeType(w: var SszWriter, value: auto) {.raises: [Defect, IOError] when value is HashArray|HashList: writeVarSizeType(w, value.data) + elif value is SingleMemberUnion: + doAssert value.selector == 0'u8 + w.writeValue 0'u8 + w.writeValue value.value elif value is List: # We reduce code bloat by forwarding all `List` types to a general `seq[T]` proc. writeSeq(w, asSeq value) @@ -203,6 +207,9 @@ func sszSize*(value: auto): int {.gcsafe, raises: [Defect].} = elif T is BitList: return len(bytes(value)) + elif T is SingleMemberUnion: + sszSize(toSszType value.value) + 1 + elif T is object|tuple: result = anonConst fixedPortionSize(T) enumInstanceSerializedFields(value, _{.used.}, field): diff --git a/beacon_chain/ssz/types.nim b/beacon_chain/ssz/types.nim index 7d8dbac39..8ee4fe212 100644 --- a/beacon_chain/ssz/types.nim +++ b/beacon_chain/ssz/types.nim @@ -85,6 +85,10 @@ type List*[T; maxLen: static Limit] = distinct seq[T] BitList*[maxLen: static Limit] = distinct BitSeq + SingleMemberUnion*[T] = object + selector*: uint8 + value*: T + HashArray*[maxLen: static Limit; T] = object ## Array implementation that caches the hash of each chunk of data - see ## also HashList for more details. diff --git a/tests/official/all_fixtures_require_ssz.nim b/tests/official/all_fixtures_require_ssz.nim index 8ee77cd6a..265d9bf25 100644 --- a/tests/official/all_fixtures_require_ssz.nim +++ b/tests/official/all_fixtures_require_ssz.nim @@ -13,6 +13,7 @@ import ../testutil import ./phase0/all_phase0_fixtures_require_ssz, - ./altair/all_altair_fixtures_require_ssz + ./altair/all_altair_fixtures_require_ssz, + ./merge/all_merge_fixtures_require_ssz summarizeLongTests("FixtureAll") diff --git a/tests/official/merge/all_merge_fixtures_require_ssz.nim b/tests/official/merge/all_merge_fixtures_require_ssz.nim new file mode 100644 index 000000000..2436d78f4 --- /dev/null +++ b/tests/official/merge/all_merge_fixtures_require_ssz.nim @@ -0,0 +1,19 @@ +# beacon_chain +# Copyright (c) 2021 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. + +# All non-pure SSZ tests that require the -d:ssz_testing +# to ignore invalid BLS signature in EF test vectors +# https://github.com/status-im/nimbus-eth2/issues/374 + +{.used.} + +import + ./test_fixture_operations_attestations, + ./test_fixture_operations_attester_slashings, + ./test_fixture_operations_proposer_slashings, + ./test_fixture_operations_voluntary_exit, + ./test_fixture_ssz_consensus_objects diff --git a/tests/official/merge/test_fixture_operations_attestations.nim b/tests/official/merge/test_fixture_operations_attestations.nim new file mode 100644 index 000000000..4e6776cc1 --- /dev/null +++ b/tests/official/merge/test_fixture_operations_attestations.nim @@ -0,0 +1,71 @@ +# beacon_chain +# Copyright (c) 2018-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 + std/os, + # Utilities + chronicles, + unittest2, + stew/results, + # Beacon chain internals + ../../../beacon_chain/spec/beaconstate, + ../../../beacon_chain/spec/datatypes/merge, + # Test utilities + ../../testutil, + ../fixtures_utils, + ../../helpers/debug_state + +const OperationsAttestationsDir = SszTestsDir/const_preset/"merge"/"operations"/"attestation"/"pyspec_tests" + +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 = OperationsAttestationsDir / identifier + + proc `testImpl _ operations_attestations _ identifier`() = + + var prefix: string + if existsFile(testDir/"post.ssz_snappy"): + prefix = "[Valid] " + else: + prefix = "[Invalid] " + + test prefix & identifier: + var cache = StateCache() + + let attestation = + parseTest(testDir/"attestation.ssz_snappy", SSZ, Attestation) + var preState = + newClone(parseTest(testDir/"pre.ssz_snappy", SSZ, merge.BeaconState)) + + if existsFile(testDir/"post.ssz_snappy"): + let postState = + newClone(parseTest(testDir/"post.ssz_snappy", SSZ, merge.BeaconState)) + let done = process_attestation( + preState[], attestation, {}, + get_base_reward_per_increment(preState[], cache), cache).isOk + doAssert done, "Valid attestation not processed" + check: preState[].hash_tree_root() == postState[].hash_tree_root() + reportDiff(preState, postState) + else: + let done = process_attestation( + preState[], attestation, {}, + get_base_reward_per_increment(preState[], cache), cache).isOk + doAssert done == false, "We didn't expect this invalid attestation to be processed." + + `testImpl _ operations_attestations _ identifier`() + +suite "Ethereum Foundation - Merge - Operations - Attestations " & preset(): + for kind, path in walkDir( + OperationsAttestationsDir, relative = true, checkDir = true): + runTest(path) diff --git a/tests/official/merge/test_fixture_operations_attester_slashings.nim b/tests/official/merge/test_fixture_operations_attester_slashings.nim new file mode 100644 index 000000000..9cf427aed --- /dev/null +++ b/tests/official/merge/test_fixture_operations_attester_slashings.nim @@ -0,0 +1,68 @@ +# beacon_chain +# Copyright (c) 2018-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 + std/os, + # Utilities + chronicles, + stew/results, + # Beacon chain internals + ../../../beacon_chain/spec/state_transition_block, + ../../../beacon_chain/spec/datatypes/merge, + # Test utilities + ../../testutil, + ../fixtures_utils, + ../../helpers/debug_state + +const OpAttSlashingDir = SszTestsDir/const_preset/"merge"/"operations"/"attester_slashing"/"pyspec_tests" + +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 = OpAttSlashingDir / identifier + + proc `testImpl _ operations_attester_slashing _ identifier`() = + + var prefix: string + if existsFile(testDir/"post.ssz_snappy"): + prefix = "[Valid] " + else: + prefix = "[Invalid] " + + test prefix & identifier: + let attesterSlashing = + parseTest(testDir/"attester_slashing.ssz_snappy", SSZ, AttesterSlashing) + var + cache = StateCache() + preState = + newClone(parseTest(testDir/"pre.ssz_snappy", SSZ, merge.BeaconState)) + + if existsFile(testDir/"post.ssz_snappy"): + let + postState = + newClone(parseTest(testDir/"post.ssz_snappy", SSZ, merge.BeaconState)) + done = process_attester_slashing( + defaultRuntimeConfig, preState[], attesterSlashing, {}, cache).isOk + doAssert done, "Valid attestater slashing not processed" + check: preState[].hash_tree_root() == postState[].hash_tree_root() + reportDiff(preState, postState) + else: + let done = process_attester_slashing( + defaultRuntimeConfig, preState[], attesterSlashing, {}, cache).isOk + doAssert done == false, "We didn't expect this invalid attester slashing to be processed." + + `testImpl _ operations_attester_slashing _ identifier`() + +suite "Ethereum Foundation - Merge - Operations - Attester slashing " & preset(): + for kind, path in walkDir(OpAttSlashingDir, relative = true, checkDir = true): + runTest(path) diff --git a/tests/official/merge/test_fixture_operations_proposer_slashings.nim b/tests/official/merge/test_fixture_operations_proposer_slashings.nim new file mode 100644 index 000000000..e1db0f9cf --- /dev/null +++ b/tests/official/merge/test_fixture_operations_proposer_slashings.nim @@ -0,0 +1,70 @@ +# beacon_chain +# Copyright (c) 2018-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, + # Utilities + stew/results, + # Beacon chain internals + ../../../beacon_chain/spec/state_transition_block, + ../../../beacon_chain/spec/datatypes/merge, + # Test utilities + ../../testutil, + ../fixtures_utils, + ../../helpers/debug_state + +when isMainModule: + import chronicles # or some random compile error happens... + +const OpProposerSlashingDir = SszTestsDir/const_preset/"merge"/"operations"/"proposer_slashing"/"pyspec_tests" + +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 = OpProposerSlashingDir / identifier + + proc `testImpl_proposer_slashing _ identifier`() = + + var prefix: string + if existsFile(testDir/"post.ssz_snappy"): + prefix = "[Valid] " + else: + prefix = "[Invalid] " + + test prefix & identifier: + let proposerSlashing = parseTest( + testDir/"proposer_slashing.ssz_snappy", SSZ, ProposerSlashing) + var + preState = + newClone(parseTest(testDir/"pre.ssz_snappy", SSZ, merge.BeaconState)) + cache = StateCache() + + if existsFile(testDir/"post.ssz_snappy"): + let + postState = + newClone(parseTest(testDir/"post.ssz_snappy", SSZ, merge.BeaconState)) + done = process_proposer_slashing( + defaultRuntimeConfig, preState[], proposerSlashing, {}, cache).isOk + doAssert done, "Valid proposer slashing not processed" + check: preState[].hash_tree_root() == postState[].hash_tree_root() + reportDiff(preState, postState) + else: + let done = process_proposer_slashing(defaultRuntimeConfig, preState[], proposerSlashing, {}, cache).isOk + doAssert done == false, "We didn't expect this invalid proposer slashing to be processed." + + `testImpl_proposer_slashing _ identifier`() + +suite "Ethereum Foundation - Merge - Operations - Proposer slashing " & preset(): + for kind, path in walkDir( + OpProposerSlashingDir, relative = true, checkDir = true): + runTest(path) diff --git a/tests/official/merge/test_fixture_operations_voluntary_exit.nim b/tests/official/merge/test_fixture_operations_voluntary_exit.nim new file mode 100644 index 000000000..9272f51ca --- /dev/null +++ b/tests/official/merge/test_fixture_operations_voluntary_exit.nim @@ -0,0 +1,69 @@ +# beacon_chain +# Copyright (c) 2018-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 + std/os, + # Utilities + chronicles, + stew/results, + # Beacon chain internals + ../../../beacon_chain/spec/state_transition_block, + ../../../beacon_chain/spec/datatypes/merge, + # Test utilities + ../../testutil, + ../fixtures_utils, + ../../helpers/debug_state + +const OpVoluntaryExitDir = SszTestsDir/const_preset/"merge"/"operations"/"voluntary_exit"/"pyspec_tests" + +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 = OpVoluntaryExitDir / identifier + + proc `testImpl _ voluntary_exit _ identifier`() = + + var prefix: string + if existsFile(testDir/"post.ssz_snappy"): + prefix = "[Valid] " + else: + prefix = "[Invalid] " + + test prefix & identifier: + let voluntaryExit = parseTest( + testDir/"voluntary_exit.ssz_snappy", SSZ, SignedVoluntaryExit) + var + preState = + newClone(parseTest(testDir/"pre.ssz_snappy", SSZ, merge.BeaconState)) + cache = StateCache() + + if existsFile(testDir/"post.ssz_snappy"): + let + postState = + newClone(parseTest(testDir/"post.ssz_snappy", SSZ, merge.BeaconState)) + done = + process_voluntary_exit(defaultRuntimeConfig, preState[], voluntaryExit, {}, cache).isOk + doAssert done, "Valid voluntary exit not processed" + check: preState[].hash_tree_root() == postState[].hash_tree_root() + reportDiff(preState, postState) + else: + let done = + process_voluntary_exit(defaultRuntimeConfig, preState[], voluntaryExit, {}, cache).isOk + doAssert done == false, "We didn't expect this invalid voluntary exit to be processed." + + `testImpl _ voluntary_exit _ identifier`() + +suite "Ethereum Foundation - Merge - Operations - Voluntary exit " & preset(): + for kind, path in walkDir( + OpVoluntaryExitDir, relative = true, checkDir = true): + runTest(path) diff --git a/tests/official/merge/test_fixture_ssz_consensus_objects.nim b/tests/official/merge/test_fixture_ssz_consensus_objects.nim new file mode 100644 index 000000000..de9a6417f --- /dev/null +++ b/tests/official/merge/test_fixture_ssz_consensus_objects.nim @@ -0,0 +1,152 @@ +# beacon_chain +# Copyright (c) 2018-2021 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, strutils, streams, strformat, + macros, sets, + # Third-party + yaml, + # Beacon chain internals + ../../beacon_chain/spec/datatypes/merge, + # Status libraries + snappy, + # Test utilities + ../../testutil, ../fixtures_utils + +# SSZ tests of consensus objects (minimal/mainnet preset specific) + +# Parsing definitions +# ---------------------------------------------------------------- + +const + SSZDir = SszTestsDir/const_preset/"merge"/"ssz_static" + +type + SSZHashTreeRoot = object + # The test files have the values at the "root" + # so we **must** use "root" as a field name + root: string + # Some have a signing_root field + signing_root {.defaultVal: "".}: string + + # https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.3/specs/phase0/validator.md#eth1block + Eth1Block = object + timestamp: uint64 + deposit_root: Eth2Digest + deposit_count: uint64 + # All other eth1 block fields + +# Note this only tracks HashTreeRoot +# Checking the values against the yaml file is TODO (require more flexible Yaml parser) + +proc checkSSZ(T: type merge.SignedBeaconBlock, dir: string, expectedHash: SSZHashTreeRoot) = + # Deserialize into a ref object to not fill Nim stack + let encoded = snappy.decode( + readFileBytes(dir/"serialized.ssz_snappy"), MaxObjectSize) + var deserialized = newClone(sszDecodeEntireInput(encoded, T)) + + # SignedBeaconBlocks usually not hashed because they're identified by + # htr(BeaconBlock), so do it manually + check: expectedHash.root == "0x" & toLowerASCII($hash_tree_root( + [hash_tree_root(deserialized.message), + hash_tree_root(deserialized.signature)])) + + check deserialized.root == hash_tree_root(deserialized.message) + check SSZ.encode(deserialized[]) == encoded + check sszSize(deserialized[]) == encoded.len + + # TODO check the value (requires YAML loader) + +proc checkSSZ(T: type, dir: string, expectedHash: SSZHashTreeRoot) = + # Deserialize into a ref object to not fill Nim stack + let encoded = snappy.decode( + readFileBytes(dir/"serialized.ssz_snappy"), MaxObjectSize) + var deserialized = newClone(sszDecodeEntireInput(encoded, T)) + + check: expectedHash.root == "0x" & toLowerASCII($hash_tree_root(deserialized[])) + + check SSZ.encode(deserialized[]) == encoded + check sszSize(deserialized[]) == encoded.len + + # TODO check the value (requires YAML loader) + +proc loadExpectedHashTreeRoot(dir: string): SSZHashTreeRoot = + var s = openFileStream(dir/"roots.yaml") + yaml.load(s, result) + s.close() + +# Test runner +# ---------------------------------------------------------------- + +suite "Ethereum Foundation - Merge - SSZ consensus objects " & preset(): + doAssert existsDir(SSZDir), "You need to run the \"download_test_vectors.sh\" script to retrieve the official test vectors." + for pathKind, sszType in walkDir(SSZDir, relative = true, checkDir = true): + doAssert pathKind == pcDir + + test &" Testing {sszType}": + let path = SSZDir/sszType + for pathKind, sszTestKind in walkDir( + path, relative = true, checkDir = true): + doAssert pathKind == pcDir + let path = SSZDir/sszType/sszTestKind + for pathKind, sszTestCase in walkDir( + path, relative = true, checkDir = true): + let path = SSZDir/sszType/sszTestKind/sszTestCase + let hash = loadExpectedHashTreeRoot(path) + + case sszType: + of "AggregateAndProof": checkSSZ(AggregateAndProof, path, hash) + of "Attestation": checkSSZ(Attestation, path, hash) + of "AttestationData": checkSSZ(AttestationData, path, hash) + of "AttesterSlashing": checkSSZ(AttesterSlashing, path, hash) + of "BeaconBlock": checkSSZ(merge.BeaconBlock, path, hash) + of "BeaconBlockBody": checkSSZ(merge.BeaconBlockBody, path, hash) + of "BeaconBlockHeader": checkSSZ(BeaconBlockHeader, path, hash) + of "BeaconState": checkSSZ(merge.BeaconState, path, hash) + of "Checkpoint": checkSSZ(Checkpoint, path, hash) + of "ContributionAndProof": checkSSZ(ContributionAndProof, path, hash) + of "Deposit": checkSSZ(Deposit, path, hash) + of "DepositData": checkSSZ(DepositData, path, hash) + of "DepositMessage": checkSSZ(DepositMessage, path, hash) + of "Eth1Block": checkSSZ(Eth1Block, path, hash) + of "Eth1Data": checkSSZ(Eth1Data, path, hash) + of "ExecutionPayload": checkSSZ(ExecutionPayload, path, hash) + of "ExecutionPayloadHeader": + checkSSZ(ExecutionPayloadHeader, path, hash) + of "Fork": checkSSZ(Fork, path, hash) + of "ForkData": checkSSZ(ForkData, path, hash) + of "HistoricalBatch": checkSSZ(HistoricalBatch, path, hash) + of "IndexedAttestation": checkSSZ(IndexedAttestation, path, hash) + of "LightClientSnapshot": checkSSZ(LightClientSnapshot, path, hash) + of "LightClientUpdate": checkSSZ(LightClientUpdate, path, hash) + of "PendingAttestation": checkSSZ(PendingAttestation, path, hash) + of "ProposerSlashing": checkSSZ(ProposerSlashing, path, hash) + of "SignedAggregateAndProof": + checkSSZ(SignedAggregateAndProof, path, hash) + of "SignedBeaconBlock": checkSSZ(merge.SignedBeaconBlock, path, hash) + of "SignedBeaconBlockHeader": + checkSSZ(SignedBeaconBlockHeader, path, hash) + of "SignedContributionAndProof": + checkSSZ(SignedContributionAndProof, path, hash) + of "SignedVoluntaryExit": checkSSZ(SignedVoluntaryExit, path, hash) + of "SigningData": checkSSZ(SigningData, path, hash) + of "SyncAggregate": checkSSZ(SyncAggregate, path, hash) + of "SyncAggregatorSelectionData": + checkSSZ(SyncAggregatorSelectionData, path, hash) + of "SyncCommittee": checkSSZ(SyncCommittee, path, hash) + of "SyncCommitteeContribution": + checkSSZ(SyncCommitteeContribution, path, hash) + of "SyncCommitteeMessage": checkSSZ(SyncCommitteeMessage, path, hash) + of "Validator": checkSSZ(Validator, path, hash) + of "VoluntaryExit": checkSSZ(VoluntaryExit, path, hash) + else: + raise newException(ValueError, "Unsupported test: " & sszType) + +summarizeLongTests("FixtureSSZConsensus")