From 0a43c89cd2438903cbbc09451a3c61b890ae4414 Mon Sep 17 00:00:00 2001 From: tersec Date: Mon, 7 Nov 2022 19:37:48 +0100 Subject: [PATCH] run capella block sanity tests in CI (#4292) --- AllTests-mainnet.md | 5 +- ConsensusSpecPreset-mainnet.md | 78 ++++++++++++- ConsensusSpecPreset-minimal.md | 83 +++++++++++++- beacon_chain/spec/forks.nim | 9 +- beacon_chain/spec/helpers.nim | 18 +-- beacon_chain/spec/state_transition_block.nim | 103 +++++++++++------- .../capella/all_capella_fixtures.nim | 2 +- .../capella/test_fixture_sanity_blocks.nim | 88 +++++++++++++++ 8 files changed, 332 insertions(+), 54 deletions(-) create mode 100644 tests/consensus_spec/capella/test_fixture_sanity_blocks.nim diff --git a/AllTests-mainnet.md b/AllTests-mainnet.md index d506028ca..c3148b530 100644 --- a/AllTests-mainnet.md +++ b/AllTests-mainnet.md @@ -2,6 +2,7 @@ AllTests-mainnet === ## Attestation pool processing [Preset: mainnet] ```diff ++ Attestation from different branch [Preset: mainnet] OK + Attestations may arrive in any order [Preset: mainnet] OK + Attestations may overlap, bigger first [Preset: mainnet] OK + Attestations may overlap, smaller first [Preset: mainnet] OK @@ -14,7 +15,7 @@ AllTests-mainnet + Trying to add a duplicate block from an old pruned epoch is tagged as an error OK + Working with aggregates [Preset: mainnet] OK ``` -OK: 11/11 Fail: 0/11 Skip: 0/11 +OK: 12/12 Fail: 0/12 Skip: 0/12 ## Backfill ```diff + Init without genesis / block OK @@ -603,4 +604,4 @@ OK: 1/1 Fail: 0/1 Skip: 0/1 OK: 9/9 Fail: 0/9 Skip: 0/9 ---TOTAL--- -OK: 332/337 Fail: 0/337 Skip: 5/337 +OK: 333/338 Fail: 0/338 Skip: 5/338 diff --git a/ConsensusSpecPreset-mainnet.md b/ConsensusSpecPreset-mainnet.md index ff47aa20d..4212b38d7 100644 --- a/ConsensusSpecPreset-mainnet.md +++ b/ConsensusSpecPreset-mainnet.md @@ -307,6 +307,20 @@ ConsensusSpecPreset-mainnet + [Invalid] EF - Bellatrix - Sanity - Blocks - same_slot_block_transition [Preset: mainnet] OK + [Invalid] EF - Bellatrix - Sanity - Blocks - slash_and_exit_same_index [Preset: mainnet] OK + [Invalid] EF - Bellatrix - Sanity - Blocks - zero_block_sig [Preset: mainnet] OK ++ [Invalid] EF - Capella - Sanity - Blocks - double_same_proposer_slashings_same_block [Pres OK ++ [Invalid] EF - Capella - Sanity - Blocks - double_similar_proposer_slashings_same_block [P OK ++ [Invalid] EF - Capella - Sanity - Blocks - double_validator_exit_same_block [Preset: mainn OK ++ [Invalid] EF - Capella - Sanity - Blocks - duplicate_attester_slashing [Preset: mainnet] OK ++ [Invalid] EF - Capella - Sanity - Blocks - expected_deposit_in_block [Preset: mainnet] OK ++ [Invalid] EF - Capella - Sanity - Blocks - invalid_block_sig [Preset: mainnet] OK ++ [Invalid] EF - Capella - Sanity - Blocks - invalid_proposer_index_sig_from_expected_propos OK ++ [Invalid] EF - Capella - Sanity - Blocks - invalid_proposer_index_sig_from_proposer_index OK ++ [Invalid] EF - Capella - Sanity - Blocks - invalid_state_root [Preset: mainnet] OK ++ [Invalid] EF - Capella - Sanity - Blocks - parent_from_same_slot [Preset: mainnet] OK ++ [Invalid] EF - Capella - Sanity - Blocks - prev_slot_block_transition [Preset: mainnet] OK ++ [Invalid] EF - Capella - Sanity - Blocks - same_slot_block_transition [Preset: mainnet] OK ++ [Invalid] EF - Capella - Sanity - Blocks - slash_and_exit_same_index [Preset: mainnet] OK ++ [Invalid] EF - Capella - Sanity - Blocks - zero_block_sig [Preset: mainnet] OK + [Invalid] EF - Phase 0 - Sanity - Blocks - double_same_proposer_slashings_same_block [Pres OK + [Invalid] EF - Phase 0 - Sanity - Blocks - double_similar_proposer_slashings_same_block [P OK + [Invalid] EF - Phase 0 - Sanity - Blocks - double_validator_exit_same_block [Preset: mainn OK @@ -429,6 +443,66 @@ ConsensusSpecPreset-mainnet + [Valid] EF - Bellatrix - Sanity - Blocks - skipped_slots [Preset: mainnet] OK + [Valid] EF - Bellatrix - Sanity - Blocks - slash_and_exit_diff_index [Preset: mainnet] OK + [Valid] EF - Bellatrix - Sanity - Blocks - voluntary_exit [Preset: mainnet] OK ++ [Valid] EF - Capella - Finality - finality_no_updates_at_genesis [Preset: mainnet] OK ++ [Valid] EF - Capella - Finality - finality_rule_1 [Preset: mainnet] OK ++ [Valid] EF - Capella - Finality - finality_rule_2 [Preset: mainnet] OK ++ [Valid] EF - Capella - Finality - finality_rule_3 [Preset: mainnet] OK ++ [Valid] EF - Capella - Finality - finality_rule_4 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_0 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_1 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_10 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_11 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_12 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_13 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_14 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_15 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_2 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_3 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_4 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_5 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_6 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_7 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_8 [Preset: mainnet] OK ++ [Valid] EF - Capella - Random - randomized_9 [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - attestation [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - attester_slashing [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - balance_driven_status_transitions [Preset: main OK ++ [Valid] EF - Capella - Sanity - Blocks - deposit_in_block [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - deposit_top_up [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - empty_block_transition [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - empty_block_transition_no_tx [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - empty_block_transition_randomized_payload [Pres OK ++ [Valid] EF - Capella - Sanity - Blocks - empty_epoch_transition [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - empty_sync_committee_committee [Preset: mainnet OK ++ [Valid] EF - Capella - Sanity - Blocks - empty_sync_committee_committee_genesis [Preset: OK ++ [Valid] EF - Capella - Sanity - Blocks - exit_and_bls_change [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - full_random_operations_0 [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - full_random_operations_1 [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - full_random_operations_2 [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - full_random_operations_3 [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - full_sync_committee_committee [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - full_sync_committee_committee_genesis [Preset: OK ++ [Valid] EF - Capella - Sanity - Blocks - full_withdrawal_in_epoch_transition [Preset: ma OK ++ [Valid] EF - Capella - Sanity - Blocks - half_sync_committee_committee [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - half_sync_committee_committee_genesis [Preset: OK ++ [Valid] EF - Capella - Sanity - Blocks - high_proposer_index [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - historical_batch [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - inactivity_scores_full_participation_leaking [P OK ++ [Valid] EF - Capella - Sanity - Blocks - inactivity_scores_leaking [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - is_execution_enabled_false [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - many_partial_withdrawals_in_epoch_transition [P OK ++ [Valid] EF - Capella - Sanity - Blocks - multiple_attester_slashings_no_overlap [Preset: OK ++ [Valid] EF - Capella - Sanity - Blocks - multiple_attester_slashings_partial_overlap [Pr OK ++ [Valid] EF - Capella - Sanity - Blocks - multiple_different_proposer_slashings_same_bloc OK ++ [Valid] EF - Capella - Sanity - Blocks - multiple_different_validator_exits_same_block [ OK ++ [Valid] EF - Capella - Sanity - Blocks - partial_withdrawal_in_epoch_transition [Preset: OK ++ [Valid] EF - Capella - Sanity - Blocks - proposer_after_inactive_index [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - proposer_self_slashing [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - proposer_slashing [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - skipped_slots [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - slash_and_exit_diff_index [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - successful_bls_change [Preset: mainnet] OK ++ [Valid] EF - Capella - Sanity - Blocks - voluntary_exit [Preset: mainnet] OK + [Valid] EF - Phase 0 - Finality - finality_no_updates_at_genesis [Preset: mainnet] OK + [Valid] EF - Phase 0 - Finality - finality_rule_1 [Preset: mainnet] OK + [Valid] EF - Phase 0 - Finality - finality_rule_2 [Preset: mainnet] OK @@ -494,7 +568,7 @@ ConsensusSpecPreset-mainnet + fork_random_low_balances OK + fork_random_misc_balances OK ``` -OK: 464/491 Fail: 0/491 Skip: 27/491 +OK: 538/565 Fail: 0/565 Skip: 27/565 ## Attestation ```diff + [Invalid] EF - Altair - Operations - Attestation - after_epoch_slots OK @@ -1826,4 +1900,4 @@ OK: 48/48 Fail: 0/48 Skip: 0/48 OK: 14/14 Fail: 0/14 Skip: 0/14 ---TOTAL--- -OK: 1553/1580 Fail: 0/1580 Skip: 27/1580 +OK: 1627/1654 Fail: 0/1654 Skip: 27/1654 diff --git a/ConsensusSpecPreset-minimal.md b/ConsensusSpecPreset-minimal.md index 7a9333e10..540419039 100644 --- a/ConsensusSpecPreset-minimal.md +++ b/ConsensusSpecPreset-minimal.md @@ -356,6 +356,20 @@ ConsensusSpecPreset-minimal + [Invalid] EF - Bellatrix - Sanity - Blocks - same_slot_block_transition [Preset: minimal] OK + [Invalid] EF - Bellatrix - Sanity - Blocks - slash_and_exit_same_index [Preset: minimal] OK + [Invalid] EF - Bellatrix - Sanity - Blocks - zero_block_sig [Preset: minimal] OK ++ [Invalid] EF - Capella - Sanity - Blocks - double_same_proposer_slashings_same_block [Pres OK ++ [Invalid] EF - Capella - Sanity - Blocks - double_similar_proposer_slashings_same_block [P OK ++ [Invalid] EF - Capella - Sanity - Blocks - double_validator_exit_same_block [Preset: minim OK ++ [Invalid] EF - Capella - Sanity - Blocks - duplicate_attester_slashing [Preset: minimal] OK ++ [Invalid] EF - Capella - Sanity - Blocks - expected_deposit_in_block [Preset: minimal] OK ++ [Invalid] EF - Capella - Sanity - Blocks - invalid_block_sig [Preset: minimal] OK ++ [Invalid] EF - Capella - Sanity - Blocks - invalid_proposer_index_sig_from_expected_propos OK ++ [Invalid] EF - Capella - Sanity - Blocks - invalid_proposer_index_sig_from_proposer_index OK ++ [Invalid] EF - Capella - Sanity - Blocks - invalid_state_root [Preset: minimal] OK ++ [Invalid] EF - Capella - Sanity - Blocks - parent_from_same_slot [Preset: minimal] OK ++ [Invalid] EF - Capella - Sanity - Blocks - prev_slot_block_transition [Preset: minimal] OK ++ [Invalid] EF - Capella - Sanity - Blocks - same_slot_block_transition [Preset: minimal] OK ++ [Invalid] EF - Capella - Sanity - Blocks - slash_and_exit_same_index [Preset: minimal] OK ++ [Invalid] EF - Capella - Sanity - Blocks - zero_block_sig [Preset: minimal] OK + [Invalid] EF - Phase 0 - Sanity - Blocks - double_same_proposer_slashings_same_block [Pres OK + [Invalid] EF - Phase 0 - Sanity - Blocks - double_similar_proposer_slashings_same_block [P OK + [Invalid] EF - Phase 0 - Sanity - Blocks - double_validator_exit_same_block [Preset: minim OK @@ -488,6 +502,71 @@ ConsensusSpecPreset-minimal + [Valid] EF - Bellatrix - Sanity - Blocks - skipped_slots [Preset: minimal] OK + [Valid] EF - Bellatrix - Sanity - Blocks - slash_and_exit_diff_index [Preset: minimal] OK + [Valid] EF - Bellatrix - Sanity - Blocks - voluntary_exit [Preset: minimal] OK ++ [Valid] EF - Capella - Finality - finality_no_updates_at_genesis [Preset: minimal] OK ++ [Valid] EF - Capella - Finality - finality_rule_1 [Preset: minimal] OK ++ [Valid] EF - Capella - Finality - finality_rule_2 [Preset: minimal] OK ++ [Valid] EF - Capella - Finality - finality_rule_3 [Preset: minimal] OK ++ [Valid] EF - Capella - Finality - finality_rule_4 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_0 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_1 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_10 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_11 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_12 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_13 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_14 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_15 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_2 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_3 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_4 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_5 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_6 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_7 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_8 [Preset: minimal] OK ++ [Valid] EF - Capella - Random - randomized_9 [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - attestation [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - attester_slashing [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - balance_driven_status_transitions [Preset: mini OK ++ [Valid] EF - Capella - Sanity - Blocks - deposit_in_block [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - deposit_top_up [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - empty_block_transition [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - empty_block_transition_large_validator_set [Pre OK ++ [Valid] EF - Capella - Sanity - Blocks - empty_block_transition_no_tx [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - empty_block_transition_randomized_payload [Pres OK ++ [Valid] EF - Capella - Sanity - Blocks - empty_epoch_transition [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - empty_epoch_transition_large_validator_set [Pre OK ++ [Valid] EF - Capella - Sanity - Blocks - empty_epoch_transition_not_finalizing [Preset: OK ++ [Valid] EF - Capella - Sanity - Blocks - empty_sync_committee_committee [Preset: minimal OK ++ [Valid] EF - Capella - Sanity - Blocks - empty_sync_committee_committee_genesis [Preset: OK ++ [Valid] EF - Capella - Sanity - Blocks - eth1_data_votes_consensus [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - eth1_data_votes_no_consensus [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - exit_and_bls_change [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - full_random_operations_0 [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - full_random_operations_1 [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - full_random_operations_2 [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - full_random_operations_3 [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - full_sync_committee_committee [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - full_sync_committee_committee_genesis [Preset: OK ++ [Valid] EF - Capella - Sanity - Blocks - full_withdrawal_in_epoch_transition [Preset: mi OK ++ [Valid] EF - Capella - Sanity - Blocks - half_sync_committee_committee [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - half_sync_committee_committee_genesis [Preset: OK ++ [Valid] EF - Capella - Sanity - Blocks - high_proposer_index [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - historical_batch [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - inactivity_scores_full_participation_leaking [P OK ++ [Valid] EF - Capella - Sanity - Blocks - inactivity_scores_leaking [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - is_execution_enabled_false [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - many_partial_withdrawals_in_epoch_transition [P OK ++ [Valid] EF - Capella - Sanity - Blocks - multiple_attester_slashings_no_overlap [Preset: OK ++ [Valid] EF - Capella - Sanity - Blocks - multiple_attester_slashings_partial_overlap [Pr OK ++ [Valid] EF - Capella - Sanity - Blocks - multiple_different_proposer_slashings_same_bloc OK ++ [Valid] EF - Capella - Sanity - Blocks - multiple_different_validator_exits_same_block [ OK ++ [Valid] EF - Capella - Sanity - Blocks - partial_withdrawal_in_epoch_transition [Preset: OK ++ [Valid] EF - Capella - Sanity - Blocks - proposer_after_inactive_index [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - proposer_self_slashing [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - proposer_slashing [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - skipped_slots [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - slash_and_exit_diff_index [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - successful_bls_change [Preset: minimal] OK ++ [Valid] EF - Capella - Sanity - Blocks - voluntary_exit [Preset: minimal] OK + [Valid] EF - Phase 0 - Finality - finality_no_updates_at_genesis [Preset: minimal] OK + [Valid] EF - Phase 0 - Finality - finality_rule_1 [Preset: minimal] OK + [Valid] EF - Phase 0 - Finality - finality_rule_2 [Preset: minimal] OK @@ -561,7 +640,7 @@ ConsensusSpecPreset-minimal + fork_random_low_balances OK + fork_random_misc_balances OK ``` -OK: 523/558 Fail: 0/558 Skip: 35/558 +OK: 602/637 Fail: 0/637 Skip: 35/637 ## Attestation ```diff + [Invalid] EF - Altair - Operations - Attestation - after_epoch_slots OK @@ -1953,4 +2032,4 @@ OK: 52/52 Fail: 0/52 Skip: 0/52 OK: 14/14 Fail: 0/14 Skip: 0/14 ---TOTAL--- -OK: 1660/1695 Fail: 0/1695 Skip: 35/1695 +OK: 1739/1774 Fail: 0/1774 Skip: 35/1774 diff --git a/beacon_chain/spec/forks.nim b/beacon_chain/spec/forks.nim index 95960d4f2..3ea4a7d8a 100644 --- a/beacon_chain/spec/forks.nim +++ b/beacon_chain/spec/forks.nim @@ -75,17 +75,20 @@ type ForkyBeaconBlockBody* = phase0.BeaconBlockBody | altair.BeaconBlockBody | - bellatrix.BeaconBlockBody + bellatrix.BeaconBlockBody | + capella.BeaconBlockBody ForkySigVerifiedBeaconBlockBody* = phase0.SigVerifiedBeaconBlockBody | altair.SigVerifiedBeaconBlockBody | - bellatrix.SigVerifiedBeaconBlockBody + bellatrix.SigVerifiedBeaconBlockBody | + capella.SigVerifiedBeaconBlockBody ForkyTrustedBeaconBlockBody* = phase0.TrustedBeaconBlockBody | altair.TrustedBeaconBlockBody | - bellatrix.TrustedBeaconBlockBody + bellatrix.TrustedBeaconBlockBody | + capella.TrustedBeaconBlockBody SomeForkyBeaconBlockBody* = ForkyBeaconBlockBody | diff --git a/beacon_chain/spec/helpers.nim b/beacon_chain/spec/helpers.nim index dbbcf0955..7b3852199 100644 --- a/beacon_chain/spec/helpers.nim +++ b/beacon_chain/spec/helpers.nim @@ -334,20 +334,24 @@ func is_execution_block*(blck: SomeForkyBeaconBlock): bool = else: false -# https://github.com/ethereum/consensus-specs/blob/v1.2.0/specs/bellatrix/beacon-chain.md#is_merge_transition_block +# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.0/specs/bellatrix/beacon-chain.md#is_merge_transition_block func is_merge_transition_block( - state: bellatrix.BeaconState, + state: bellatrix.BeaconState | capella.BeaconState, body: bellatrix.BeaconBlockBody | bellatrix.TrustedBeaconBlockBody | - bellatrix.SigVerifiedBeaconBlockBody): bool = - const defaultBellatrixExecutionPayload = default(bellatrix.ExecutionPayload) + bellatrix.SigVerifiedBeaconBlockBody | + capella.BeaconBlockBody | capella.TrustedBeaconBlockBody | + capella.SigVerifiedBeaconBlockBody): bool = + const defaultExecutionPayload = default(typeof(body.execution_payload)) not is_merge_transition_complete(state) and - body.execution_payload != defaultBellatrixExecutionPayload + body.execution_payload != defaultExecutionPayload # https://github.com/ethereum/consensus-specs/blob/v1.2.0/specs/bellatrix/beacon-chain.md#is_execution_enabled func is_execution_enabled*( - state: bellatrix.BeaconState, + state: bellatrix.BeaconState | capella.BeaconState, body: bellatrix.BeaconBlockBody | bellatrix.TrustedBeaconBlockBody | - bellatrix.SigVerifiedBeaconBlockBody): bool = + bellatrix.SigVerifiedBeaconBlockBody | + capella.BeaconBlockBody | capella.TrustedBeaconBlockBody | + capella.SigVerifiedBeaconBlockBody): bool = is_merge_transition_block(state, body) or is_merge_transition_complete(state) # https://github.com/ethereum/consensus-specs/blob/v1.2.0/specs/bellatrix/beacon-chain.md#compute_timestamp_at_slot diff --git a/beacon_chain/spec/state_transition_block.nim b/beacon_chain/spec/state_transition_block.nim index 9aba76a26..f49c71fe5 100644 --- a/beacon_chain/spec/state_transition_block.nim +++ b/beacon_chain/spec/state_transition_block.nim @@ -393,7 +393,43 @@ proc process_voluntary_exit*( ? initiate_validator_exit(cfg, state, exited_validator, cache) ok() -# https://github.com/ethereum/consensus-specs/blob/v1.2.0/specs/phase0/beacon-chain.md#operations +# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.0/specs/capella/beacon-chain.md#new-process_bls_to_execution_change +proc process_bls_to_execution_change*( + state: var capella.BeaconState, + signed_address_change: SignedBLSToExecutionChange): Result[void, cstring] = + let address_change = signed_address_change.message + + if not (address_change.validator_index < state.validators.lenu64): + return err("process_bls_to_execution_change: invalid validator index") + + var withdrawal_credentials = + state.validators.item(address_change.validator_index).withdrawal_credentials + + if not (withdrawal_credentials.data[0] == BLS_WITHDRAWAL_PREFIX): + return err("process_bls_to_execution_change: invalid withdrawal prefix") + + # TODO what's usual convention here re 32 hardcoded constant? + if not (withdrawal_credentials.data.toOpenArray(1, 31) == + eth2digest(address_change.from_bls_pubkey.blob).data.toOpenArray(1, 31)): + return err("process_bls_to_execution_change: invalid withdrawal credentials") + + if not verify_bls_to_execution_change_signature( + state.fork, state.genesis_validators_root, state.get_current_epoch, + signed_address_change, address_change.from_bls_pubkey, + signed_address_change.signature): + return err("process_bls_to_execution_change: invalid signature") + + withdrawal_credentials.data[0] = ETH1_ADDRESS_WITHDRAWAL_PREFIX + withdrawal_credentials.data.fill(1, 11, 0) + withdrawal_credentials.data[12..31] = + address_change.to_execution_address.data + state.validators.mitem(address_change.validator_index).withdrawal_credentials = + withdrawal_credentials + + ok() + +# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.0/specs/phase0/beacon-chain.md#operations +# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.0/specs/capella/beacon-chain.md#modified-process_operations proc process_operations(cfg: RuntimeConfig, state: var ForkyBeaconState, body: SomeForkyBeaconBlockBody, @@ -420,6 +456,10 @@ proc process_operations(cfg: RuntimeConfig, ? process_deposit(cfg, state, op, flags) for op in body.voluntary_exits: ? process_voluntary_exit(cfg, state, op, flags, cache) + for fieldName, _ in body.fieldPairs: + when fieldName == "bls_to_execution_changes": + for op in body.bls_to_execution_changes: + ? process_bls_to_execution_change(state, op) ok() @@ -579,41 +619,6 @@ proc process_execution_payload*( ok() -# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.0/specs/capella/beacon-chain.md#new-process_bls_to_execution_change -proc process_bls_to_execution_change*( - state: var capella.BeaconState, - signed_address_change: SignedBLSToExecutionChange): Result[void, cstring] = - let address_change = signed_address_change.message - - if not (address_change.validator_index < state.validators.lenu64): - return err("process_bls_to_execution_change: invalid validator index") - - var withdrawal_credentials = - state.validators.item(address_change.validator_index).withdrawal_credentials - - if not (withdrawal_credentials.data[0] == BLS_WITHDRAWAL_PREFIX): - return err("process_bls_to_execution_change: invalid withdrawal prefix") - - # TODO what's usual convention here re 32 hardcoded constant? - if not (withdrawal_credentials.data.toOpenArray(1, 31) == - eth2digest(address_change.from_bls_pubkey.blob).data.toOpenArray(1, 31)): - return err("process_bls_to_execution_change: invalid withdrawal credentials") - - if not verify_bls_to_execution_change_signature( - state.fork, state.genesis_validators_root, state.get_current_epoch, - signed_address_change, address_change.from_bls_pubkey, - signed_address_change.signature): - return err("process_bls_to_execution_change: invalid signature") - - withdrawal_credentials.data[0] = ETH1_ADDRESS_WITHDRAWAL_PREFIX - withdrawal_credentials.data.fill(1, 11, 0) - withdrawal_credentials.data[12..31] = - address_change.to_execution_address.data - state.validators.mitem(address_change.validator_index).withdrawal_credentials = - withdrawal_credentials - - ok() - # https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.0/specs/capella/beacon-chain.md#new-process_withdrawals func process_withdrawals*( state: var capella.BeaconState, payload: capella.ExecutionPayload): @@ -686,6 +691,7 @@ proc process_block*( ok() +# https://github.com/ethereum/consensus-specs/blob/v1.2.0/specs/bellatrix/beacon-chain.md#block-processing # TODO workaround for https://github.com/nim-lang/Nim/issues/18095 type SomeBellatrixBlock = bellatrix.BeaconBlock | bellatrix.SigVerifiedBeaconBlock | bellatrix.TrustedBeaconBlock @@ -716,6 +722,7 @@ proc process_block*( ok() +# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.0/specs/capella/beacon-chain.md#block-processing # TODO workaround for https://github.com/nim-lang/Nim/issues/18095 type SomeCapellaBlock = capella.BeaconBlock | capella.SigVerifiedBeaconBlock | capella.TrustedBeaconBlock @@ -723,4 +730,26 @@ proc process_block*( cfg: RuntimeConfig, state: var capella.BeaconState, blck: SomeCapellaBlock, flags: UpdateFlags, cache: var StateCache): Result[void, cstring]= - raiseAssert $capellaImplementationMissing + ## When there's a new block, we need to verify that the block is sane and + ## update the state accordingly - the state is left in an unknown state when + ## block application fails (!) + + ? process_block_header(state, blck, flags, cache) + if is_execution_enabled(state, blck.body): + ? process_withdrawals(state, blck.body.execution_payload) # [New in Capella] + ? process_execution_payload( + state, blck.body.execution_payload, + func(_: capella.ExecutionPayload): bool = true) + ? process_randao(state, blck.body, flags, cache) + ? process_eth1_data(state, blck.body) + + let + total_active_balance = get_total_active_balance(state, cache) + base_reward_per_increment = + get_base_reward_per_increment(total_active_balance) + ? process_operations( + cfg, state, blck.body, base_reward_per_increment, flags, cache) + ? process_sync_aggregate( + state, blck.body.sync_aggregate, total_active_balance, cache) + + ok() diff --git a/tests/consensus_spec/capella/all_capella_fixtures.nim b/tests/consensus_spec/capella/all_capella_fixtures.nim index 99f1c8962..e21ec0441 100644 --- a/tests/consensus_spec/capella/all_capella_fixtures.nim +++ b/tests/consensus_spec/capella/all_capella_fixtures.nim @@ -10,7 +10,7 @@ import ./test_fixture_fork, ./test_fixture_operations, - #./test_fixture_sanity_blocks, # TODO needs forked + ./test_fixture_sanity_blocks, #./test_fixture_sanity_slots, # TODO needs forked ./test_fixture_ssz_consensus_objects, ./test_fixture_state_transition_epoch diff --git a/tests/consensus_spec/capella/test_fixture_sanity_blocks.nim b/tests/consensus_spec/capella/test_fixture_sanity_blocks.nim new file mode 100644 index 000000000..c691e884c --- /dev/null +++ b/tests/consensus_spec/capella/test_fixture_sanity_blocks.nim @@ -0,0 +1,88 @@ +# beacon_chain +# Copyright (c) 2022 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, sequtils], + # Nimble + chronicles, + # Beacon chain internals + ../../../beacon_chain/spec/[forks, state_transition], + ../../../beacon_chain/spec/datatypes/capella, + # Test utilities + ../../testutil, + ../../helpers/debug_state, + ../fixtures_utils + +const + FinalityDir = SszTestsDir/const_preset/"capella"/"finality"/"finality"/"pyspec_tests" + RandomDir = SszTestsDir/const_preset/"capella"/"random"/"random"/"pyspec_tests" + SanityBlocksDir = SszTestsDir/const_preset/"capella"/"sanity"/"blocks"/"pyspec_tests" + +proc runTest(testName, testDir, unitTestName: string) = + let testPath = testDir / unitTestName + + proc `testImpl _ blck _ testName`() = + let + hasPostState = fileExists(testPath/"post.ssz_snappy") + prefix = if hasPostState: "[Valid] " else: "[Invalid] " + + test prefix & testName & " - " & unitTestName & preset(): + var + preState = newClone(parseTest( + testPath/"pre.ssz_snappy", SSZ, capella.BeaconState)) + fhPreState = (ref ForkedHashedBeaconState)( + capellaData: capella.HashedBeaconState( + data: preState[], root: hash_tree_root(preState[])), + kind: BeaconStateFork.Capella) + cache = StateCache() + info = ForkedEpochInfo() + + # In test cases with more than 10 blocks the first 10 aren't 0-prefixed, + # so purely lexicographic sorting wouldn't sort properly. + let numBlocks = toSeq(walkPattern(testPath/"blocks_*.ssz_snappy")).len + if numBlocks > 1: + return + for i in 0 ..< numBlocks: + let blck = parseTest( + testPath/"blocks_" & $i & ".ssz_snappy", SSZ, + capella.SignedBeaconBlock) + + if hasPostState: + let res = state_transition( + defaultRuntimeConfig, fhPreState[], blck, cache, info, flags = {}, + noRollback) + res.expect("no failure when applying block " & $i) + else: + let res = state_transition( + defaultRuntimeConfig, fhPreState[], blck, cache, info, flags = {}, + noRollback) + doAssert (i + 1 < numBlocks) or not res.isOk, + "We didn't expect these invalid blocks to be processed" + + if hasPostState: + let postState = newClone(parseTest( + testPath/"post.ssz_snappy", SSZ, capella.BeaconState)) + when false: + reportDiff(fhPreState.capellaData.data, postState) + doAssert getStateRoot(fhPreState[]) == postState[].hash_tree_root() + + `testImpl _ blck _ testName`() + +suite "EF - Capella - Sanity - Blocks " & preset(): + for kind, path in walkDir(SanityBlocksDir, relative = true, checkDir = true): + runTest("EF - Capella - Sanity - Blocks", SanityBlocksDir, path) + +suite "EF - Capella - Random " & preset(): + for kind, path in walkDir(RandomDir, relative = true, checkDir = true): + runTest("EF - Capella - Random", RandomDir, path) + +suite "EF - Capella - Finality " & preset(): + for kind, path in walkDir(FinalityDir, relative = true, checkDir = true): + runTest("EF - Capella - Finality", FinalityDir, path)