From 0fab9682a6029b95ebd900144a7eb67b5c9ec881 Mon Sep 17 00:00:00 2001 From: tersec Date: Sat, 15 Jun 2024 22:15:27 +0000 Subject: [PATCH 01/68] use EF consensus-specs v1.5.0-alpha.3 test vectors (#6362) --- ConsensusSpecPreset-mainnet.md | 96 +++--- ConsensusSpecPreset-minimal.md | 154 ++++----- beacon_chain/beacon_chain_db_immutable.nim | 2 +- beacon_chain/el/el_manager.nim | 32 +- beacon_chain/spec/beaconstate.nim | 161 +++++++-- beacon_chain/spec/datatypes/base.nim | 2 +- beacon_chain/spec/datatypes/constants.nim | 4 +- beacon_chain/spec/datatypes/electra.nim | 57 ++-- .../eth2_apis/eth2_rest_serialization.nim | 7 +- beacon_chain/spec/mev/electra_mev.nim | 12 +- .../spec/presets/gnosis/electra_preset.nim | 8 +- .../spec/presets/mainnet/electra_preset.nim | 8 +- .../spec/presets/minimal/electra_preset.nim | 4 +- beacon_chain/spec/signatures.nim | 20 -- beacon_chain/spec/state_transition.nim | 29 +- beacon_chain/spec/state_transition_block.nim | 177 +++++----- beacon_chain/spec/state_transition_epoch.nim | 44 ++- beacon_chain/spec/validator.nim | 8 +- beacon_chain/validators/beacon_validators.nim | 2 - .../validators/message_router_mev.nim | 3 +- research/block_sim.nim | 4 +- research/wss_sim.nim | 1 - scripts/test_merge_node.nim | 68 ---- .../electra/test_fixture_operations.nim | 84 +++-- .../test_fixture_ssz_consensus_objects.nim | 8 +- tests/test_el_manager.nim | 314 +++++++++--------- tests/testblockutil.nim | 1 - vendor/nim-eth2-scenarios | 2 +- 28 files changed, 671 insertions(+), 641 deletions(-) delete mode 100644 scripts/test_merge_node.nim diff --git a/ConsensusSpecPreset-mainnet.md b/ConsensusSpecPreset-mainnet.md index 542a6f090..9f7b5a296 100644 --- a/ConsensusSpecPreset-mainnet.md +++ b/ConsensusSpecPreset-mainnet.md @@ -2468,14 +2468,20 @@ OK: 10/10 Fail: 0/10 Skip: 0/10 OK: 10/10 Fail: 0/10 Skip: 0/10 ## EF - Electra - Epoch Processing - Pending balance deposits [Preset: mainnet] ```diff ++ Pending balance deposits - mixture_of_skipped_and_above_churn [Preset: mainnet] OK + Pending balance deposits - multiple_pending_deposits_above_churn [Preset: mainnet] OK + Pending balance deposits - multiple_pending_deposits_below_churn [Preset: mainnet] OK ++ Pending balance deposits - multiple_pending_one_skipped [Preset: mainnet] OK ++ Pending balance deposits - multiple_skipped_deposits_exiting_validators [Preset: mainnet] OK + Pending balance deposits - pending_deposit_balance_above_churn [Preset: mainnet] OK + Pending balance deposits - pending_deposit_balance_equal_churn [Preset: mainnet] OK + Pending balance deposits - pending_deposit_min_activation_balance [Preset: mainnet] OK + Pending balance deposits - pending_deposit_preexisting_churn [Preset: mainnet] OK ++ Pending balance deposits - processing_deposit_of_withdrawable_validator [Preset: mainnet] OK ++ Pending balance deposits - processing_deposit_of_withdrawable_validator_does_not_get_churn OK ++ Pending balance deposits - skipped_deposit_exiting_validator [Preset: mainnet] OK ``` -OK: 6/6 Fail: 0/6 Skip: 0/6 +OK: 12/12 Fail: 0/12 Skip: 0/12 ## EF - Electra - Epoch Processing - Pending consolidations [Preset: mainnet] ```diff + Pending consolidations - all_consolidation_cases_together [Preset: mainnet] OK @@ -2673,6 +2679,11 @@ OK: 14/14 Fail: 0/14 Skip: 0/14 + [Valid] EF - Electra - Operations - Block Header - basic_block_header OK ``` OK: 6/6 Fail: 0/6 Skip: 0/6 +## EF - Electra - Operations - Consolidation Request [Preset: mainnet] +```diff ++ [Valid] EF - Electra - Operations - Consolidation Request - incorrect_not_enough_consoli OK +``` +OK: 1/1 Fail: 0/1 Skip: 0/1 ## EF - Electra - Operations - Deposit [Preset: mainnet] ```diff + [Invalid] EF - Electra - Operations - Deposit - invalid_bad_merkle_proof OK @@ -2698,45 +2709,27 @@ OK: 6/6 Fail: 0/6 Skip: 0/6 + [Valid] EF - Electra - Operations - Deposit - top_up__zero_balance OK ``` OK: 21/21 Fail: 0/21 Skip: 0/21 -## EF - Electra - Operations - Deposit Receipt [Preset: mainnet] +## EF - Electra - Operations - Deposit Request [Preset: mainnet] ```diff -+ [Valid] EF - Electra - Operations - Deposit Receipt - correct_sig_but_forked_state OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - effective_deposit_with_genesis_for OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - incorrect_sig_new_deposit OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - incorrect_sig_top_up OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - incorrect_withdrawal_credentials_t OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - ineffective_deposit_with_previous_ OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - key_validate_invalid_decompression OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - key_validate_invalid_subgroup OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - new_deposit_eth1_withdrawal_creden OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - new_deposit_max OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - new_deposit_non_versioned_withdraw OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - new_deposit_over_max OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - new_deposit_under_max OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - success_top_up_to_withdrawn_valida OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - top_up__less_effective_balance OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - top_up__max_effective_balance OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - top_up__zero_balance OK ++ [Valid] EF - Electra - Operations - Deposit Request - correct_sig_but_forked_state OK ++ [Valid] EF - Electra - Operations - Deposit Request - effective_deposit_with_genesis_for OK ++ [Valid] EF - Electra - Operations - Deposit Request - incorrect_sig_new_deposit OK ++ [Valid] EF - Electra - Operations - Deposit Request - incorrect_sig_top_up OK ++ [Valid] EF - Electra - Operations - Deposit Request - incorrect_withdrawal_credentials_t OK ++ [Valid] EF - Electra - Operations - Deposit Request - ineffective_deposit_with_previous_ OK ++ [Valid] EF - Electra - Operations - Deposit Request - key_validate_invalid_decompression OK ++ [Valid] EF - Electra - Operations - Deposit Request - key_validate_invalid_subgroup OK ++ [Valid] EF - Electra - Operations - Deposit Request - new_deposit_eth1_withdrawal_creden OK ++ [Valid] EF - Electra - Operations - Deposit Request - new_deposit_max OK ++ [Valid] EF - Electra - Operations - Deposit Request - new_deposit_non_versioned_withdraw OK ++ [Valid] EF - Electra - Operations - Deposit Request - new_deposit_over_max OK ++ [Valid] EF - Electra - Operations - Deposit Request - new_deposit_under_max OK ++ [Valid] EF - Electra - Operations - Deposit Request - success_top_up_to_withdrawn_valida OK ++ [Valid] EF - Electra - Operations - Deposit Request - top_up__less_effective_balance OK ++ [Valid] EF - Electra - Operations - Deposit Request - top_up__max_effective_balance OK ++ [Valid] EF - Electra - Operations - Deposit Request - top_up__zero_balance OK ``` OK: 17/17 Fail: 0/17 Skip: 0/17 -## EF - Electra - Operations - Execution Layer Withdrawal Request [Preset: mainnet] -```diff -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - activation_epoc OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - basic_withdrawa OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - basic_withdrawa OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - incorrect_sourc OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - incorrect_withd OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - insufficient_ef OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - no_compounding_ OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - no_excess_balan OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - on_withdrawal_r OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - partial_withdra OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - partial_withdra OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - partial_withdra OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - partial_withdra OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - pending_withdra OK -``` -OK: 14/14 Fail: 0/14 Skip: 0/14 ## EF - Electra - Operations - Execution Payload [Preset: mainnet] ```diff + [Invalid] EF - Electra - Operations - Execution Payload - invalid_bad_everything_first_pay OK @@ -2856,6 +2849,24 @@ OK: 26/26 Fail: 0/26 Skip: 0/26 + [Valid] EF - Electra - Operations - Voluntary Exit - success_exit_queue__min_churn OK ``` OK: 24/24 Fail: 0/24 Skip: 0/24 +## EF - Electra - Operations - Withdrawal Request [Preset: mainnet] +```diff ++ [Valid] EF - Electra - Operations - Withdrawal Request - activation_epoch_less_than_shar OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request_with_c OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - incorrect_source_address OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - incorrect_withdrawal_credential OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - insufficient_effective_balance OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - no_compounding_credentials OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - no_excess_balance OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - on_withdrawal_request_initiated OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_activation_e OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_incorrect_so OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_incorrect_wi OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_on_exit_init OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - pending_withdrawals_consume_all OK +``` +OK: 14/14 Fail: 0/14 Skip: 0/14 ## EF - Electra - Operations - Withdrawals [Preset: mainnet] ```diff + [Invalid] EF - Electra - Operations - Withdrawals - invalid_a_lot_fully_withdrawable_too_f OK @@ -2982,15 +2993,14 @@ OK: 34/34 Fail: 0/34 Skip: 0/34 + Testing BlobIdentifier OK + Testing BlobSidecar OK + Testing Checkpoint OK -+ Testing Consolidation OK ++ Testing ConsolidationRequest OK + Testing ContributionAndProof OK + Testing Deposit OK + Testing DepositData OK + Testing DepositMessage OK -+ Testing DepositReceipt OK ++ Testing DepositRequest OK + Testing Eth1Block OK + Testing Eth1Data OK -+ Testing ExecutionLayerWithdrawalRequest OK + Testing ExecutionPayload OK + Testing ExecutionPayloadHeader OK + Testing Fork OK @@ -3013,7 +3023,6 @@ OK: 34/34 Fail: 0/34 Skip: 0/34 + Testing SignedBLSToExecutionChange OK + Testing SignedBeaconBlock OK + Testing SignedBeaconBlockHeader OK -+ Testing SignedConsolidation OK + Testing SignedContributionAndProof OK + Testing SignedVoluntaryExit OK + Testing SigningData OK @@ -3025,8 +3034,9 @@ OK: 34/34 Fail: 0/34 Skip: 0/34 + Testing Validator OK + Testing VoluntaryExit OK + Testing Withdrawal OK ++ Testing WithdrawalRequest OK ``` -OK: 55/55 Fail: 0/55 Skip: 0/55 +OK: 54/54 Fail: 0/54 Skip: 0/54 ## EF - Electra - Sanity - Blocks [Preset: mainnet] ```diff + [Invalid] EF - Electra - Sanity - Blocks - deposit_transition__invalid_eth1_deposits_overl OK @@ -3675,4 +3685,4 @@ OK: 69/88 Fail: 0/88 Skip: 19/88 OK: 3/3 Fail: 0/3 Skip: 0/3 ---TOTAL--- -OK: 2961/2981 Fail: 0/2981 Skip: 20/2981 +OK: 2967/2987 Fail: 0/2987 Skip: 20/2987 diff --git a/ConsensusSpecPreset-minimal.md b/ConsensusSpecPreset-minimal.md index edd1c355a..e0cfad762 100644 --- a/ConsensusSpecPreset-minimal.md +++ b/ConsensusSpecPreset-minimal.md @@ -2579,14 +2579,20 @@ OK: 10/10 Fail: 0/10 Skip: 0/10 OK: 12/12 Fail: 0/12 Skip: 0/12 ## EF - Electra - Epoch Processing - Pending balance deposits [Preset: minimal] ```diff ++ Pending balance deposits - mixture_of_skipped_and_above_churn [Preset: minimal] OK + Pending balance deposits - multiple_pending_deposits_above_churn [Preset: minimal] OK + Pending balance deposits - multiple_pending_deposits_below_churn [Preset: minimal] OK ++ Pending balance deposits - multiple_pending_one_skipped [Preset: minimal] OK ++ Pending balance deposits - multiple_skipped_deposits_exiting_validators [Preset: minimal] OK + Pending balance deposits - pending_deposit_balance_above_churn [Preset: minimal] OK + Pending balance deposits - pending_deposit_balance_equal_churn [Preset: minimal] OK + Pending balance deposits - pending_deposit_min_activation_balance [Preset: minimal] OK + Pending balance deposits - pending_deposit_preexisting_churn [Preset: minimal] OK ++ Pending balance deposits - processing_deposit_of_withdrawable_validator [Preset: minimal] OK ++ Pending balance deposits - processing_deposit_of_withdrawable_validator_does_not_get_churn OK ++ Pending balance deposits - skipped_deposit_exiting_validator [Preset: minimal] OK ``` -OK: 6/6 Fail: 0/6 Skip: 0/6 +OK: 12/12 Fail: 0/12 Skip: 0/12 ## EF - Electra - Epoch Processing - Pending consolidations [Preset: minimal] ```diff + Pending consolidations - all_consolidation_cases_together [Preset: minimal] OK @@ -2802,29 +2808,30 @@ OK: 14/14 Fail: 0/14 Skip: 0/14 + [Valid] EF - Electra - Operations - Block Header - basic_block_header OK ``` OK: 6/6 Fail: 0/6 Skip: 0/6 -## EF - Electra - Operations - Consolidation [Preset: minimal] +## EF - Electra - Operations - Consolidation Request [Preset: minimal] ```diff -+ [Invalid] EF - Electra - Operations - Consolidation - invalid_before_specified_epoch OK -+ [Invalid] EF - Electra - Operations - Consolidation - invalid_different_credentials OK -+ [Invalid] EF - Electra - Operations - Consolidation - invalid_exited_source OK -+ [Invalid] EF - Electra - Operations - Consolidation - invalid_exited_target OK -+ [Invalid] EF - Electra - Operations - Consolidation - invalid_inactive_source OK -+ [Invalid] EF - Electra - Operations - Consolidation - invalid_inactive_target OK -+ [Invalid] EF - Electra - Operations - Consolidation - invalid_no_execution_withdrawal_cred OK -+ [Invalid] EF - Electra - Operations - Consolidation - invalid_not_enough_consolidation_chu OK -+ [Invalid] EF - Electra - Operations - Consolidation - invalid_source_equals_target OK -+ [Invalid] EF - Electra - Operations - Consolidation - invalid_source_signature OK -+ [Invalid] EF - Electra - Operations - Consolidation - invalid_target_signature OK -+ [Valid] EF - Electra - Operations - Consolidation - basic_consolidation_in_current_conso OK -+ [Valid] EF - Electra - Operations - Consolidation - basic_consolidation_in_new_consolida OK -+ [Valid] EF - Electra - Operations - Consolidation - basic_consolidation_with_compounding OK -+ [Valid] EF - Electra - Operations - Consolidation - basic_consolidation_with_insufficien OK -+ [Valid] EF - Electra - Operations - Consolidation - basic_consolidation_with_preexisting OK -+ [Valid] EF - Electra - Operations - Consolidation - consolidation_balance_larger_than_ch OK -+ [Valid] EF - Electra - Operations - Consolidation - consolidation_balance_through_two_ch OK -+ [Valid] EF - Electra - Operations - Consolidation - consolidation_churn_limit_balance OK ++ [Valid] EF - Electra - Operations - Consolidation Request - basic_consolidation_in_curre OK ++ [Valid] EF - Electra - Operations - Consolidation Request - basic_consolidation_in_new_c OK ++ [Valid] EF - Electra - Operations - Consolidation Request - basic_consolidation_with_com OK ++ [Valid] EF - Electra - Operations - Consolidation Request - basic_consolidation_with_ins OK ++ [Valid] EF - Electra - Operations - Consolidation Request - basic_consolidation_with_pre OK ++ [Valid] EF - Electra - Operations - Consolidation Request - consolidation_balance_larger OK ++ [Valid] EF - Electra - Operations - Consolidation Request - consolidation_balance_throug OK ++ [Valid] EF - Electra - Operations - Consolidation Request - consolidation_churn_limit_ba OK ++ [Valid] EF - Electra - Operations - Consolidation Request - incorrect_exceed_pending_con OK ++ [Valid] EF - Electra - Operations - Consolidation Request - incorrect_exited_source OK ++ [Valid] EF - Electra - Operations - Consolidation Request - incorrect_exited_target OK ++ [Valid] EF - Electra - Operations - Consolidation Request - incorrect_inactive_source OK ++ [Valid] EF - Electra - Operations - Consolidation Request - incorrect_inactive_target OK ++ [Valid] EF - Electra - Operations - Consolidation Request - incorrect_incorrect_source_a OK ++ [Valid] EF - Electra - Operations - Consolidation Request - incorrect_no_source_executio OK ++ [Valid] EF - Electra - Operations - Consolidation Request - incorrect_no_target_executio OK ++ [Valid] EF - Electra - Operations - Consolidation Request - incorrect_not_enough_consoli OK ++ [Valid] EF - Electra - Operations - Consolidation Request - incorrect_source_equals_targ OK ++ [Valid] EF - Electra - Operations - Consolidation Request - incorrect_unknown_source_pub OK ++ [Valid] EF - Electra - Operations - Consolidation Request - incorrect_unknown_target_pub OK ``` -OK: 19/19 Fail: 0/19 Skip: 0/19 +OK: 20/20 Fail: 0/20 Skip: 0/20 ## EF - Electra - Operations - Deposit [Preset: minimal] ```diff + [Invalid] EF - Electra - Operations - Deposit - invalid_bad_merkle_proof OK @@ -2850,55 +2857,27 @@ OK: 19/19 Fail: 0/19 Skip: 0/19 + [Valid] EF - Electra - Operations - Deposit - top_up__zero_balance OK ``` OK: 21/21 Fail: 0/21 Skip: 0/21 -## EF - Electra - Operations - Deposit Receipt [Preset: minimal] +## EF - Electra - Operations - Deposit Request [Preset: minimal] ```diff -+ [Valid] EF - Electra - Operations - Deposit Receipt - correct_sig_but_forked_state OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - effective_deposit_with_genesis_for OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - incorrect_sig_new_deposit OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - incorrect_sig_top_up OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - incorrect_withdrawal_credentials_t OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - ineffective_deposit_with_previous_ OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - key_validate_invalid_decompression OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - key_validate_invalid_subgroup OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - new_deposit_eth1_withdrawal_creden OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - new_deposit_max OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - new_deposit_non_versioned_withdraw OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - new_deposit_over_max OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - new_deposit_under_max OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - success_top_up_to_withdrawn_valida OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - top_up__less_effective_balance OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - top_up__max_effective_balance OK -+ [Valid] EF - Electra - Operations - Deposit Receipt - top_up__zero_balance OK ++ [Valid] EF - Electra - Operations - Deposit Request - correct_sig_but_forked_state OK ++ [Valid] EF - Electra - Operations - Deposit Request - effective_deposit_with_genesis_for OK ++ [Valid] EF - Electra - Operations - Deposit Request - incorrect_sig_new_deposit OK ++ [Valid] EF - Electra - Operations - Deposit Request - incorrect_sig_top_up OK ++ [Valid] EF - Electra - Operations - Deposit Request - incorrect_withdrawal_credentials_t OK ++ [Valid] EF - Electra - Operations - Deposit Request - ineffective_deposit_with_previous_ OK ++ [Valid] EF - Electra - Operations - Deposit Request - key_validate_invalid_decompression OK ++ [Valid] EF - Electra - Operations - Deposit Request - key_validate_invalid_subgroup OK ++ [Valid] EF - Electra - Operations - Deposit Request - new_deposit_eth1_withdrawal_creden OK ++ [Valid] EF - Electra - Operations - Deposit Request - new_deposit_max OK ++ [Valid] EF - Electra - Operations - Deposit Request - new_deposit_non_versioned_withdraw OK ++ [Valid] EF - Electra - Operations - Deposit Request - new_deposit_over_max OK ++ [Valid] EF - Electra - Operations - Deposit Request - new_deposit_under_max OK ++ [Valid] EF - Electra - Operations - Deposit Request - success_top_up_to_withdrawn_valida OK ++ [Valid] EF - Electra - Operations - Deposit Request - top_up__less_effective_balance OK ++ [Valid] EF - Electra - Operations - Deposit Request - top_up__max_effective_balance OK ++ [Valid] EF - Electra - Operations - Deposit Request - top_up__zero_balance OK ``` OK: 17/17 Fail: 0/17 Skip: 0/17 -## EF - Electra - Operations - Execution Layer Withdrawal Request [Preset: minimal] -```diff -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - activation_epoc OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - basic_partial_w OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - basic_partial_w OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - basic_partial_w OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - basic_withdrawa OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - basic_withdrawa OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - basic_withdrawa OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - incorrect_sourc OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - incorrect_withd OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - insufficient_ef OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - no_compounding_ OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - no_excess_balan OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - on_withdrawal_r OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - partial_withdra OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - partial_withdra OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - partial_withdra OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - partial_withdra OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - partial_withdra OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - partial_withdra OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - partial_withdra OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - partial_withdra OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - partial_withdra OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - partial_withdra OK -+ [Valid] EF - Electra - Operations - Execution Layer Withdrawal Request - pending_withdra OK -``` -OK: 24/24 Fail: 0/24 Skip: 0/24 ## EF - Electra - Operations - Execution Payload [Preset: minimal] ```diff + [Invalid] EF - Electra - Operations - Execution Payload - invalid_bad_everything_first_pay OK @@ -3012,6 +2991,34 @@ OK: 24/24 Fail: 0/24 Skip: 0/24 + [Valid] EF - Electra - Operations - Voluntary Exit - success_exit_queue__scaled_churn OK ``` OK: 20/20 Fail: 0/20 Skip: 0/20 +## EF - Electra - Operations - Withdrawal Request [Preset: minimal] +```diff ++ [Valid] EF - Electra - Operations - Withdrawal Request - activation_epoch_less_than_shar OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - basic_partial_withdrawal_reques OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - basic_partial_withdrawal_reques OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - basic_partial_withdrawal_reques OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request_with_c OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request_with_f OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - incorrect_source_address OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - incorrect_withdrawal_credential OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - insufficient_effective_balance OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - no_compounding_credentials OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - no_excess_balance OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - on_withdrawal_request_initiated OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_activation_e OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_incorrect_so OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_incorrect_wi OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_on_exit_init OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_queue_full OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_request_with OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_request_with OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_request_with OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_request_with OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_request_with OK ++ [Valid] EF - Electra - Operations - Withdrawal Request - pending_withdrawals_consume_all OK +``` +OK: 24/24 Fail: 0/24 Skip: 0/24 ## EF - Electra - Operations - Withdrawals [Preset: minimal] ```diff + [Invalid] EF - Electra - Operations - Withdrawals - invalid_a_lot_fully_withdrawable_too_f OK @@ -3139,15 +3146,14 @@ OK: 34/34 Fail: 0/34 Skip: 0/34 + Testing BlobIdentifier OK + Testing BlobSidecar OK + Testing Checkpoint OK -+ Testing Consolidation OK ++ Testing ConsolidationRequest OK + Testing ContributionAndProof OK + Testing Deposit OK + Testing DepositData OK + Testing DepositMessage OK -+ Testing DepositReceipt OK ++ Testing DepositRequest OK + Testing Eth1Block OK + Testing Eth1Data OK -+ Testing ExecutionLayerWithdrawalRequest OK + Testing ExecutionPayload OK + Testing ExecutionPayloadHeader OK + Testing Fork OK @@ -3170,7 +3176,6 @@ OK: 34/34 Fail: 0/34 Skip: 0/34 + Testing SignedBLSToExecutionChange OK + Testing SignedBeaconBlock OK + Testing SignedBeaconBlockHeader OK -+ Testing SignedConsolidation OK + Testing SignedContributionAndProof OK + Testing SignedVoluntaryExit OK + Testing SigningData OK @@ -3182,8 +3187,9 @@ OK: 34/34 Fail: 0/34 Skip: 0/34 + Testing Validator OK + Testing VoluntaryExit OK + Testing Withdrawal OK ++ Testing WithdrawalRequest OK ``` -OK: 55/55 Fail: 0/55 Skip: 0/55 +OK: 54/54 Fail: 0/54 Skip: 0/54 ## EF - Electra - Sanity - Blocks [Preset: minimal] ```diff + [Invalid] EF - Electra - Sanity - Blocks - deposit_transition__invalid_eth1_deposits_overl OK @@ -4005,4 +4011,4 @@ OK: 185/207 Fail: 0/207 Skip: 22/207 OK: 3/3 Fail: 0/3 Skip: 0/3 ---TOTAL--- -OK: 3256/3279 Fail: 0/3279 Skip: 23/3279 +OK: 3262/3285 Fail: 0/3285 Skip: 23/3285 diff --git a/beacon_chain/beacon_chain_db_immutable.nim b/beacon_chain/beacon_chain_db_immutable.nim index 20f71abdd..4821ba304 100644 --- a/beacon_chain/beacon_chain_db_immutable.nim +++ b/beacon_chain/beacon_chain_db_immutable.nim @@ -401,7 +401,7 @@ type historical_summaries*: HashList[HistoricalSummary, Limit HISTORICAL_ROOTS_LIMIT] - deposit_receipts_start_index*: uint64 # [New in Electra:EIP6110] + deposit_requests_start_index*: uint64 # [New in Electra:EIP6110] deposit_balance_to_consume*: Gwei # [New in Electra:EIP7251] exit_balance_to_consume*: Gwei # [New in Electra:EIP7251] earliest_exit_epoch*: Epoch # [New in Electra:EIP7251] diff --git a/beacon_chain/el/el_manager.nim b/beacon_chain/el/el_manager.nim index d2e754c87..20650b6fd 100644 --- a/beacon_chain/el/el_manager.nim +++ b/beacon_chain/el/el_manager.nim @@ -502,8 +502,8 @@ func asConsensusType*(rpcExecutionPayload: ExecutionPayloadV4): template getTransaction(tt: TypedTransaction): bellatrix.Transaction = bellatrix.Transaction.init(tt.distinctBase) - template getDepositReceipt(dr: DepositReceiptV1): DepositReceipt = - DepositReceipt( + template getDepositRequest(dr: DepositReceiptV1): DepositRequest = + DepositRequest( pubkey: ValidatorPubKey(blob: dr.pubkey.distinctBase), withdrawal_credentials: dr.withdrawalCredentials.asEth2Digest, amount: dr.amount.Gwei, @@ -511,8 +511,8 @@ func asConsensusType*(rpcExecutionPayload: ExecutionPayloadV4): index: dr.index.uint64) template getExecutionLayerWithdrawalRequest(elwr: WithdrawalRequestV1): - ExecutionLayerWithdrawalRequest = - ExecutionLayerWithdrawalRequest( + WithdrawalRequest = + WithdrawalRequest( source_address: ExecutionAddress(data: elwr.sourceAddress.distinctBase), validator_pubkey: ValidatorPubKey( blob: elwr.validatorPublicKey.distinctBase), @@ -540,11 +540,11 @@ func asConsensusType*(rpcExecutionPayload: ExecutionPayloadV4): mapIt(rpcExecutionPayload.withdrawals, it.asConsensusWithdrawal)), blob_gas_used: rpcExecutionPayload.blobGasUsed.uint64, excess_blob_gas: rpcExecutionPayload.excessBlobGas.uint64, - deposit_receipts: - List[electra.DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init( - mapIt(rpcExecutionPayload.depositRequests, it.getDepositReceipt)), + deposit_requests: + List[electra.DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init( + mapIt(rpcExecutionPayload.depositRequests, it.getDepositRequest)), withdrawal_requests: - List[electra.ExecutionLayerWithdrawalRequest, + List[electra.WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init( mapIt(rpcExecutionPayload.withdrawalRequests, it.getExecutionLayerWithdrawalRequest))) @@ -647,7 +647,7 @@ func asEngineExecutionPayload*(executionPayload: electra.ExecutionPayload): template getTypedTransaction(tt: bellatrix.Transaction): TypedTransaction = TypedTransaction(tt.distinctBase) - template getDepositReceipt(dr: DepositReceipt): DepositReceiptV1 = + template getDepositRequest(dr: DepositRequest): DepositReceiptV1 = DepositReceiptV1( pubkey: FixedBytes[RawPubKeySize](dr.pubkey.blob), withdrawalCredentials: FixedBytes[32](dr.withdrawal_credentials.data), @@ -655,12 +655,11 @@ func asEngineExecutionPayload*(executionPayload: electra.ExecutionPayload): signature: FixedBytes[RawSigSize](dr.signature.blob), index: dr.index.Quantity) - template getExecutionLayerWithdrawalRequest( - elwr: ExecutionLayerWithdrawalRequest): WithdrawalRequestV1 = + template getWithdrawalRequest(wr: WithdrawalRequest): WithdrawalRequestV1 = WithdrawalRequestV1( - sourceAddress: Address(elwr.source_address.data), - validatorPublicKey: FixedBytes[RawPubKeySize](elwr.validator_pubkey.blob), - amount: elwr.amount.Quantity) + sourceAddress: Address(wr.source_address.data), + validatorPublicKey: FixedBytes[RawPubKeySize](wr.validator_pubkey.blob), + amount: wr.amount.Quantity) engine_api.ExecutionPayloadV4( parentHash: executionPayload.parent_hash.asBlockHash, @@ -682,10 +681,9 @@ func asEngineExecutionPayload*(executionPayload: electra.ExecutionPayload): blobGasUsed: Quantity(executionPayload.blob_gas_used), excessBlobGas: Quantity(executionPayload.excess_blob_gas), depositRequests: mapIt( - executionPayload.deposit_receipts, it.getDepositReceipt), + executionPayload.deposit_requests, it.getDepositRequest), withdrawalRequests: - mapIt(executionPayload.withdrawal_requests, - it.getExecutionLayerWithdrawalRequest)) + mapIt(executionPayload.withdrawal_requests, it.getWithdrawalRequest)) func isConnected(connection: ELConnection): bool = connection.web3.isSome diff --git a/beacon_chain/spec/beaconstate.nim b/beacon_chain/spec/beaconstate.nim index 51e7f4b11..8cf203124 100644 --- a/beacon_chain/spec/beaconstate.nim +++ b/beacon_chain/spec/beaconstate.nim @@ -1122,6 +1122,7 @@ proc process_attestation*( ok(proposer_reward) # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#get_next_sync_committee_indices +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#modified-get_next_sync_committee_indices func get_next_sync_committee_keys( state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState | electra.BeaconState): @@ -1153,8 +1154,13 @@ func get_next_sync_committee_keys( candidate_index = active_validator_indices[shuffled_index] random_byte = eth2digest(hash_buffer).data[i mod 32] effective_balance = state.validators[candidate_index].effective_balance - if effective_balance * MAX_RANDOM_BYTE >= - MAX_EFFECTIVE_BALANCE.Gwei * random_byte: + const meb = + when typeof(state).kind >= Electra: + MAX_EFFECTIVE_BALANCE_ELECTRA.Gwei # [Modified in Electra:EIP7251] + else: + MAX_EFFECTIVE_BALANCE.Gwei + + if effective_balance * MAX_RANDOM_BYTE >= meb * random_byte: res[index] = state.validators[candidate_index].pubkey inc index i += 1'u64 @@ -1165,24 +1171,6 @@ func has_eth1_withdrawal_credential*(validator: Validator): bool = ## Check if ``validator`` has an 0x01 prefixed "eth1" withdrawal credential. validator.withdrawal_credentials.data[0] == ETH1_ADDRESS_WITHDRAWAL_PREFIX -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#is_fully_withdrawable_validator -func is_fully_withdrawable_validator( - validator: Validator, balance: Gwei, epoch: Epoch): bool = - ## Check if ``validator`` is fully withdrawable. - has_eth1_withdrawal_credential(validator) and - validator.withdrawable_epoch <= epoch and balance > 0.Gwei - -# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#is_partially_withdrawable_validator -func is_partially_withdrawable_validator( - validator: Validator, balance: Gwei): bool = - ## Check if ``validator`` is partially withdrawable. - let - has_max_effective_balance = - validator.effective_balance == MAX_EFFECTIVE_BALANCE.Gwei - has_excess_balance = balance > MAX_EFFECTIVE_BALANCE.Gwei - has_eth1_withdrawal_credential(validator) and - has_max_effective_balance and has_excess_balance - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-is_compounding_withdrawal_credential func is_compounding_withdrawal_credential*( withdrawal_credentials: Eth2Digest): bool = @@ -1200,6 +1188,43 @@ func has_execution_withdrawal_credential*(validator: Validator): bool = has_compounding_withdrawal_credential(validator) or has_eth1_withdrawal_credential(validator) +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#is_fully_withdrawable_validator +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#updated-is_fully_withdrawable_validator +func is_fully_withdrawable_validator( + fork: static ConsensusFork, validator: Validator, balance: Gwei, + epoch: Epoch): bool = + ## Check if ``validator`` is fully withdrawable. + when fork >= ConsensusFork.Electra: + # [Modified in Electra:EIP7251] + has_execution_withdrawal_credential(validator) and + validator.withdrawable_epoch <= epoch and balance > 0.Gwei + else: + has_eth1_withdrawal_credential(validator) and + validator.withdrawable_epoch <= epoch and balance > 0.Gwei + +# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#is_partially_withdrawable_validator +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#updated-is_partially_withdrawable_validator +func is_partially_withdrawable_validator( + fork: static ConsensusFork, validator: Validator, balance: Gwei): bool = + ## Check if ``validator`` is partially withdrawable. + when fork >= ConsensusFork.Electra: + # [Modified in Electra:EIP7251] + let + max_effective_balance = get_validator_max_effective_balance(validator) + has_max_effective_balance = + validator.effective_balance == max_effective_balance + has_excess_balance = + balance > max_effective_balance # [Modified in Electra:EIP7251] + has_execution_withdrawal_credential(validator) and + has_max_effective_balance and has_excess_balance + else: + let + has_max_effective_balance = + validator.effective_balance == static(MAX_EFFECTIVE_BALANCE.Gwei) + has_excess_balance = balance > static(MAX_EFFECTIVE_BALANCE.Gwei) + has_eth1_withdrawal_credential(validator) and + has_max_effective_balance and has_excess_balance + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#get_validator_max_effective_balance func get_validator_max_effective_balance(validator: Validator): Gwei = ## Get max effective balance for ``validator``. @@ -1247,21 +1272,21 @@ func get_pending_balance_to_withdraw*( # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#new-get_expected_withdrawals func get_expected_withdrawals*( - state: capella.BeaconState | deneb.BeaconState | electra.BeaconState): - seq[Withdrawal] = + state: capella.BeaconState | deneb.BeaconState): seq[Withdrawal] = let epoch = get_current_epoch(state) num_validators = lenu64(state.validators) + bound = min(len(state.validators), MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP) var withdrawal_index = state.next_withdrawal_index validator_index = state.next_withdrawal_validator_index withdrawals: seq[Withdrawal] = @[] - bound = min(len(state.validators), MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP) for _ in 0 ..< bound: let validator = state.validators[validator_index] balance = state.balances[validator_index] - if is_fully_withdrawable_validator(validator, balance, epoch): + if is_fully_withdrawable_validator( + typeof(state).kind, validator, balance, epoch): var w = Withdrawal( index: withdrawal_index, validator_index: validator_index, @@ -1269,7 +1294,8 @@ func get_expected_withdrawals*( w.address.data[0..19] = validator.withdrawal_credentials.data[12..^1] withdrawals.add w withdrawal_index = WithdrawalIndex(withdrawal_index + 1) - elif is_partially_withdrawable_validator(validator, balance): + elif is_partially_withdrawable_validator( + typeof(state).kind, validator, balance): var w = Withdrawal( index: withdrawal_index, validator_index: validator_index, @@ -1282,6 +1308,82 @@ func get_expected_withdrawals*( validator_index = (validator_index + 1) mod num_validators withdrawals +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#updated-get_expected_withdrawals +# This partials count is used in exactly one place, while in general being able +# to cleanly treat the results of get_expected_withdrawals as a seq[Withdrawal] +# are valuable enough to make that the default version of this spec function. +func get_expected_withdrawals_with_partial_count*(state: electra.BeaconState): + (seq[Withdrawal], uint64) = + let epoch = get_current_epoch(state) + var + withdrawal_index = state.next_withdrawal_index + withdrawals: seq[Withdrawal] = @[] + + # [New in Electra:EIP7251] Consume pending partial withdrawals + for withdrawal in state.pending_partial_withdrawals: + if withdrawal.withdrawable_epoch > epoch or + len(withdrawals) == MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: + break + + let + validator = state.validators[withdrawal.index] + has_sufficient_effective_balance = + validator.effective_balance >= static(MIN_ACTIVATION_BALANCE.Gwei) + has_excess_balance = + state.balances[withdrawal.index] > static(MIN_ACTIVATION_BALANCE.Gwei) + if validator.exit_epoch == FAR_FUTURE_EPOCH and + has_sufficient_effective_balance and has_excess_balance: + let withdrawable_balance = min( + state.balances[withdrawal.index] - static(MIN_ACTIVATION_BALANCE.Gwei), + withdrawal.amount) + var w = Withdrawal( + index: withdrawal_index, + validator_index: withdrawal.index, + amount: withdrawable_balance) + w.address.data[0..19] = validator.withdrawal_credentials.data[12..^1] + withdrawals.add w + withdrawal_index += 1 + + let partial_withdrawals_count = lenu64(withdrawals) + + let + bound = min(len(state.validators), MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP) + num_validators = lenu64(state.validators) + var validator_index = state.next_withdrawal_validator_index + + # Sweep for remaining. + for _ in 0 ..< bound: + let + validator = state.validators[validator_index] + balance = state.balances[validator_index] + if is_fully_withdrawable_validator( + typeof(state).kind, validator, balance, epoch): + var w = Withdrawal( + index: withdrawal_index, + validator_index: validator_index, + amount: balance) + w.address.data[0..19] = validator.withdrawal_credentials.data[12..^1] + withdrawals.add w + withdrawal_index = WithdrawalIndex(withdrawal_index + 1) + elif is_partially_withdrawable_validator( + typeof(state).kind, validator, balance): + var w = Withdrawal( + index: withdrawal_index, + validator_index: validator_index, + # [Modified in Electra:EIP7251] + amount: balance - get_validator_max_effective_balance(validator)) + w.address.data[0..19] = validator.withdrawal_credentials.data[12..^1] + withdrawals.add w + withdrawal_index = WithdrawalIndex(withdrawal_index + 1) + if len(withdrawals) == MAX_WITHDRAWALS_PER_PAYLOAD: + break + validator_index = (validator_index + 1) mod num_validators + + (withdrawals, partial_withdrawals_count) + +func get_expected_withdrawals*(state: electra.BeaconState): seq[Withdrawal] = + get_expected_withdrawals_with_partial_count(state)[0] + # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#get_next_sync_committee func get_next_sync_committee*( state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState | @@ -1842,7 +1944,7 @@ func upgrade_to_deneb*(cfg: RuntimeConfig, pre: capella.BeaconState): historical_summaries: pre.historical_summaries ) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.1/specs/electra/fork.md#upgrading-the-state +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/fork.md#upgrading-the-state func upgrade_to_electra*( cfg: RuntimeConfig, pre: deneb.BeaconState, cache: var StateCache): ref electra.BeaconState = @@ -1866,8 +1968,9 @@ func upgrade_to_electra*( withdrawals_root: pre.latest_execution_payload_header.withdrawals_root, blob_gas_used: 0, excess_blob_gas: 0, - deposit_receipts_root: ZERO_HASH, # [New in Electra:EIP6110] - withdrawal_requests_root: ZERO_HASH, # [New in ELectra:EIP7002] + deposit_requests_root: ZERO_HASH, # [New in Electra:EIP6110] + withdrawal_requests_root: ZERO_HASH, # [New in Electra:EIP7002], + consolidation_requests_root: ZERO_HASH # [New in Electra:EIP7251] ) var max_exit_epoch = FAR_FUTURE_EPOCH @@ -1942,7 +2045,7 @@ func upgrade_to_electra*( historical_summaries: pre.historical_summaries, # [New in Electra:EIP6110] - deposit_receipts_start_index: UNSET_DEPOSIT_RECEIPTS_START_INDEX, + deposit_requests_start_index: UNSET_DEPOSIT_REQUESTS_START_INDEX, # [New in Electra:EIP7251] deposit_balance_to_consume: 0.Gwei, diff --git a/beacon_chain/spec/datatypes/base.nim b/beacon_chain/spec/datatypes/base.nim index 5dc1708d4..2c0249691 100644 --- a/beacon_chain/spec/datatypes/base.nim +++ b/beacon_chain/spec/datatypes/base.nim @@ -74,7 +74,7 @@ export tables, results, endians2, json_serialization, sszTypes, beacon_time, crypto, digest, presets -const SPEC_VERSION* = "1.5.0-alpha.2" +const SPEC_VERSION* = "1.5.0-alpha.3" ## Spec version we're aiming to be compatible with, right now const diff --git a/beacon_chain/spec/datatypes/constants.nim b/beacon_chain/spec/datatypes/constants.nim index 8e702dd38..1e0bb3e8d 100644 --- a/beacon_chain/spec/datatypes/constants.nim +++ b/beacon_chain/spec/datatypes/constants.nim @@ -83,8 +83,8 @@ const # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/p2p-interface.md#configuration MAX_REQUEST_BLOCKS_DENEB*: uint64 = 128 # TODO Make use of in request code - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#misc - UNSET_DEPOSIT_RECEIPTS_START_INDEX*: uint64 = not 0'u64 + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#misc + UNSET_DEPOSIT_REQUESTS_START_INDEX*: uint64 = not 0'u64 FULL_EXIT_REQUEST_AMOUNT*: uint64 = 0 # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#withdrawal-prefixes diff --git a/beacon_chain/spec/datatypes/electra.nim b/beacon_chain/spec/datatypes/electra.nim index c16a0257e..2326c88d6 100644 --- a/beacon_chain/spec/datatypes/electra.nim +++ b/beacon_chain/spec/datatypes/electra.nim @@ -49,8 +49,8 @@ const NEXT_SYNC_COMMITTEE_GINDEX = 87.GeneralizedIndex # next_sync_committee type - # https://github.com/ethereum/consensus-specs/blob/94a0b6c581f2809aa8aca4ef7ee6fbb63f9d74e9/specs/electra/beacon-chain.md#depositreceipt - DepositReceipt* = object + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#depositrequest + DepositRequest* = object pubkey*: ValidatorPubKey withdrawal_credentials*: Eth2Digest amount*: Gwei @@ -85,7 +85,7 @@ type attestation_1*: TrustedIndexedAttestation # Modified in Electra:EIP7549] attestation_2*: TrustedIndexedAttestation # Modified in Electra:EIP7549] - # https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#executionpayload + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#executionpayload ExecutionPayload* = object # Execution block header fields parent_hash*: Eth2Digest @@ -110,18 +110,21 @@ type withdrawals*: List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD] blob_gas_used*: uint64 excess_blob_gas*: uint64 - deposit_receipts*: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD] + deposit_requests*: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD] ## [New in Electra:EIP6110] withdrawal_requests*: - List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD] + List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD] ## [New in Electra:EIP6110] + consolidation_requests*: + List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD] + ## [New in Electra:EIP7251] ExecutionPayloadForSigning* = object executionPayload*: ExecutionPayload blockValue*: Wei blobsBundle*: BlobsBundle - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#executionpayloadheader + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#executionpayloadheader ExecutionPayloadHeader* = object # Execution block header fields parent_hash*: Eth2Digest @@ -144,8 +147,9 @@ type withdrawals_root*: Eth2Digest blob_gas_used*: uint64 excess_blob_gas*: uint64 - deposit_receipts_root*: Eth2Digest # [New in Electra:EIP6110] + deposit_requests_root*: Eth2Digest # [New in Electra:EIP6110] withdrawal_requests_root*: Eth2Digest # [New in Electra:EIP7002:EIP7251] + consolidation_requests_root*: Eth2Digest # [New in Electra:EIP7251] ExecutePayload* = proc( execution_payload: ExecutionPayload): bool {.gcsafe, raises: [].} @@ -162,31 +166,22 @@ type withdrawable_epoch*: Epoch # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/electra/beacon-chain.md#executionlayerwithdrawalrequest - ExecutionLayerWithdrawalRequest* = object + WithdrawalRequest* = object source_address*: ExecutionAddress validator_pubkey*: ValidatorPubKey amount*: Gwei - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/electra/beacon-chain.md#consolidation - Consolidation* = object - source_index*: uint64 - target_index*: uint64 - epoch*: Epoch - - # https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#signedconsolidation - SignedConsolidation* = object - message*: Consolidation - signature*: ValidatorSig - - TrustedSignedConsolidation* = object - message*: Consolidation - signature*: TrustedSig - # https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#pendingconsolidation PendingConsolidation* = object source_index*: uint64 target_index*: uint64 + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#consolidationrequest + ConsolidationRequest* = object + source_address*: ExecutionAddress + source_pubkey*: ValidatorPubKey + target_pubkey*: ValidatorPubKey + FinalityBranch = array[log2trunc(FINALIZED_ROOT_GINDEX), Eth2Digest] @@ -372,7 +367,7 @@ type historical_summaries*: HashList[HistoricalSummary, Limit HISTORICAL_ROOTS_LIMIT] - deposit_receipts_start_index*: uint64 # [New in Electra:EIP6110] + deposit_requests_start_index*: uint64 # [New in Electra:EIP6110] deposit_balance_to_consume*: Gwei # [New in Electra:EIP7251] exit_balance_to_consume*: Gwei # [New in Electra:EIP7251] earliest_exit_epoch*: Epoch # [New in Electra:EIP7251] @@ -457,7 +452,7 @@ type state_root*: Eth2Digest body*: TrustedBeaconBlockBody - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#beaconblockbody + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#beaconblockbody BeaconBlockBody* = object randao_reveal*: ValidatorSig eth1_data*: Eth1Data @@ -482,8 +477,6 @@ type execution_payload*: electra.ExecutionPayload # [Modified in Electra:EIP6110:EIP7002] bls_to_execution_changes*: SignedBLSToExecutionChangeList blob_kzg_commitments*: KzgCommitments - consolidations*: List[SignedConsolidation, Limit MAX_CONSOLIDATIONS] - ## [New in Electra:EIP7251] SigVerifiedBeaconBlockBody* = object ## A BeaconBlock body with signatures verified @@ -523,8 +516,6 @@ type execution_payload*: ExecutionPayload # [Modified in Electra:EIP6110:EIP7002] bls_to_execution_changes*: SignedBLSToExecutionChangeList blob_kzg_commitments*: KzgCommitments - consolidations*: List[TrustedSignedConsolidation, Limit MAX_CONSOLIDATIONS] - ## [New in Electra:EIP7251] TrustedBeaconBlockBody* = object ## A full verified block @@ -552,8 +543,6 @@ type execution_payload*: ExecutionPayload # [Modified in Electra:EIP6110:EIP7002] bls_to_execution_changes*: SignedBLSToExecutionChangeList blob_kzg_commitments*: KzgCommitments - consolidations*: List[TrustedSignedConsolidation, Limit MAX_CONSOLIDATIONS] - ## [New in Electra:EIP7251] # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#signedbeaconblock SignedBeaconBlock* = object @@ -598,12 +587,12 @@ type AttestationCommitteeBits* = BitArray[MAX_COMMITTEES_PER_SLOT.int] - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#attestation + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#attestation Attestation* = object aggregation_bits*: ElectraCommitteeValidatorsBits data*: AttestationData - committee_bits*: AttestationCommitteeBits # [New in Electra:EIP7549] signature*: ValidatorSig + committee_bits*: AttestationCommitteeBits # [New in Electra:EIP7549] TrustedAttestation* = object # The Trusted version, at the moment, implies that the cryptographic signature was checked. @@ -611,8 +600,8 @@ type # Currently the code MUST verify the state transition as soon as the signature is verified aggregation_bits*: ElectraCommitteeValidatorsBits data*: AttestationData - committee_bits*: AttestationCommitteeBits # [New in Electra:EIP7549] signature*: TrustedSig + committee_bits*: AttestationCommitteeBits # [New in Electra:EIP7549] SomeSignedBeaconBlock* = SignedBeaconBlock | diff --git a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim index e9d5edac5..13762ec7d 100644 --- a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim +++ b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim @@ -51,7 +51,7 @@ RestJson.useDefaultSerializationFor( BlobSidecarInfoObject, BlobsBundle, Checkpoint, - Consolidation, + ConsolidationRequest, ContributionAndProof, DataEnclosedObject, DataMetaEnclosedObject, @@ -65,14 +65,13 @@ RestJson.useDefaultSerializationFor( DenebSignedBlockContents, Deposit, DepositData, - DepositReceipt, + DepositRequest, DepositTreeSnapshot, DistributedKeystoreInfo, ElectraSignedBlockContents, EmptyBody, Eth1Data, EventBeaconBlockObject, - ExecutionLayerWithdrawalRequest, Fork, GetBlockAttestationsResponse, GetBlockHeaderResponse, @@ -169,7 +168,6 @@ RestJson.useDefaultSerializationFor( SetGraffitiRequest, SignedBLSToExecutionChange, SignedBeaconBlockHeader, - SignedConsolidation, SignedContributionAndProof, SignedValidatorRegistrationV1, SignedVoluntaryExit, @@ -194,6 +192,7 @@ RestJson.useDefaultSerializationFor( Web3SignerSyncCommitteeMessageData, Web3SignerValidatorRegistration, Withdrawal, + WithdrawalRequest, altair.BeaconBlock, altair.BeaconBlockBody, altair.BeaconState, diff --git a/beacon_chain/spec/mev/electra_mev.nim b/beacon_chain/spec/mev/electra_mev.nim index 994d07c07..08ec71e30 100644 --- a/beacon_chain/spec/mev/electra_mev.nim +++ b/beacon_chain/spec/mev/electra_mev.nim @@ -44,7 +44,6 @@ type List[SignedBLSToExecutionChange, Limit MAX_BLS_TO_EXECUTION_CHANGES] blob_kzg_commitments*: KzgCommitments # [New in Deneb] - consolidations*: List[SignedConsolidation, Limit MAX_CONSOLIDATIONS] # https://github.com/ethereum/builder-specs/blob/v0.4.0/specs/bellatrix/builder.md#blindedbeaconblock BlindedBeaconBlock* = object @@ -142,11 +141,12 @@ func toSignedBlindedBeaconBlock*(blck: electra.SignedBeaconBlock): hash_tree_root(blck.message.body.execution_payload.transactions), withdrawals_root: hash_tree_root(blck.message.body.execution_payload.withdrawals), - deposit_receipts_root: hash_tree_root( - blck.message.body.execution_payload.deposit_receipts), - withdrawal_requests_root: - hash_tree_root( - blck.message.body.execution_payload.withdrawal_requests)), + deposit_requests_root: hash_tree_root( + blck.message.body.execution_payload.deposit_requests), + withdrawal_requests_root: hash_tree_root( + blck.message.body.execution_payload.withdrawal_requests), + consolidation_requests_root: hash_tree_root( + blck.message.body.execution_payload.consolidation_requests)), bls_to_execution_changes: blck.message.body.bls_to_execution_changes, blob_kzg_commitments: blck.message.body.blob_kzg_commitments)), signature: blck.signature) diff --git a/beacon_chain/spec/presets/gnosis/electra_preset.nim b/beacon_chain/spec/presets/gnosis/electra_preset.nim index 7b81ad125..3719f8c74 100644 --- a/beacon_chain/spec/presets/gnosis/electra_preset.nim +++ b/beacon_chain/spec/presets/gnosis/electra_preset.nim @@ -8,7 +8,7 @@ {.push raises: [].} # Gnosis preset - Electra (Gnosis version not avilable yet; EF mainnet for now) -# https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/presets/mainnet/electra.yaml +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/presets/mainnet/electra.yaml const # Gwei values # --------------------------------------------------------------- @@ -40,12 +40,12 @@ const # `uint64(2**3)` (= 8) MAX_ATTESTATIONS_ELECTRA*: uint64 = 8 # `uint64(2**0)` (= 1) - MAX_CONSOLIDATIONS*: uint64 = 1 + MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD*: uint64 = 1 # Execution # --------------------------------------------------------------- - # 2**13 (= 8192) receipts - MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD* = 8192 + # 2**13 (= 8192) deposit requests + MAX_DEPOSIT_REQUESTS_PER_PAYLOAD* = 8192 # 2**4 (= 16) withdrawal requests MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD* = 16 diff --git a/beacon_chain/spec/presets/mainnet/electra_preset.nim b/beacon_chain/spec/presets/mainnet/electra_preset.nim index 31f991de8..52c88c998 100644 --- a/beacon_chain/spec/presets/mainnet/electra_preset.nim +++ b/beacon_chain/spec/presets/mainnet/electra_preset.nim @@ -8,7 +8,7 @@ {.push raises: [].} # Electra preset - Electra -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/presets/mainnet/electra.yaml +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/presets/mainnet/electra.yaml const # Gwei values # --------------------------------------------------------------- @@ -40,12 +40,12 @@ const # `uint64(2**3)` (= 8) MAX_ATTESTATIONS_ELECTRA*: uint64 = 8 # `uint64(2**0)` (= 1) - MAX_CONSOLIDATIONS*: uint64 = 1 + MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD*: uint64 = 1 # Execution # --------------------------------------------------------------- - # 2**13 (= 8192) receipts - MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD* = 8192 + # 2**13 (= 8192) deposit requests + MAX_DEPOSIT_REQUESTS_PER_PAYLOAD* = 8192 # 2**4 (= 16) withdrawal requests MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD* = 16 diff --git a/beacon_chain/spec/presets/minimal/electra_preset.nim b/beacon_chain/spec/presets/minimal/electra_preset.nim index 61a75a6a1..7528f2d2f 100644 --- a/beacon_chain/spec/presets/minimal/electra_preset.nim +++ b/beacon_chain/spec/presets/minimal/electra_preset.nim @@ -40,12 +40,12 @@ const # `uint64(2**3)` (= 8) MAX_ATTESTATIONS_ELECTRA*: uint64 = 8 # `uint64(2**0)` (= 1) - MAX_CONSOLIDATIONS*: uint64 = 1 + MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD*: uint64 = 1 # Execution # --------------------------------------------------------------- # [customized] - MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD* = 4 + MAX_DEPOSIT_REQUESTS_PER_PAYLOAD* = 4 # [customized] 2**1 (= 2) withdrawal requests MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD* = 2 diff --git a/beacon_chain/spec/signatures.nim b/beacon_chain/spec/signatures.nim index 1fcb6ca9f..12f2a0c72 100644 --- a/beacon_chain/spec/signatures.nim +++ b/beacon_chain/spec/signatures.nim @@ -421,23 +421,3 @@ proc verify_bls_to_execution_change_signature*( let signing_root = compute_bls_to_execution_change_signing_root( genesisFork, genesis_validators_root, msg.message) blsVerify(pubkey, signing_root.data, signature) - -func compute_consolidation_signing_root( - genesisFork: Fork, genesis_validators_root: Eth2Digest, - msg: Consolidation): Eth2Digest = - # Uses genesis fork version regardless - doAssert genesisFork.current_version == genesisFork.previous_version - - let domain = compute_domain( - DOMAIN_CONSOLIDATION, genesisFork.current_version, - genesis_validators_root=genesis_validators_root) - compute_signing_root(msg, domain) - -proc verify_consolidation_signature*( - genesisFork: Fork, genesis_validators_root: Eth2Digest, - msg: SignedConsolidation | TrustedSignedConsolidation, - pubkeys: openArray[ValidatorPubKey]): bool = - withTrust(msg.signature): - let signing_root = compute_consolidation_signing_root( - genesisFork, genesis_validators_root, msg.message) - blsFastAggregateVerify(pubkeys, signing_root.data, msg.signature) diff --git a/beacon_chain/spec/state_transition.nim b/beacon_chain/spec/state_transition.nim index dc936631c..664c0a46a 100644 --- a/beacon_chain/spec/state_transition.nim +++ b/beacon_chain/spec/state_transition.nim @@ -361,8 +361,7 @@ func partialBeaconBlock*( deposits: seq[Deposit], validator_changes: BeaconBlockValidatorChanges, sync_aggregate: SyncAggregate, - execution_payload: ForkyExecutionPayloadForSigning, - consolidations: openArray[SignedConsolidation] + execution_payload: ForkyExecutionPayloadForSigning ): auto = const consensusFork = typeof(state).kind @@ -412,8 +411,7 @@ func partialBeaconBlock*( deposits: seq[Deposit], validator_changes: BeaconBlockValidatorChanges, sync_aggregate: SyncAggregate, - execution_payload: ForkyExecutionPayloadForSigning, - consolidations: seq[SignedConsolidation], + execution_payload: ForkyExecutionPayloadForSigning ): auto = const consensusFork = typeof(state).kind @@ -436,10 +434,7 @@ func partialBeaconBlock*( sync_aggregate: sync_aggregate, execution_payload: execution_payload.executionPayload, bls_to_execution_changes: validator_changes.bls_to_execution_changes, - blob_kzg_commitments: execution_payload.blobsBundle.commitments, - consolidations: - List[SignedConsolidation, Limit MAX_CONSOLIDATIONS].init( - consolidations))) + blob_kzg_commitments: execution_payload.blobsBundle.commitments)) proc makeBeaconBlockWithRewards*( cfg: RuntimeConfig, @@ -453,7 +448,6 @@ proc makeBeaconBlockWithRewards*( validator_changes: BeaconBlockValidatorChanges, sync_aggregate: SyncAggregate, executionPayload: ForkyExecutionPayloadForSigning, - consolidations: seq[SignedConsolidation], rollback: RollbackForkedHashedProc, cache: var StateCache, # TODO: @@ -480,7 +474,7 @@ proc makeBeaconBlockWithRewards*( partialBeaconBlock( cfg, state.`kind Data`, proposer_index, randao_reveal, eth1_data, graffiti, attestations, deposits, validator_changes, sync_aggregate, - executionPayload, consolidations)) + executionPayload)) let res = process_block( cfg, state.`kind Data`.data, blck.`kind Data`.asSigVerified(), @@ -524,7 +518,7 @@ proc makeBeaconBlockWithRewards*( transactions_root.get when executionPayload is electra.ExecutionPayloadForSigning: - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/electra/beacon-chain.md#beaconblockbody + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#beaconblockbody forkyState.data.latest_block_header.body_root = hash_tree_root( [hash_tree_root(randao_reveal), hash_tree_root(eth1_data), @@ -539,9 +533,7 @@ proc makeBeaconBlockWithRewards*( hash_tree_root(sync_aggregate), execution_payload_root.get, hash_tree_root(validator_changes.bls_to_execution_changes), - hash_tree_root(kzg_commitments.get), - hash_tree_root(List[SignedConsolidation, Limit MAX_CONSOLIDATIONS].init( - consolidations)) + hash_tree_root(kzg_commitments.get) ]) else: raiseAssert "Attempt to use non-Electra payload with post-Deneb state" @@ -584,7 +576,6 @@ proc makeBeaconBlock*( validator_changes: BeaconBlockValidatorChanges, sync_aggregate: SyncAggregate, executionPayload: ForkyExecutionPayloadForSigning, - consolidations: seq[SignedConsolidation], rollback: RollbackForkedHashedProc, cache: var StateCache, verificationFlags: UpdateFlags, transactions_root: Opt[Eth2Digest], @@ -595,7 +586,7 @@ proc makeBeaconBlock*( ? makeBeaconBlockWithRewards( cfg, state, proposer_index, randao_reveal, eth1_data, graffiti, attestations, deposits, validator_changes, sync_aggregate, - executionPayload, consolidations, rollback, cache, verificationFlags, + executionPayload, rollback, cache, verificationFlags, transactions_root, execution_payload_root, kzg_commitments) ok(blockAndRewards.blck) @@ -608,13 +599,12 @@ proc makeBeaconBlock*( validator_changes: BeaconBlockValidatorChanges, sync_aggregate: SyncAggregate, executionPayload: ForkyExecutionPayloadForSigning, - consolidations: seq[SignedConsolidation], rollback: RollbackForkedHashedProc, cache: var StateCache): Result[ForkedBeaconBlock, cstring] = makeBeaconBlock( cfg, state, proposer_index, randao_reveal, eth1_data, graffiti, attestations, deposits, validator_changes, sync_aggregate, - executionPayload, consolidations, rollback, cache, + executionPayload, rollback, cache, verificationFlags = {}, transactions_root = Opt.none Eth2Digest, execution_payload_root = Opt.none Eth2Digest, kzg_commitments = Opt.none KzgCommitments) @@ -628,14 +618,13 @@ proc makeBeaconBlock*( validator_changes: BeaconBlockValidatorChanges, sync_aggregate: SyncAggregate, executionPayload: ForkyExecutionPayloadForSigning, - consolidations: seq[SignedConsolidation], rollback: RollbackForkedHashedProc, cache: var StateCache, verificationFlags: UpdateFlags): Result[ForkedBeaconBlock, cstring] = makeBeaconBlock( cfg, state, proposer_index, randao_reveal, eth1_data, graffiti, attestations, deposits, validator_changes, sync_aggregate, - executionPayload, consolidations, rollback, cache, + executionPayload, rollback, cache, verificationFlags = verificationFlags, transactions_root = Opt.none Eth2Digest, execution_payload_root = Opt.none Eth2Digest, diff --git a/beacon_chain/spec/state_transition_block.nim b/beacon_chain/spec/state_transition_block.nim index 91947856f..c77fdc32d 100644 --- a/beacon_chain/spec/state_transition_block.nim +++ b/beacon_chain/spec/state_transition_block.nim @@ -397,22 +397,22 @@ proc process_deposit*( apply_deposit(cfg, state, bloom_filter, deposit.data, flags) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-process_deposit_receipt -func process_deposit_receipt*( +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#new-process_deposit_request +func process_deposit_request*( cfg: RuntimeConfig, state: var electra.BeaconState, - bloom_filter: var PubkeyBloomFilter, deposit_receipt: DepositReceipt, + bloom_filter: var PubkeyBloomFilter, deposit_request: DepositRequest, flags: UpdateFlags): Result[void, cstring] = - # Set deposit receipt start index - if state.deposit_receipts_start_index == - UNSET_DEPOSIT_RECEIPTS_START_INDEX: - state.deposit_receipts_start_index = deposit_receipt.index + # Set deposit request start index + if state.deposit_requests_start_index == + UNSET_DEPOSIT_REQUESTS_START_INDEX: + state.deposit_requests_start_index = deposit_request.index apply_deposit( cfg, state, bloom_filter, DepositData( - pubkey: deposit_receipt.pubkey, - withdrawal_credentials: deposit_receipt.withdrawal_credentials, - amount: deposit_receipt.amount, - signature: deposit_receipt.signature), flags) + pubkey: deposit_request.pubkey, + withdrawal_credentials: deposit_request.withdrawal_credentials, + amount: deposit_request.amount, + signature: deposit_request.signature), flags) # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#voluntary-exits # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#modified-process_voluntary_exit @@ -507,13 +507,12 @@ proc process_bls_to_execution_change*( ok() -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/electra/beacon-chain.md#new-process_execution_layer_withdrawal_request -func process_execution_layer_withdrawal_request*( +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#new-process_withdrawal_request +func process_withdrawal_request*( cfg: RuntimeConfig, state: var electra.BeaconState, - execution_layer_withdrawal_request: ExecutionLayerWithdrawalRequest, - cache: var StateCache) = + withdrawal_request: WithdrawalRequest, cache: var StateCache) = let - amount = execution_layer_withdrawal_request.amount + amount = withdrawal_request.amount is_full_exit_request = amount == static(FULL_EXIT_REQUEST_AMOUNT.Gwei) # If partial withdrawal queue is full, only full exits are processed @@ -522,7 +521,8 @@ func process_execution_layer_withdrawal_request*( return let - request_pubkey = execution_layer_withdrawal_request.validator_pubkey + request_pubkey = withdrawal_request.validator_pubkey + # Verify pubkey exists index = findValidatorIndex(state, request_pubkey).valueOr: return validator = state.validators.item(index) @@ -532,7 +532,7 @@ func process_execution_layer_withdrawal_request*( has_correct_credential = has_execution_withdrawal_credential(validator) is_correct_source_address = validator.withdrawal_credentials.data.toOpenArray(12, 31) == - execution_layer_withdrawal_request.source_address.data + withdrawal_request.source_address.data if not (has_correct_credential and is_correct_source_address): return @@ -588,67 +588,66 @@ func process_execution_layer_withdrawal_request*( withdrawable_epoch: withdrawable_epoch, )) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#consolidations -proc process_consolidation*( +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#new-process_consolidation_request +proc process_consolidation_request*( cfg: RuntimeConfig, state: var electra.BeaconState, - signed_consolidation: SignedConsolidation | TrustedSignedConsolidation, - cache: var StateCache): Result[void, cstring] = - # If the pending consolidations queue is full, no consolidations are allowed - # in the block + consolidation_request: ConsolidationRequest, + cache: var StateCache) = + # If the pending consolidations queue is full, consolidation requests are + # ignored if not(lenu64(state.pending_consolidations) < PENDING_CONSOLIDATIONS_LIMIT): - return err("Consolidation: too many pending consolidations already") + return - # If there is too little available consolidation churn limit, no - # consolidations are allowed in the block + # If there is too little available consolidation churn limit, consolidation + # requests are ignored if not (get_consolidation_churn_limit(cfg, state, cache) > static(MIN_ACTIVATION_BALANCE.Gwei)): - return err("Consolidation: insufficient available consolidation churn limit") - - let consolidation = signed_consolidation.message - - # Verify that source != target, so a consolidation cannot be used as an exit. - if not(consolidation.source_index != consolidation.target_index): - return err("Consolidation: a consolidation cannot be used as an exit") + return let - source_validator = addr state.validators.mitem(consolidation.source_index) - target_validator = state.validators.item(consolidation.target_index) + # Verify pubkeys exists + source_index = + findValidatorIndex(state, consolidation_request.source_pubkey).valueOr: + return + target_index = + findValidatorIndex(state, consolidation_request.target_pubkey).valueOr: + return + + # Verify that source != target, so a consolidation cannot be used as an exit. + if source_index == target_index: + return + + let + source_validator = addr state.validators.mitem(source_index) + target_validator = state.validators.item(target_index) + + # Verify source withdrawal credentials + let + has_correct_credential = + has_execution_withdrawal_credential(source_validator[]) + is_correct_source_address = + source_validator.withdrawal_credentials.data.toOpenArray(12, 31) == + consolidation_request.source_address.data + if not (has_correct_credential and is_correct_source_address): + return + + # Verify that target has execution withdrawal credentials + if not has_execution_withdrawal_credential(target_validator): + return # Verify the source and the target are active let current_epoch = get_current_epoch(state) if not is_active_validator(source_validator[], current_epoch): - return err("Consolidation: source validator not active") + return if not is_active_validator(target_validator, current_epoch): - return err("Consolidation: target validator not active") + return # Verify exits for source and target have not been initiated - if not (source_validator[].exit_epoch == FAR_FUTURE_EPOCH): - return err("Consolidation: exit for source validator already initiated") - if not (target_validator.exit_epoch == FAR_FUTURE_EPOCH): - return err("Consolidation: exit for target validator already initiated") - - # Consolidations must specify an epoch when they become valid; they are not - # valid before then - if not (current_epoch >= consolidation.epoch): - return err("Consolidation: consolidation not valid before specified epoch") - - # Verify the source and the target have Execution layer withdrawal credentials - if not has_execution_withdrawal_credential(source_validator[]): - return err("Consolidation: source doesn't have execution layer withdrawal credentials") - if not has_execution_withdrawal_credential(target_validator): - return err("Consolidation: target doesn't have execution layer withdrawal credentials") - - # Verify the same withdrawal address - if not (source_validator[].withdrawal_credentials.data.toOpenArray(12, 31) == - target_validator.withdrawal_credentials.data.toOpenArray(12, 31)): - return err("Consolidation: source and target don't have same withdrawal address") - - # Verify consolidation is signed by the source and the target - if not verify_consolidation_signature( - cfg.genesisFork, state.genesis_validators_root, signed_consolidation, - [source_validator[].pubkey, target_validator.pubkey]): - return err("Consolidation: invalid signature") + if source_validator[].exit_epoch != FAR_FUTURE_EPOCH: + return + if target_validator.exit_epoch != FAR_FUTURE_EPOCH: + return # Initiate source validator exit and append pending consolidation source_validator[].exit_epoch = compute_consolidation_epoch_and_update_churn( @@ -657,10 +656,7 @@ proc process_consolidation*( source_validator[].exit_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY debugComment "check HashList add return value" discard state.pending_consolidations.add(PendingConsolidation( - source_index: consolidation.source_index, - target_index: consolidation.target_index)) - - ok() + source_index: source_index.uint64, target_index: target_index.uint64)) type # https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.5.0#/Rewards/getBlockRewards @@ -672,7 +668,7 @@ type # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#operations # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#modified-process_operations -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.1/specs/electra/beacon-chain.md#modified-process_operations +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#operations proc process_operations( cfg: RuntimeConfig, state: var ForkyBeaconState, body: SomeForkyBeaconBlockBody, base_reward_per_increment: Gwei, @@ -683,7 +679,7 @@ proc process_operations( # Disable former deposit mechanism once all prior deposits are processed let eth1_deposit_index_limit = - min(state.eth1_data.deposit_count, state.deposit_receipts_start_index) + min(state.eth1_data.deposit_count, state.deposit_requests_start_index) req_deposits = if state.eth1_deposit_index < eth1_deposit_index_limit: min( @@ -733,17 +729,17 @@ proc process_operations( for op in body.bls_to_execution_changes: ? process_bls_to_execution_change(cfg, state, op) - # [New in Electra:EIP7002:EIP7251] when typeof(body).kind >= ConsensusFork.Electra: - for op in body.execution_payload.withdrawal_requests: - process_execution_layer_withdrawal_request( - cfg, state, op, cache) - for op in body.execution_payload.deposit_receipts: - debugComment "combine with previous bloom filter construction" + for op in body.execution_payload.deposit_requests: + debugComment "combine with previous Bloom filter construction" let bloom_filter = constructBloomFilter(state.validators.asSeq) - ? process_deposit_receipt(cfg, state, bloom_filter[], op, {}) - for op in body.consolidations: - ? process_consolidation(cfg, state, op, cache) + ? process_deposit_request(cfg, state, bloom_filter[], op, {}) + for op in body.execution_payload.withdrawal_requests: + # [New in Electra:EIP7002:7251] + process_withdrawal_request(cfg, state, op, cache) + for op in body.execution_payload.consolidation_requests: + # [New in Electra:EIP7251] + process_consolidation_request(cfg, state, op, cache) ok(operations_rewards) @@ -971,7 +967,7 @@ type SomeElectraBeaconBlockBody = electra.BeaconBlockBody | electra.SigVerifiedBeaconBlockBody | electra.TrustedBeaconBlockBody -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#modified-process_execution_payload +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#modified-process_execution_payload proc process_execution_payload*( state: var electra.BeaconState, body: SomeElectraBeaconBlockBody, notify_new_payload: electra.ExecutePayload): Result[void, cstring] = @@ -1018,20 +1014,33 @@ proc process_execution_payload*( withdrawals_root: hash_tree_root(payload.withdrawals), blob_gas_used: payload.blob_gas_used, excess_blob_gas: payload.excess_blob_gas, - deposit_receipts_root: - hash_tree_root(payload.deposit_receipts), # [New in Electra:EIP6110] + deposit_requests_root: + hash_tree_root(payload.deposit_requests), # [New in Electra:EIP6110] withdrawal_requests_root: - hash_tree_root(payload.withdrawal_requests)) # [New in Electra:EIP7002:EIP7251] + hash_tree_root(payload.withdrawal_requests), # [New in Electra:EIP7002:EIP7251] + consolidation_requests_root: + hash_tree_root(payload.consolidation_requests)) # [New in Electra:EIP7251] ok() # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#new-process_withdrawals +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#updated-process_withdrawals func process_withdrawals*( state: var (capella.BeaconState | deneb.BeaconState | electra.BeaconState), payload: capella.ExecutionPayload | deneb.ExecutionPayload | electra.ExecutionPayload): Result[void, cstring] = - let expected_withdrawals = get_expected_withdrawals(state) + when typeof(state).kind >= ConsensusFork.Electra: + let (expected_withdrawals, partial_withdrawals_count) = + get_expected_withdrawals_with_partial_count(state) + + # Update pending partial withdrawals [New in Electra:EIP7251] + # Moved slightly earlier to be in same when block + state.pending_partial_withdrawals = + HashList[PendingPartialWithdrawal, Limit PENDING_PARTIAL_WITHDRAWALS_LIMIT].init( + state.pending_partial_withdrawals.asSeq[partial_withdrawals_count .. ^1]) + else: + let expected_withdrawals = get_expected_withdrawals(state) if not (len(payload.withdrawals) == len(expected_withdrawals)): return err("process_withdrawals: different numbers of payload and expected withdrawals") diff --git a/beacon_chain/spec/state_transition_epoch.nim b/beacon_chain/spec/state_transition_epoch.nim index 06373511d..633ff7540 100644 --- a/beacon_chain/spec/state_transition_epoch.nim +++ b/beacon_chain/spec/state_transition_epoch.nim @@ -1218,25 +1218,45 @@ func process_historical_summaries_update*( ok() -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-process_pending_balance_deposits +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#new-process_pending_balance_deposits func process_pending_balance_deposits*( cfg: RuntimeConfig, state: var electra.BeaconState, cache: var StateCache): Result[void, cstring] = - let - available_for_processing = state.deposit_balance_to_consume + - get_activation_exit_churn_limit(cfg, state, cache) + let available_for_processing = state.deposit_balance_to_consume + + get_activation_exit_churn_limit(cfg, state, cache) var processed_amount = 0.Gwei - next_deposit_index = 0.Gwei + next_deposit_index = 0 + deposits_to_postpone: seq[PendingBalanceDeposit] for deposit in state.pending_balance_deposits: - if processed_amount + deposit.amount > available_for_processing: - break + let validator = state.validators.item(deposit.index) + let deposit_validator_index = ValidatorIndex.init(deposit.index).valueOr: + # TODO this function in spec doesn't really have error returns as such return err("process_pending_balance_deposits: deposit index out of range") - increase_balance(state, deposit_validator_index, deposit.amount) - processed_amount += deposit.amount - inc next_deposit_index + + # Validator is exiting, postpone the deposit until after withdrawable epoch + if validator.exit_epoch < FAR_FUTURE_EPOCH: + if get_current_epoch(state) <= validator.withdrawable_epoch: + deposits_to_postpone.add(deposit) + # Deposited balance will never become active. Increase balance but do not + # consume churn + else: + increase_balance(state, deposit_validator_index, deposit.amount) + # Validator is not exiting, attempt to process deposit + else: + # Deposit does not fit in the churn, no more deposit processing in this + # epoch. + if processed_amount + deposit.amount > available_for_processing: + break + # Deposit fits in the churn, process it. Increase balance and consume churn. + else: + increase_balance(state, deposit_validator_index, deposit.amount) + processed_amount += deposit.amount + + # Regardless of how the deposit was handled, we move on in the queue. + next_deposit_index += 1 state.pending_balance_deposits = HashList[PendingBalanceDeposit, Limit PENDING_BALANCE_DEPOSITS_LIMIT].init( @@ -1248,6 +1268,10 @@ func process_pending_balance_deposits*( state.deposit_balance_to_consume = available_for_processing - processed_amount + debugComment "yet another in-theory-might-overflow-maybe things, look at these more carefully" + if len(deposits_to_postpone) > 0: + discard state.pending_balance_deposits.add deposits_to_postpone + ok() # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-process_pending_consolidations diff --git a/beacon_chain/spec/validator.nim b/beacon_chain/spec/validator.nim index 7e0d31ed1..b10fa09b3 100644 --- a/beacon_chain/spec/validator.nim +++ b/beacon_chain/spec/validator.nim @@ -349,6 +349,7 @@ func compute_inverted_shuffled_index*( countdown(SHUFFLE_ROUND_COUNT.uint8 - 1, 0'u8, 1) # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#compute_proposer_index +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#updated-compute_proposer_index template compute_proposer_index(state: ForkyBeaconState, indices: openArray[ValidatorIndex], seed: Eth2Digest, unshuffleTransform: untyped): Opt[ValidatorIndex] = @@ -373,8 +374,13 @@ template compute_proposer_index(state: ForkyBeaconState, candidate_index = indices[unshuffleTransform] random_byte = (eth2digest(buffer).data)[i mod 32] effective_balance = state.validators[candidate_index].effective_balance + const max_effective_balance = + when typeof(state).kind >= ConsensusFork.Electra: + MAX_EFFECTIVE_BALANCE_ELECTRA.Gwei # [Modified in Electra:EIP7251] + else: + MAX_EFFECTIVE_BALANCE.Gwei if effective_balance * MAX_RANDOM_BYTE >= - MAX_EFFECTIVE_BALANCE.Gwei * random_byte: + max_effective_balance * random_byte: res = Opt.some(candidate_index) break i += 1 diff --git a/beacon_chain/validators/beacon_validators.nim b/beacon_chain/validators/beacon_validators.nim index 328075535..583c93ff6 100644 --- a/beacon_chain/validators/beacon_validators.nim +++ b/beacon_chain/validators/beacon_validators.nim @@ -539,7 +539,6 @@ proc makeBeaconBlockForHeadAndSlot*( slot, validator_index return err("Unable to get execution payload") - debugComment "flesh out consolidations" let res = makeBeaconBlockWithRewards( node.dag.cfg, state[], @@ -552,7 +551,6 @@ proc makeBeaconBlockForHeadAndSlot*( exits, node.syncCommitteeMsgPool[].produceSyncAggregate(head.bid, slot), payload, - @[], # consolidations noRollback, # Temporary state - no need for rollback cache, verificationFlags = {}, diff --git a/beacon_chain/validators/message_router_mev.nim b/beacon_chain/validators/message_router_mev.nim index 76a2c44e3..7dad0b76d 100644 --- a/beacon_chain/validators/message_router_mev.nim +++ b/beacon_chain/validators/message_router_mev.nim @@ -38,7 +38,8 @@ macro copyFields*( # unblinded objects, and can't simply be copied. "transactions_root", "execution_payload", "execution_payload_header", "body", "withdrawals_root", - "deposit_receipts_root", "withdrawal_requests_root"]: + "deposit_requests_root", "withdrawal_requests_root", + "consolidation_requests_root"]: # TODO use stew/assign2 result.add newAssignment( newDotExpr(dst, ident(name)), newDotExpr(src, ident(name))) diff --git a/research/block_sim.nim b/research/block_sim.nim index 11fc531c7..b7443f8d5 100644 --- a/research/block_sim.nim +++ b/research/block_sim.nim @@ -85,7 +85,7 @@ proc makeSimulationBlock( var blck = partialBeaconBlock( cfg, state, proposer_index, randao_reveal, eth1_data, graffiti, - attestations, deposits, exits, sync_aggregate, execution_payload, @[]) + attestations, deposits, exits, sync_aggregate, execution_payload) let res = process_block( cfg, state.data, blck.asSigVerified(), verificationFlags, cache) @@ -128,7 +128,7 @@ proc makeSimulationBlock( var blck = partialBeaconBlock( cfg, state, proposer_index, randao_reveal, eth1_data, graffiti, - attestations, deposits, exits, sync_aggregate, execution_payload, @[]) + attestations, deposits, exits, sync_aggregate, execution_payload) let res = process_block( cfg, state.data, blck.asSigVerified(), verificationFlags, cache) diff --git a/research/wss_sim.nim b/research/wss_sim.nim index d93401f7c..7c0f913ea 100644 --- a/research/wss_sim.nim +++ b/research/wss_sim.nim @@ -295,7 +295,6 @@ cli do(validatorsDir: string, secretsDir: string, BeaconBlockValidatorChanges(), syncAggregate, payload, - @[], # consolidations noRollback, cache).get() diff --git a/scripts/test_merge_node.nim b/scripts/test_merge_node.nim deleted file mode 100644 index 0505ee042..000000000 --- a/scripts/test_merge_node.nim +++ /dev/null @@ -1,68 +0,0 @@ -# beacon_chain -# Copyright (c) 2022-2024 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. - -{.push raises: [].} - -# https://notes.ethereum.org/@9AeMAlpyQYaAAyuj47BzRw/rkwW3ceVY -# Monitor traffic: socat -v TCP-LISTEN:9550,fork TCP-CONNECT:127.0.0.1:8550 - -import - std/options, - stew/results, - chronos, - ../beacon_chain/el/el_manager - -from std/os import paramCount, paramStr -from nimcrypto/utils import fromHex -from web3/engine_api_types import PayloadExecutionStatus -from ../beacon_chain/networking/network_metadata import Eth1Network -from ../beacon_chain/spec/datatypes/base import ZERO_HASH -from ../beacon_chain/spec/presets import Eth1Address, defaultRuntimeConfig - -# TODO factor this out and have a version with the result of the JWT secret -# slurp for testing purposes -proc readJwtSecret(jwtSecretFile: string): Result[seq[byte], cstring] = - # https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.3/src/engine/authentication.md#key-distribution - # If such a parameter is given, but the file cannot be read, or does not - # contain a hex-encoded key of 256 bits, the client SHOULD treat this as an - # error: either abort the startup, or show error and continue without - # exposing the authenticated port. - const MIN_SECRET_LEN = 32 - - try: - let lines = readLines(jwtSecretFile, 1) - if lines.len > 0: - # Secret JWT key is parsed in constant time using nimcrypto: - # https://github.com/cheatfate/nimcrypto/pull/44 - let secret = utils.fromHex(lines[0]) - if secret.len >= MIN_SECRET_LEN: - ok(secret) - else: - err("JWT secret not at least 256 bits") - else: - err("JWT secret file empty") - except IOError as exc: - err("JWT secret file could not be read from") - -proc run() {.async.} = - if paramCount() < 2: - echo "args are: web3url jwtsecretfilename" - - let - elManager = newClone ELManager.init( - defaultRuntimeConfig, db = nil, nil, @[paramStr(1)], - none(DepositContractSnapshot), none(Eth1Network), false, - some readJwtSecret(paramStr(2)).get) - - try: - await elManager.exchangeTransitionConfiguration() - except ValueError as exc: - # Expected, since nothing here sets up the Nimbus TTD correctly - echo "exchangeTransitionConfiguration ValueError: " & exc.msg - echo "Invalid TTD errors are fine in this context" - -waitFor run() diff --git a/tests/consensus_spec/electra/test_fixture_operations.nim b/tests/consensus_spec/electra/test_fixture_operations.nim index f4bc3fe6d..0bf68ff77 100644 --- a/tests/consensus_spec/electra/test_fixture_operations.nim +++ b/tests/consensus_spec/electra/test_fixture_operations.nim @@ -32,10 +32,10 @@ const OpAttSlashingDir = OpDir/"attester_slashing" OpBlockHeaderDir = OpDir/"block_header" OpBlsToExecutionChangeDir = OpDir/"bls_to_execution_change" - OpConsolidationDir = OpDir/"consolidation" - OpDepositReceiptDir = OpDir/"deposit_receipt" + OpConsolidationRequestDir = OpDir/"consolidation_request" + OpDepositRequestDir = OpDir/"deposit_request" OpDepositsDir = OpDir/"deposit" - OpExecutionLayerWithdrawalRequestDir = OpDir/"execution_layer_withdrawal_request" + OpWithdrawalRequestDir = OpDir/"withdrawal_request" OpExecutionPayloadDir = OpDir/"execution_payload" OpProposerSlashingDir = OpDir/"proposer_slashing" OpSyncAggregateDir = OpDir/"sync_aggregate" @@ -45,14 +45,13 @@ const baseDescription = "EF - Electra - Operations - " -var testDirs = toHashSet([ +const testDirs = toHashSet([ OpAttestationsDir, OpAttSlashingDir, OpBlockHeaderDir, - OpBlsToExecutionChangeDir, OpDepositReceiptDir, OpDepositsDir, - OpExecutionLayerWithdrawalRequestDir, OpExecutionPayloadDir, + OpBlsToExecutionChangeDir, OpConsolidationRequestDir, OpDepositRequestDir, + OpDepositsDir, OpWithdrawalRequestDir, OpExecutionPayloadDir, OpProposerSlashingDir, OpSyncAggregateDir, OpVoluntaryExitDir, OpWithdrawalsDir]) -when const_preset == "minimal": - testDirs.incl OpConsolidationDir + doAssert toHashSet( mapIt(toSeq(walkDir(OpDir, relative = false)), it.path)) == testDirs @@ -149,24 +148,19 @@ suite baseDescription & "BLS to execution change " & preset(): OpBlsToExecutionChangeDir, suiteName, "BLS to execution change", "address_change", applyBlsToExecutionChange, path) -when const_preset == "minimal": - suite baseDescription & "Consolidation " & preset(): - proc applyConsolidation( - preState: var electra.BeaconState, - signed_consolidation: SignedConsolidation): - Result[void, cstring] = - var cache: StateCache - process_consolidation( - defaultRuntimeConfig, preState, signed_consolidation, cache) +suite baseDescription & "Consolidation Request " & preset(): + proc applyConsolidationRequest( + preState: var electra.BeaconState, + consolidation_request: ConsolidationRequest): Result[void, cstring] = + var cache: StateCache + process_consolidation_request( + defaultRuntimeConfig, preState, consolidation_request, cache) + ok() - for path in walkTests(OpConsolidationDir): - if path in [ - "invalid_exceed_pending_consolidations_limit", # apparently invalid prestate SSZ - ]: - continue - runTest[SignedConsolidation, typeof applyConsolidation]( - OpConsolidationDir, suiteName, "Consolidation", "consolidation", - applyConsolidation, path) + for path in walkTests(OpConsolidationRequestDir): + runTest[ConsolidationRequest, typeof applyConsolidationRequest]( + OpConsolidationRequestDir, suiteName, "Consolidation Request", + "consolidation_request", applyConsolidationRequest, path) from ".."/".."/".."/beacon_chain/bloomfilter import constructBloomFilter @@ -182,18 +176,18 @@ suite baseDescription & "Deposit " & preset(): runTest[Deposit, typeof applyDeposit]( OpDepositsDir, suiteName, "Deposit", "deposit", applyDeposit, path) -suite baseDescription & "Deposit Receipt " & preset(): - func applyDepositReceipt( - preState: var electra.BeaconState, depositReceipt: DepositReceipt): +suite baseDescription & "Deposit Request " & preset(): + func applyDepositRequest( + preState: var electra.BeaconState, depositRequest: DepositRequest): Result[void, cstring] = - process_deposit_receipt( + process_deposit_request( defaultRuntimeConfig, preState, - constructBloomFilter(preState.validators.asSeq)[], depositReceipt, {}) + constructBloomFilter(preState.validators.asSeq)[], depositRequest, {}) - for path in walkTests(OpDepositReceiptDir): - runTest[DepositReceipt, typeof applyDepositReceipt]( - OpDepositReceiptDir, suiteName, "Deposit Receipt", "deposit_receipt", - applyDepositReceipt, path) + for path in walkTests(OpDepositRequestDir): + runTest[DepositRequest, typeof applyDepositRequest]( + OpDepositRequestDir, suiteName, "Deposit Request", "deposit_request", + applyDepositRequest, path) suite baseDescription & "Execution Payload " & preset(): func makeApplyExecutionPayloadCb(path: string): auto = @@ -212,23 +206,19 @@ suite baseDescription & "Execution Payload " & preset(): OpExecutionPayloadDir, suiteName, "Execution Payload", "body", applyExecutionPayload, path) -suite baseDescription & "Execution Layer Withdrawal Request " & preset(): - func applyExecutionLayerWithdrawalRequest( - preState: var electra.BeaconState, - executionLayerWithdrawalRequest: ExecutionLayerWithdrawalRequest): +suite baseDescription & "Withdrawal Request " & preset(): + func applyWithdrawalRequest( + preState: var electra.BeaconState, withdrawalRequest: WithdrawalRequest): Result[void, cstring] = var cache: StateCache - process_execution_layer_withdrawal_request( - defaultRuntimeConfig, preState, executionLayerWithdrawalRequest, cache) + process_withdrawal_request( + defaultRuntimeConfig, preState, withdrawalRequest, cache) ok() - for path in walkTests(OpExecutionLayerWithdrawalRequestDir): - runTest[ExecutionLayerWithdrawalRequest, - typeof applyExecutionLayerWithdrawalRequest]( - OpExecutionLayerWithdrawalRequestDir, suiteName, - "Execution Layer Withdrawal Request", - "execution_layer_withdrawal_request", - applyExecutionLayerWithdrawalRequest, path) + for path in walkTests(OpWithdrawalRequestDir): + runTest[WithdrawalRequest, typeof applyWithdrawalRequest]( + OpWithdrawalRequestDir, suiteName, "Withdrawal Request", + "withdrawal_request", applyWithdrawalRequest, path) suite baseDescription & "Proposer Slashing " & preset(): proc applyProposerSlashing( diff --git a/tests/consensus_spec/electra/test_fixture_ssz_consensus_objects.nim b/tests/consensus_spec/electra/test_fixture_ssz_consensus_objects.nim index 11e854cf8..816736052 100644 --- a/tests/consensus_spec/electra/test_fixture_ssz_consensus_objects.nim +++ b/tests/consensus_spec/electra/test_fixture_ssz_consensus_objects.nim @@ -128,16 +128,14 @@ suite "EF - Electra - SSZ consensus objects " & preset(): of "BlobSidecar": checkSSZ(BlobSidecar, path, hash) of "BLSToExecutionChange": checkSSZ(BLSToExecutionChange, path, hash) of "Checkpoint": checkSSZ(Checkpoint, path, hash) - of "Consolidation": checkSSZ(Consolidation, path, hash) + of "ConsolidationRequest": checkSSZ(ConsolidationRequest, 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 "DepositReceipt": checkSSZ(DepositReceipt, path, hash) + of "DepositRequest": checkSSZ(DepositRequest, path, hash) of "Eth1Block": checkSSZ(Eth1Block, path, hash) of "Eth1Data": checkSSZ(Eth1Data, path, hash) - of "ExecutionLayerWithdrawalRequest": - checkSSZ(ExecutionLayerWithdrawalRequest, path, hash) of "ExecutionPayload": checkSSZ(ExecutionPayload, path, hash) of "ExecutionPayloadHeader": checkSSZ(ExecutionPayloadHeader, path, hash) @@ -172,7 +170,6 @@ suite "EF - Electra - SSZ consensus objects " & preset(): checkSSZ(SignedBLSToExecutionChange, path, hash) of "SignedContributionAndProof": checkSSZ(SignedContributionAndProof, path, hash) - of "SignedConsolidation": checkSSZ(SignedConsolidation, path, hash) of "SignedVoluntaryExit": checkSSZ(SignedVoluntaryExit, path, hash) of "SigningData": checkSSZ(SigningData, path, hash) of "SyncAggregate": checkSSZ(SyncAggregate, path, hash) @@ -185,5 +182,6 @@ suite "EF - Electra - SSZ consensus objects " & preset(): of "Withdrawal": checkSSZ(Withdrawal, path, hash) of "Validator": checkSSZ(Validator, path, hash) of "VoluntaryExit": checkSSZ(VoluntaryExit, path, hash) + of "WithdrawalRequest": checkSSZ(WithdrawalRequest, path, hash) else: raise newException(ValueError, "Unsupported test: " & sszType) \ No newline at end of file diff --git a/tests/test_el_manager.nim b/tests/test_el_manager.nim index ebdd002fc..e61de7f3a 100644 --- a/tests/test_el_manager.nim +++ b/tests/test_el_manager.nim @@ -1609,39 +1609,39 @@ suite "Eth1 monitor": ]), blob_gas_used: 4401258332680664954'u64, excess_blob_gas: 12834012644793671460'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x814b12b95f9846e3d69ee46e6a47a26d6cc8613641a1352f35395a15de56043ef451726e797757b9768657a9e9787a83")), withdrawal_credentials: Eth2Digest.fromHex("0x241d63159f0cde42aeec7610900762ad2016f5bc0270250d7086b173bf6e4181"), amount: 12638322094749964200'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x10244d58594ff86b3548ae04b3c193756c7cf2e9830da492c6021259f8bce7ac6ea62d93a9b78adc77a168b91865876ac68ef7f05564cac91353e400fa5c44317789d2d93d6a6cba9155db29b7857562a6d9316454d1a9c5178e2ce5c75fa5bb")), index: 8139570810318771243'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xb7721c98fe1ae6beaf0e486d2d951a307a3d3265cf6f2b16bd8b40f2dbfbc6e4e20e3f75c29e70a0432af0385a997eaf")), withdrawal_credentials: Eth2Digest.fromHex("0x0aae47c8d21e2ff63a5b341c1bf209f5176762d522d16d2f7b9a595cc327a3a6"), amount: 15018910798502483977'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xa6d248e93991eff0b001418667e718204216d88fce9933fcce52e4daa026e8c47f9863a77d675fecd6def721d194684c28823350fe80429356c57792c70b22571e7d3219b9a8a35d3a552dd5eb6ffdd01ee5a1fcd2d14ad82038f7ca00a22ca8")), index: 13899393201735021181'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xbced475462c8676eb79a8e288f1f7759b621192b2a5f41162473affe3219663fa1e9d78f0ce94c556e4bfa1dfd3f0f9f")), withdrawal_credentials: Eth2Digest.fromHex("0x245144c69624ec1ff4feefd0d9080e016fcab37726bf712df06ebe512bd11fc3"), amount: 8365809466950819313'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x806f5cb96d5cabc2ecfe96fd92816e1e86ea1e86229675bbdd6de141461bfbf3d358094f41ddb91cab075a67950af6016a326697be18d38a2056aab597d40cb216b642b5d6c6f4edacd4a4a89a7c342f3d11f18a1f4f7783ea25251a1f355009")), index: 17214334124209319458'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x22189bc4bc3f45eb3d6d8a5bc6b85aa8f680c5f9cd1aba686757faee3d31bec7bff6af52671fdb767ea7ccaf14ac2ae1")), withdrawal_credentials: Eth2Digest.fromHex("0x25993e69ef274cd8b703d25cd3932b117e08123578b20365aeae8a244a625355"), amount: 12258289723293669412'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xce7d46dc7f0b4ad54417dd50800761161dee1abb2e20af7c4cad314a6921768f7b89ba17bc7b51497c67a14255c31aa19d19bdad1d572f88c598ffdbe7be5d8cbe1ceb83836948512448725ca56ba834626a8f42aa110c7b272524707e514fab")), index: 13244611922088961185'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x0b1cd7defa0a00c8714ab2ab6a1da006d469c725042c589890c9e5c21070d5289a5b33357f9dd8a79e6364fc4e012440")), withdrawal_credentials: Eth2Digest.fromHex("0x4b07a81b5612a02914cfd99571711c78cbaa3e0f1fbb23c4a0a51e04c263a659"), amount: 16282163526662133088'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x943c3c3818d5aa98fbf8344ef4cdc9c13cdabfdeb7762efc8bb32d2ea32d3bbb4ef069a254f5f35325f48609fad7bbafb6389e204767a9b3bbe46a04f8baa850bfd4d3747aaf2816c7e18fc2ebe4fa41088d195d09c761819c7a2e57a3451148")), index: 900883336538271514'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ ]), ), (electra.ExecutionPayload)( @@ -1667,46 +1667,46 @@ suite "Eth1 monitor": ]), blob_gas_used: 4810756443599845432'u64, excess_blob_gas: 1435200597189175983'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x8fa8ea53febdf07bd7f832be8c965a4aca37c3340b4cfd75624c125f4eb5946a404e9cc35d74f55048c1fcfadde3551e")), withdrawal_credentials: Eth2Digest.fromHex("0x7647368d6b5580fc677b463d57d4cc9dda93117e9c8604cda4679030cd4956e4"), amount: 11838169110820399795'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x84ed920f689cda2883afa0c5d12db16206abca7d0319047c2542b9fc6c0e5fb9cf945e76c34da4448bf06a90cf51686393af3b80feebef058a8cf98762439bf748c7394083edcb3b4b20390c00415046f84885a8fc60d873318ed08f7e420d7b")), index: 14081768455144986910'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xae3d89af9e4d6caa6e9746a13f9bba9886c7fb75669af29e089799bf94614d722a776006b4b2fc347e54c88ddebdb5df")), withdrawal_credentials: Eth2Digest.fromHex("0x0548c33677c9d3d11898e1b1cb7e8546b5d28c09626aeb43fe77609ef8eb709c"), amount: 0.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x8beef976488318fe3577aaa2686096377805c1486c3598c5a01202884ac1b68013cdc02e1bda7cc5fcd649c76cb57df4d8bde53f119e2c9f7699653f4686c12ce909b508fc92a063773da4319bc9ec52f1605c7a4c220a1d3bf182e80b7a5949")), index: 7396750296380130136'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xd3abc92b8a163a56e35c545a528eaa0c5bdbfcc5de8a1be80231d2a33ef1249a31c3638771f7a3e764fee81f6c95d433")), withdrawal_credentials: Eth2Digest.fromHex("0x074fa7f5af43e713a8ee7f09fb46ef4f05b23a060486141b5d9e9d273c7fbe56"), amount: 1209689892101089592'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x01b42eaad61c4f658526ff4d64bb49f19276a698b34870245109c24f6f59dcaf87ab2275526c665d2493ea6c77f2bfb86e77d0375f4f63ce4cb3dbe5632442453fb4c73558d3569b62f1a6ecd5821daa85d6762a8a24c0eba6b8e51c9b0acb8f")), index: 16259922695017953678'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xf18bdc121a076ebb642352c940b5c0cd9c60ea4d3b8188b9f7b446efcabbc5af2f0a2672632b0474c5147d17427bf526")), withdrawal_credentials: Eth2Digest.fromHex("0x80de1f7b69ecf34465e463b30e49453c36e65684ce3004a082ffd84bf4c0441e"), amount: 4622244708907095023'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x426dc233d2195c02283140b3d90a50da4d6d5bce3f7c3894a910d891ed835c2cb1dd8ba1e5f82dd214a322abd50e3043408d6f7a04499b2bdf6fcc5b4cda0400d557df79bba2aea31de06de9c8a1e069666a3b71577809480f82fce4a12882fd")), index: 9250544134833432385'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x809a16fa8c9e34875aaac4939775bb6b0034b2fb7f5db570567ef604b11485c878544dc6e6878f4ad921fce8cdcc7273")), withdrawal_credentials: Eth2Digest.fromHex("0xcf05474e4f86279a6faec8fd6987ac10c4aa6595e6d061fe7217a68d5fcaf5d3"), amount: 4509592030421891894'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x0d543b0e9b934586fb877615c8d2551e11998f020bce6b96901fb8045ef42eb41f6039e813136043fe5c63d91a11e1e15e5c4063d1775f95ae1715cb87b21b7690b44ec38efd1a825e1e3ac68d21940f772b3309edb3ddebb24204e06d4924c2")), index: 12423850076890731216'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x39554fbddf13facd81344d536c08ed5769304749"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xc4f5b2c07cc2f6758dd8eaef217247f767bcd88a8f5c93b030023d420568f47735d113df344627759f4ea1b56c53136f"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x243c496e83f955ef23dc3d121b3cbe5f56305d73"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xe9a3d62cdf9acae4966e5682958d0cc9223065b4d68ed3b12a024a56744ab9656736326061f9fb41a8f15564cb4d241f"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x462f156d8d950c7ffd40d7ba149bcc34093bbdb7"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xd6d7f2281c2b9c98a8a5dc0b7f41783eb91b838973207239852e817ed412e164e330003ac9ab0e96bc65886e15b5cbe9"))), ]), @@ -1731,22 +1731,22 @@ suite "Eth1 monitor": ]), blob_gas_used: 723464856451065691'u64, excess_blob_gas: 11231138371511965912'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xd82ed23e86d1d22165bcbed4e01b2548997769f369344a4f347772108782d77c20cdaa614c57457726d3e5d384a7d09b")), withdrawal_credentials: Eth2Digest.fromHex("0x2acf0fdd7ca651a467899a928ffd036d88dd86301808ccd2a06d5002daa35d15"), amount: 15437169017045689073'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x143a1a4dcac6db342901feb541dc0c95830a4ca1aca9c3fcb55e2dcb9a5b31e2bd9214b1a3a12e17e140d37ba7ebfd11d6d8a38eea5d0755402dd400386aaefcc70d12fb1409f92797923bf964bea3f916b562f3ff2b522c48b748c8e8c632d4")), index: 15872726372973140071'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x3a8a707225d47dbddb01c1ca39181af823d57d97"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x9cf008ca8159512ffffa1fe56de68bb9e44f9c4bb3c2c4924f5d7bf1bb810cc807b155f11ddd55a4972346f8e75f06ab"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x7c55f3e4f648bcfb47db2122233b25881785709b"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xb9e559b137b8ab79ddfbc6ea2fb44d96d1925c2b7b6e4c0e1b69f66d82b656065af06bd62e8fe9210276a116ad78c382"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xcf25ed583b463f3a57acd97c398e27877b9bf6a6"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xa14ac0d85ae38dd91a9f7da12b6c7cb4e879f78effc5ac0da8f9ee56059460f31152009fc1b88d0e0a0bf576950f45e0"))), ]), @@ -1769,40 +1769,40 @@ suite "Eth1 monitor": withdrawals: List[capella.Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD].init(@[]), blob_gas_used: 1936360613980595982'u64, excess_blob_gas: 525438497879148955'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x2dc5c92e3d525d69b07de9f2e0fb3db26b05c966b029e38fa736bb60b49d6abe86d4dc61255de43e9bd012c1677a7adc")), withdrawal_credentials: Eth2Digest.fromHex("0xa85cff9568bd1244836733549567286eaa0aef139c416c235555551772e2ae29"), amount: 5525246068348642244'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x4f2e42e2305bd30fdbdc8c2b0e8f9c57c544f097cfdc2fb2335df422a14c5c827d91c586384a2d14f64bbd98124046506388058414766674bbb59bfefe2c701c05a5e9c135d60617830ac5d60788712587220964a78a632cde4e124b7692ce62")), index: 0), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x6ecff72c568c0e272157ac48bd047406c8117cc60e531a3acd46531da9b140c91ae684c72def7839e6d84b6f190877e0")), withdrawal_credentials: Eth2Digest.fromHex("0x0946aa245e0435cb321fd0e166c31cb363fc2f264bbb2d67be9fe89d07b2037c"), amount: 13283742386908495031'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xf683f76e5a79d2248248f701d87327b35705ae31284d8e7602a1470a239d35f9622c5c39812a933ca586f724af4f10b58cea183b8c127dada1abda2eb0879e1aa49f7a9bd89ab76f7d5f33d2ad80c9f058ace2bd83c224520f8d02b0942ed985")), index: 789807770712130412'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x9c696094074fb290b6f8558c7ebe08b8595859aabfe521a7307c3179b21dc8df0a63f0970f89bfe3197373a92630c3c7")), withdrawal_credentials: Eth2Digest.fromHex("0x650cc685a706fd441937753efc42e243339d62c6866f83b00c0ae2becc8882db"), amount: 2716675895799004971'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x79e01ad75396043b9343d83587ccf1dbc7928a8f520e92b2840fa40cb086b04964b8fda19176d22d643c5afe0703884487fc40a14b7a7100c96d4811ea7af08046fd0d7aab8a1f73e05fa598f5be976696109312b26ea8b629ee984be7a7077f")), index: 1321141240653182102'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xcc2fd5c9cec6e09329e140efd4ee508de16b2af020d8ed8b1323f166c3c6cc0ceacefccbb9867cd5681610749050429e")), withdrawal_credentials: Eth2Digest.fromHex("0x89a95d7a2fa26fb6db447d53a508f92f997823f95a6caa25e04196bfb3749f5d"), amount: 18351003704404188995'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x351d11b34c55e1d947d5ce132e02ef1f3765136d14945b3fa297569465d057fb593df173d99e690c7dc8f6455add6b6abc87e4ea88a68fc396ad9189f3c56bf642ccd5dcb42dbcd67b8d6c3ba6627bc2a51d776cc35adbfacb7bd5e84948995d")), index: 16817584575889190379'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xca1819f056ebd22a08689e4d40a195116b68e56a1c9b0914499801f7015f1e2696a9d3fbc17a5c2641b0429eb7bf2124")), withdrawal_credentials: Eth2Digest.fromHex("0x83b7ec99b4e424a17228b43057b9bc8ae387fbc075f1dc692b0e1765629e2494"), amount: 18420683568430679261'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x94cb986143fdae936c832d08977520c41a6a9b1569b012a8486678571ea5ce2e913f55c9d5631a8f02d1b75aca414969c56f22cf0b6e5193f7ac3568b09c9ae955581c69095908ccab9c5ff5c47b2edef262f2843ccc7cbc69eb35b14c66886c")), index: 11423537419700559218'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x44754b90f7b23eee1dddafa745ac723dcc147404"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x8d13edc45159cdcf6ed780fc7b93e74434fa392b0842dfa92458cc59515aaac127317df24def9701eb6d5ea060eaffea"))), ]), @@ -1827,21 +1827,21 @@ suite "Eth1 monitor": ]), blob_gas_used: 0, excess_blob_gas: 11830672376638423068'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x09902c0e95be295a0b550efdeca632b9e9628760737ef80afda66a830d3b3695891d94f7c0504e9d5f7ece9b244ff8cf")), withdrawal_credentials: Eth2Digest.fromHex("0x0cc2bc536712049ab8303dbc403542bf5ae5b2308c6859420ed950ed9b221567"), amount: 13281242819623749583'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x08c9aa65cb03faed07e92003192d98e83a9026d2c8b31ebdaeb70a21809d93e87351482aa9f49b039a1de250ae1a0a2cf9104c23165ed658e433062e7b8cfb26aecd8d73be477745f9e7f4da7927dfb300ef82157a66936b78582344f58468f0")), index: 16878503552918350820'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xb49156fdde58af27ac558dcf697f2eb2f2c92efd5b455ff736ca88258d9c2e7b77989585dd562da6eed32b228e8510ea")), withdrawal_credentials: Eth2Digest.fromHex("0x4e922c8a3cc2bc7f5ebf9733c67d76f338e7902653c28248ef967047a9875835"), amount: 4089107267451814479'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x9e2864164d275e436ed45120245d2063dbedc87d555cceabe8c18622fe462411ecbe7fa4a262989a45795efea09d21f8e4254cedd5c787bf80211be0a3c6ffc1bcc5f364387f32f746647e0194a599653f3af5f6e1151244df02bb7b3f7270cc")), index: 1665528005288012054'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ ]), ), (electra.ExecutionPayload)( @@ -1864,33 +1864,33 @@ suite "Eth1 monitor": ]), blob_gas_used: 17909098553568904023'u64, excess_blob_gas: 2561776469828429184'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xab3432ddf2af63c4fab5af4cc8bd2e73aadf316f2899b88ac2d81cce54476a401f2c6692b95a049a559134c160ea9588")), withdrawal_credentials: Eth2Digest.fromHex("0x4efa2bd51acb05fda811629ca1fd71fb77f4523a26087e25f8f6faeea76619f4"), amount: 0.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x2303cdb9d265dfd2ac3923c45ac94797eaec8188c244c8b9c7480d55db3d0e33876c14abd1cce784c18d07ed474ab7911b29e5d0343377d923a21c6a4ef6b0d302075a1aa9e7341e22aba6aa5b139b754a3b99b80ecc5c39771eec11d456f210")), index: 17835217878031055704'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xc6d41b4862a8b3c4dffa9a2550fedd5598417ab02715a841d91e13688bb2a3f30e22a1bc60363a77dc95b6bf0d7e0df3")), withdrawal_credentials: Eth2Digest.fromHex("0x771668e08e36fb5974e56502c56bfe6a9b4976e6954e845b416fbed33c18c26d"), amount: 0.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xdb8c8b42b6796c13f5737484f6da27b7eb3ddc3f03195be0cf6a484f34bb5e5da5ab4276222ce48b84f2b80e3f40604ec0b20ae0b451f4f25e598f483fd99d5b158ca0dc102de8c11c2713992997d7bafda9bd719c7ca70480174915d76bfe73")), index: 13902730600946299592'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x6b841e43fc2268f72a78f0c77d57c4cc6d0b87686a435813c3f9af9a87a01b21b5ca1c6b54ebcaf5e861c7cd66244ac9")), withdrawal_credentials: Eth2Digest.fromHex("0xbb1071d3f5aa5125b1d01442d9d82812dff796db2d8d36b590c1ea66ec945c33"), amount: 16549762982203261123'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x6d18d257618a085090dc37a79c3f02b6a7145f27d72736abf90cc4a1fde6a00b2670d86243ee71efbe5819360b53dc2263784457be537b0325e7b080507d78f0b18b839acbde966f3bd5567ebab939978b00b5b996f1632d6ef5aafefd3c8e6e")), index: 3347786845438227400'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xd424dc39bd77478209cee2c04bd9dedcf60823c4fabf724d0aba4a2d401a14a9b5e0cc0b6a2058e8165177c70fde7767")), withdrawal_credentials: Eth2Digest.fromHex("0xe02ee40d601028257747b8a429c224fd401ac674454ace65280f169eca07cec6"), amount: 7324985409398823338'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xca03e6b82cd3df289ed574c2deca216a089928bc944abd3efd26ee3124c45b22e7f541c02cc95f71ea8b52f0fed044ca14863b651c07b6e52abbce8afb500556a32e33a5f57a33ca6103237aa1c5bc409f4a2745b9828d6eff5360a2ba63d162")), index: 18335046601207607970'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ ]), ), (electra.ExecutionPayload)( @@ -1939,16 +1939,16 @@ suite "Eth1 monitor": ]), blob_gas_used: 14543409578714974146'u64, excess_blob_gas: 0, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x7ad7353de5ad5fcef75b9e4c275970a4ad4cd5221ac692d5ee7f51d26a35a927f5a67d3540c5d08667772f78284a4987")), withdrawal_credentials: Eth2Digest.fromHex("0x1320977c1ca99dc4970e49e5d49c5f81fb3bbbf17ccf5b7963c070ac31bb893f"), amount: 0.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x42a5b14b6d5018eedf1dc9bb07cd64ae2d25f583ad805d58d89b4c8381db8740fe188a70f1a1d2eb0e486807cefff900f93ebed94fbe2539edddf06f91bf347281f9dcc891db49d6107c2f88d678d32e5e9849a2be7b082919edb769b7c70abf")), index: 16997402741851403011'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x4bd763bcdfcf9fd2ce667c75408bc1157fa9730a"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xdf62e8946d1457a50ce017fae0c36e5dc5177e642c18b74dd6df192620f8a32bef5f02453f0835583f6082f213df7245"))), ]), @@ -1976,37 +1976,37 @@ suite "Eth1 monitor": ]), blob_gas_used: 9156166815001018661'u64, excess_blob_gas: 13354810927429053716'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x6ce4fb12127809ce5bee8b8bcd25790df1df55b636f64ac7cf646af8d20e4cf3712a03e55b77f37be494658cc79beecd")), withdrawal_credentials: Eth2Digest.fromHex("0xf4192de759e26b7fafdb9342168586029f4526dc67ee8b161dab7e057d060176"), amount: 6209827226225403552'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xa829b6d810883c32466e2bb858bfbce89865f1d3fd71883e4e8b8d7df83c6a18e96e477249a22f0a7b16efd177b982e043f3cce23127c95fdf4e809903a5a906103c25ea6fd36df3f61c3d7feb00ad49937ace39c5ea44767d7f627d25572156")), index: 6407923788439683512'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x5d0d1f7e35e59873d58f7a723c510186deb7f03b3fc0074d1d6ba90f49ccedfe7b262b18c7f362a7ef81acc98437e188")), withdrawal_credentials: Eth2Digest.fromHex("0x0221b17586adfb32e428829e7c90c7e5d8af40f26534a1e82658d887358de265"), amount: 3864819260875678713'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xfec65da38278820cfe4168de78631f7b100146cec2d4aa3002ca3a783e81ca95954351666be524ce681e4a5799f6fc47a092baca86727cbb024013415c832f8a45346e30759753c39bc6e5e17d963f7b7483f4bbd3cdaf7707ee5b51448c2516")), index: 0), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x2ffd86a5a167ed01e994b0b42077e5df2d9703560c6e8d986a8025f28c316ab4f91bcf3d0fb285c66bd9558e32165f8f")), withdrawal_credentials: Eth2Digest.fromHex("0xf2afb039d649f80905f7b2f37927be964d1c8be69ff51afefb87d597d03cfacb"), amount: 0.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x7132e4495443a0542cabf627dd5952ad0e38d000d166045c92b3360835de266511383429cc8980eb54730d8f4ced119e95452d3fc53c8a6f02da22239376356ed9bef153b632b928314835175d493dfb402f4d07ad262e9330baf5f3cef7b000")), index: 8224197877093273527'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xa6ffac664fa1f64295679cbf163ad8f1716be062460e2a645c87d11368a4119d4138311d45506867c8c75d89aeb905dd")), withdrawal_credentials: Eth2Digest.fromHex("0x7cb1f70fdb82a4c7b8415df98d90140ec58fa6422b7066b2da2d4bee20d95d65"), amount: 6485560087895553151'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xbd837ceae239191f7e958fabc91efc7b3830da9814f4d888ec278ed0fbf870e811db948bf81377fd53339db9095f3c71b36de09b6f5b38a18caba6d3e8f337bbcb107380ee3d50058e3d266653860b1c6a9309eb60f142948f53041a07109f4d")), index: 2237248193846176262'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x614d16bedf5dfe9d06171e3ef50671e66fadfce4"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x9f92a4aa0e58f82ff2ec0bbe4aca6d338fd08ffff3213f64bef81148f7dbb163eb25add8ccc540ec0dd1bf9d237e26f9"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x4cff44c8f0353fa6dee31f6c87e4b8c3bcaf1c38"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x3166f8e41daae4a0af1549a00b95ad9280d73e91a882d49c827bc078c88300264e7171cbbf50e3598da77bcdb175a203"))), ]), @@ -2034,34 +2034,34 @@ suite "Eth1 monitor": ]), blob_gas_used: 0, excess_blob_gas: 1597862542620394734'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x324b63f48d1a5e1b0858799c200e774326b0487e3037f048d20462065e42065d189b1419b018b06becdeb7ed46eacec6")), withdrawal_credentials: Eth2Digest.fromHex("0x98b06ec79f8c27a94d13de9774ef0e8756a08650654771aee335ac0c4f14a36b"), amount: 5951406920150253456'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x3cffce51a48cb97b5ddc300c82cecad819bf8d7220e95785908969adc2fe81a4c54ca561b751f8f8afc987bc232b75c3fc590368b51433370bad030aadb7a9f7e5975aada8f6c8f8954fcde7892af4f957daf88b544594d1094ab10072e2efd0")), index: 6209810282279082517'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xd40cedb2ee345c1106a11b9df2b99b7bf6c87172052a084b7f51424b0eb5cff3b9de788124974d89ce20bcc41d12a3f0")), withdrawal_credentials: Eth2Digest.fromHex("0xa31f86305d23a833cbc2f0ab5bb3d7eec6418ca06e2bd16368cdfd849b43a592"), amount: 6087805632659367228'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x7a4df2b27bded4e1cc2e20120e70f576e9991369d77dfad54186d3067416bfe1f7cb7a1021a9c0722370680367fe4c12e571902c2f4ce4c2754a4738c10ead67b1d9a1a82b2ecd4ce3b6567c87e0066c979664bf79025851cd9583c5ed2f7c2f")), index: 4361690020859323832'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x9c2b1570328c29ef47c715cd021aead97695741e"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x6d3da7dd6f61e0818830bf11df8c91af8be664041d8832ca48b0c90566963acaa54695da7fb9ae2904d1aa0d7de5dcbd"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xf3fff390ae583278167deb91dba09b4ba089acaf"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xaeaef2b0928efd727bab75c3859118681492d7aaa0ceb7cb0897e21d4689ce7a6a9306850b2dbd801cb3ec165bb97d68"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x9a89ea1df940046760d3a84e134ea525a05a91fd"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x7afe11eec6aa2da5eb2bb7f9c6f2329ef9b9c17cd2f2ea35fee5e4169bc4e26c73c30cbbde16cbe4ae2351266454c31f"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xf77580ffa7329925db0934de5f3667b1a32effd1"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x3f5026c08a653bb8cc9f46a5cb1c35200c43efb6c44f729b48d12400828f5029fdc88f4672f1f9393d7d764ba3599bf1"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xc61710d4969b77326cfe3ee23b65023c23e8789e"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xb2952e0f7d6581c3032f95f4908bf76f6df8d7e866b7b67996254597ef73ce9a15dac375b78a3456d4f7f156af2b5ed5"))), ]), @@ -2084,13 +2084,13 @@ suite "Eth1 monitor": withdrawals: List[capella.Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD].init(@[]), blob_gas_used: 1, excess_blob_gas: 1, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xe4bed2d5de111ca1d0a77bf6006c09ced6c6cc89"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x814d7cd0b6d428414fa787584e1eb52a5f215b8f0e7792499365f465ac43f5696e8d18ab579568c348f6dde75c189301"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x95137ca91b36a9a753441d911bdf91677931615c"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x0e223fadbfa2985e293f13e083bbe22a9a208d0e9f37fd99d24be92b3e329d77f1d40d61b891e2bdfed12ca746eeec50"))), ]), @@ -2118,28 +2118,28 @@ suite "Eth1 monitor": ]), blob_gas_used: 2533380168586417970'u64, excess_blob_gas: 307516487526704997'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x4dfd0237e85c7fa842fe25ed710e4b9394731e38a27f2adaf03f7c15c0478917d31d93b7acab73f6af454e86dd24b99c")), withdrawal_credentials: Eth2Digest.fromHex("0x6cacb6bd39183416e6bbef6f4725e4b1ddff84fe80f4630183f2cbed9a23e135"), amount: 0.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xe7c07da5cb5f8fda5223db042db39643418920beba7e66d1e3bcc3ba6e80170a6846caa6d67a544b3863f57eadae7d86d09d3767a20d1568b4796b32288156dda21a6ee036a47b51a806d2c27724e7ee4f974bf03116b85184a8f41c53f068f6")), index: 0), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x7fe03a03b1e91c134ebbcf8d3f80cb282b2f8f06659e80681aeba55b08353fd4306f6ee71be7c1f3e64df0d3ca945a15")), withdrawal_credentials: Eth2Digest.fromHex("0x656c24211a240b215d2a7d97a5410fe7a182e34b255e11627d03c51fb9e5c3b1"), amount: 14255636113874187022'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x8e0886f9bd55885f102852f38c980d2bd9304fab0fddc803f4233251e4c5ce891fbd53d8079dfccdb67dfd7f713fcab0c4f9e10a6cf5cdaeaf9195827b6579d36b8822e24631c1c9022d27f99cf414396f3c889e2e24d58d547d79c27291e724")), index: 12470930277850569937'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x629474c4e5a9d1ffc7507e388d86eed83cf0762eb404ddb5860bf575ef4f6a7ff3dce8a63a09375e3a9a5a49fbc6fb72")), withdrawal_credentials: Eth2Digest.fromHex("0x48c7a56b506f4838f3dafa9ba67e43a3aa2b681faa6b573ea68acdf55679f15e"), amount: 14112283334180796705'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xc614759dcdc309a46d9f24ae6b2840625bc5ddecd802c2907f9141d9091966e3367d78b3963717877a6110d741f40b45486acd32ac0e7bf1b4c36e681411570a7d1156dda127c1c5e5c6011ff857222ea51086016c01346e6cd2c8764bc7e7f4")), index: 9892892756897161299'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x9892501906b7abf06fdb6893b8e1767884bc17f5"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x30099e0ee2adf0d51a0a96d10fd2fd5cf6f17cdb4b4ea88b5a0e205bd10d40319595e0403891aaa1bac82b980ef76f23"))), ]), @@ -2165,21 +2165,21 @@ suite "Eth1 monitor": ]), blob_gas_used: 3541847679255581458'u64, excess_blob_gas: 1, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x0040411f8a57799b620765d6125d09ab8aac3074bd7ad75c4c02c99e819e63ff37882940702644921ef7509d48e45c4c")), withdrawal_credentials: Eth2Digest.fromHex("0xf601917dad8bf2e472ad4da2affd60b710264fb1802aacbe796acbae3bc26930"), amount: 3582020308334691622'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x811ffff27712770001d25199c5f1689ef102362da9a617fe7a9db13b50949c705defad17795f52d4db786e80ee3b963b402f5cbd4772bbca81893a104f091a2b11f025287250200fdcee4ad1fc20d24cee626d89c5d05360e9d19e94c8e129d2")), index: 9118657603155344378'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xeec8485a98937b5c18d52d02e8e52ef6a72ca2d0fccc367816789d49b9596e1814b63a3efbc4faf11349f360abbdb046")), withdrawal_credentials: Eth2Digest.fromHex("0x557778b1a01594a2fc0bc05835de388ff3c141bd3141820c286fe114ad14e80d"), amount: 5881642850443225888'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x967057d2edd3b53ae9fb665fe668ab2319403b4f8e4620064b11f0933f9def18d952cae5f50395ffd1a8e8554604d95371b7643386df808a18c913e186a7a915e5a5c65908dd6668f2c0d02e404eb88d3499c096967e93b791d814429caae9a2")), index: 7603599240231509693'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ ]), ), (electra.ExecutionPayload)( @@ -2202,16 +2202,16 @@ suite "Eth1 monitor": ]), blob_gas_used: 3410596457491766161'u64, excess_blob_gas: 0, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xea1c8a68747bf78cf13fc0035612547fa9b98da285369c234822eea879ad1c86c5c7d5516db5ca374acc023a21ce0477")), withdrawal_credentials: Eth2Digest.fromHex("0x6cc96c66ac799953125c24b4311e703728b294ca302ec0dfe5e82fcbfe3636ea"), amount: 10141350867210496320'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xd6a92f4de599923ba4955c360b2cd54bd544e2b75947127fefa9ec08f5e53cf02bf398b63a0420226dd356fc5d50683eaead8a5aa8a6d4fdbe62296506c813e5e02a2513b6457c1ca408e1189fba32e80d74c48e389f62c7b0b0ff3c1881ec55")), index: 14462442824619447645'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xf55f4b626328f2b7a725d8a3f8485072eebf7f6e"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x3eb1812d045ff1d2f7d96f919c41230db2993ed8194de6ba564fad54047e3b45fb925e5216cc47f69e184a4e2c45ce39"))), ]), @@ -2238,40 +2238,40 @@ suite "Eth1 monitor": ]), blob_gas_used: 15366131400223670470'u64, excess_blob_gas: 13352270791962864689'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x1e9d9b4c3b9ade4b4835d9ca67aab333ec3019b775960c734627ced08ff62080f47879339cdec66a6e3c6c54adcf5004")), withdrawal_credentials: Eth2Digest.fromHex("0xfae4f9dfdeea6379f5623d452670c431331e5cff819bd1f3d1cb24f5f34135fd"), amount: 18192096631954481393'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x0c8407a90cf206e5233d3c702e23dfeb2238ce281cf00764fdfb3d12708babd45d21767373a0c57231f20d2479cc0fcd88b58547c0281e76584f709b1afe4ef4bb0b65db3a3bf9f87e1e11fea88caf23b4ac9d9b84efdfae174628bdea84c7e0")), index: 11885726942708777117'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x5ffc8c61c4ea561e6de463b54a9b09d9d467fb3db6149c40e5f0006c1840e605bd26b92414e61041c6c9f7527920d346")), withdrawal_credentials: Eth2Digest.fromHex("0x77e707557d73e53cc2ca694428e99b2acb9e56cfe0f55afa5e58772a533e9e61"), amount: 699724654155768223'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x597938ce07c7c767bf0ac21bbdb56e9696db13044da930cf916b01648db8ec1ef4a989e483b79a381c2de2cd42a5a01ba96df21cbf71107330eb23e5de99797ddec2044c83576a7567238230d8fe19f421986761615c6ce1cb66502911c65e56")), index: 2345813180163742962'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xd8ac112850aa690da757eac4bd7726d222e04c48e22ded62e24880fa4419948cbf5a2325fe3e1bcee205f733a308a39b")), withdrawal_credentials: Eth2Digest.fromHex("0xb796c0757bcc940a422de5d3f8fc4aa130f7c9db954846330a23dc021bea4b61"), amount: 15859650167034453942'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x2f470357ded569d4fe968b5da6619cbeb414271e71ec7abc8e0e6c7c962b1932934bef085f682bc6af358670bdaf80572dd4ee3fdf80711e60205868aad5859971a858f30eaeee2883bad62b5c4e6ada3ea38ae1ab516f294a16b18c099fa760")), index: 3956355178667798015'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x98410af351e5be94f9d37f7cc9f97a85e9bd0dad"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xd96132438444f4582e21aaa4950d907a84d56f5edaf5d4262439210d6b6aae00ef67d15caa1e95040484b977ba677f31"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xe640e25259ffe5aa8b481e98684b41a14f3d2192"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xfb8bad5edefcf4a76157dd4df48c345b10966ebe21c5265519a3d166ee6f43b92bc67707a7bcc478c05cb5d5aaa5e217"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x6544a67710ed5b8466aea7bb74de9e275c7a7338"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xae821baad66de4d33dc8a8ea9088ab97cce0be2f1be1243c3c640377fd57f3f7389087ace339f953d52372d198300f8c"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x48f380f0b267ceec6fbe39f80b7108991acf97b5"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x2c9a9040e72e095e347f8ba9ad33947a1ec5ffddaa2e86a112fd73c30af209625f1bf19eb7b4fcee28409707679781d1"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x04fb4574aa211ef818aa9c13135f20f4694b8ce3"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x8d381b3ee22253692bd5861ede4c0d62cb2f6c90df6afd180831ec183ac3f8bcccbbfb5fa1f3ee38d5c3871ca8e28ba3"))), ]), @@ -2298,19 +2298,19 @@ suite "Eth1 monitor": ]), blob_gas_used: 0, excess_blob_gas: 1233408100755176706'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x16c6ba72f97bd60af3008e747aa0045eace969dd"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x79b68340894f69a82de6d6ac26b6cffd1f84be9008f7cec5a8f740c5dcd73103e50366cb45ec0c2a0984b37597011784"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xf950853d752ff1e8dfd3ffb9bdb504e851361060"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x9924a9bf1759d436f9dcc185cdb646d06af53ddf9e86351b69bda506eaaf4b47739a0737ebfcb7d734d33237eb77983c"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x7ef709dcc026c545a1707a4161948637f4c1afce"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xfe1b2e2cd818d436f9cfd7ad7e9efb8e8940bff9ac2c5094793d26f9a50f76436e25b40d375d7b9d461ac7fac81887d3"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x1e6d99ec506e2b79322f77283f3e18dfc0561346"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x25931e58a52265a5a90f7004706cd736fdb762d50aff67039d5e0242039dfc49fd6670e6f4cf62639d7debe3efe5298b"))), ]), @@ -2335,34 +2335,34 @@ suite "Eth1 monitor": ]), blob_gas_used: 11215270247452431947'u64, excess_blob_gas: 0, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x44142d2fd3abda9800ef805779e63c7ea88068f2b2509a92a2e05f61e0fc9ad1c2272e96db6ae6fdee235dff74917afe")), withdrawal_credentials: Eth2Digest.fromHex("0x65d4629f775514b46c0e413f9bf42f52cdf46f75a2a2b7b22e2a2a6b635adee4"), amount: 18375333628189344873'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x436fa460d6fce0b4df72719d42d3d7e992585fb95c573868478c2ea343af6755c702fa84cd5bd6d237688d6905261c52f9d45ae52acdfe95b6de2e34127df773fb0d32d231f138dfdc3c3837f68ba77e7586f64aa5dc45c2eb0d44a61fcb29df")), index: 11602205279250285026'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xb5ca0fc53760118a8c10c994d885d409fb93f07196f7a8bad868d5b2275f925db9119903e180d1b76b4aebe2ec2bd1d7")), withdrawal_credentials: Eth2Digest.fromHex("0x7de076e071a5916c3c122a22fc9853b6c31712c7ddfe128216bd5d87784cc008"), amount: 8755851176211479347'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x0b7a4a77b5554a3be5f9338c31158e9f0b0b5fc95e9ef176ca38183ceb3aaf214711af03ecf194091cbc99a11aa7a376d721b3c1e27e71447828326ee811a07f4680c5a73fb52106bfe9b66eadd40cf80f027f0db90e41c77c78552edaccf295")), index: 659556622372086172'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xa80127ae927ef2fc72e527bee414d2a899e1050f"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x463d04b11a5f2b3a5ff5d93f7c20acb46b06d8a434d9dcbbcde024be06f50b6542ebca1a759d8cf8381e7142bce4bd1c"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x91e2ec291b66f267104a11157c46ef32fd40c22f"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xc05bcf497d5e305552b041c7a239536c938fff8bc755fadd28fd907f070f7f4a5553660a3351739a0b1bec2e6ec3d2aa"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x1281069954affabc619e8092861136ada40cb869"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x781f234560ec5d2197a33908a66fcb156330141f51212a51a0f0117417b5370f3fd0266c9dd1bf2c66d47eaf98375327"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x56855acbe00c442f0d20d489deb80fc02b31a173"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x805d72db2998bbfaf07d13f5328db300ea7a2fa156d049bf072590d61dca40ae142de4a204e36768f6e546af62d7e1fb"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x722d597ea5a6f82a0f9b06bd8af0449d18f78795"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x1de64f16597d52214d1a5987abc026398d310712ad0db48d48e747e7783204579a886bbd9a58a47704d9874a83726a50"))), ]), @@ -2388,13 +2388,13 @@ suite "Eth1 monitor": ]), blob_gas_used: 69111814634726666'u64, excess_blob_gas: 10785611890433610477'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x027404a69d1a1a8b931d0deb6ef4c90cc23fe74e"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x144cd543ddf6cc88499595246d2373629467e69048b4c638824b8c4d82296fb635028f495c7516174670ed1c5b320462"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x748168ee6835196ae76808fe3232a422b40e42a7"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x5e024d736b5c4d340929745f59b7d681eeb151107f895a87d534491b5af13fbf7bed890a2f41dc8debacf2f65fce2c20"))), ]), @@ -2420,31 +2420,31 @@ suite "Eth1 monitor": ]), blob_gas_used: 1, excess_blob_gas: 10155937412879977460'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x5333b0180b311e552ce6b94225290f3e948b601845d628ae8137bee6e5fc8ef65d2eb2948cd564f48f40a39107d425a0")), withdrawal_credentials: Eth2Digest.fromHex("0x311c904177ac7dab28a516a2306e47550b373338232eb146993204120e838a1e"), amount: 0.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xf1dad35f740e178ef1aac4df7470becd0bb2d54767c04cda321ec2ff9e74fdd9ab1e42d65fcf2e1fbaa42f0f0de36e7d58f300de706ce634886c6883b36c517cdc411c236d984ed9568f39111d562360c1f61a066b30a0e7b724b4f5bc5d34b2")), index: 5781210920531179973'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xfd253bde6458c872a3052a365ed5fca973dad3a0bef826f46a14c866bda1bbbc1c54c8117c89ec6fb514cb358af293dc")), withdrawal_credentials: Eth2Digest.fromHex("0xd9471e69c21bdfefe367eebff0f5500573ded27a7793f9a1f9149f6997f750bf"), amount: 439091423098684932'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xddb1aa7c758a9513fd8ad0a0cd3332a9b9411d7a0795e08591f363b5b4887b4cd4e4d22c87ac9c62a5aed65e3325cb4451d9c37539c1a9d6d84e69f38ddb0b7fb27e6ed7d744b95f5dbaff6b17794fd627842c652884f46c293251bbc0c8970a")), index: 16197400268122174810'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x08dbad1402daa1c3e58e1cac5bdaa36704c9d21df7772d734f4fec1f770140dd4779646794d47c4df0c55adc130b89ea")), withdrawal_credentials: Eth2Digest.fromHex("0x3969600fb0033db2f9bf9718367ffffdc6044f53dd397042d89c822887a72bc5"), amount: 18281837285233220396'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x655e809ad38376a8d7fdd895a30d8a1ac52861864f67e1ce885cc40cbdf3ff27a8a6f8cb1b33f74254c5bfef90de22f6b1c724e888d284438995fab628ecdc5278319435192ed259b56ab6d2f18ad3ba53aa534e85fa802e15c1a1ec9fe3b7e1")), index: 15032238460111462081'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xc8bcdf0144cd4eb45e62b4fa76b7d5963fa912ec"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x4569a134a3f6e0ac638b19e8d88c9010f7281449f78adcbad225d11d2358790b2454504ac56209ac54cf66d5df779bce"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x308d3b908ce2fb2ebd207120422994608d8c3354"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x3deec67ff0f69aeeeddf322043b694ed4ec79aa2cd2414797bb95da5691b2b9731d3fe3d3627684d022241f80504f3ad"))), ]), @@ -2472,46 +2472,46 @@ suite "Eth1 monitor": ]), blob_gas_used: 7080212387270627767'u64, excess_blob_gas: 17322910515629142083'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xf08f319d0ceaed0b05713852711ac610c213b902e2173d8db62f1eb6aa3a6beaca49c48e76bcc5a25ed6a16d949fc2cd")), withdrawal_credentials: Eth2Digest.fromHex("0x166df75e231abc5e67a30cbe8f8392df207b0a203784d5cfccc8d757472defb4"), amount: 0.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xaadc232ca2439def6d7ef995342870dd330c245f46e5cd42fcf1a86a491f65baf722d4d8cad5faf0c66920b17bbad2d92bee6db09afee46839beff07db973e8515da6c77741396a4c844400c7d5f2f9cb815a4fc14dc12e85dfa1e265c8f8e52")), index: 11769346303267269586'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x4ea1b17de1819b452f77c0ec61ca191225cd3d21bd94ebaa8f63eaf87b2a7e131b45688d8187b5853e25193bee3f5586")), withdrawal_credentials: Eth2Digest.fromHex("0xabff3296e33aa3656c2911cc07ed003b5520db5ad937c60b3ba70423d25de9ce"), amount: 13132016002583744347'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xc544cafb21de7664dc3f6e49fb1d972bb9b0e84672889c29116cc08af20191c09d1078f70f5ebdfadfae76092cd5bc3328709703ec0aede57f8a339a2cea50d76f3b14b26dca2d6d66c5775190896040d91c38ebe45b642ed48a224c300f1353")), index: 0), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x926949c6a561ac127c2d6e7fb2fac3d3df36abdb91aaf857f923cd43645bfb76bf75c4afae07aafe5f4c7bd8d2aff312")), withdrawal_credentials: Eth2Digest.fromHex("0xbd953da5243317a12f8088fbd1483795ed953b05f49e4c82b7b95a93c7fb3347"), amount: 12812987719379600277'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xac73e1dfb07bae2ee700bf7cd09a10a39595491047e708d4e47c7d7149f40853657ca564beda87b00e4bc164122c0973ccd9df366b274dafd8bd949881c5ad6fee9f0abcfad2677481f41ca4a5df978ae1f26d783609772706c9c3ef1c35a54f")), index: 18434818685702059208'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x013f9a9161f2e1a9235ab5ffc2e8968cdfed7126341ab0e0f3ab176546a3e2cd3d0d9c8523542ebbbaea50b6f096af47")), withdrawal_credentials: Eth2Digest.fromHex("0x7be93c7783e230acb77ff4fa480299c5e295f7516325b73e4c4efd987d6a590d"), amount: 0.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x97ea0a8e3f3e73fb11ded1814f4232e8bfb1e7b71bce608f3f181e5609bdaab3ffde52b1ff98d94c3d02ffefa6b3716cd83deda00888224f24716619f685c940da205910227b976bedf7f0cfc16262e2ec48dd837509326c97e329fe666846ab")), index: 8630770799181013738'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x4e4c648248758aaba856a20f8496700f036a9177"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x96902ac59a4940715d171f1d6ec3e03b0c1557fc0100abb930b6626917b9792aabd48ec1bc1e37737c582fe11c966658"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xa99cc4727a81a0abfb662fe28748133420938dae"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x10f3cea6d52558a866988352bef57525f708aecb5fb392af8453e306cf7c5da68aea8a544d71db63dc1057317b00feb7"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xe13404d88c1418f69c92ed12d256382a462ecf4e"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xf8f8cffff4aa7bec351b9e084274b6e47c536671bd559c7fbf110985e684a58c0384ffc314c23c4441c0f17ce33bd767"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x6f9427252a6fa414a6501e0761cf92f0839f3bbe"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x4ca4f660800c2cfa68827299ddcbfddcf2cb01c51dcaf5af1abc5e8f05164846ca26f1c8c884a3e674a22dbfc0d9fa7b"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x14bce680ec1a632aac5f77cb4d5eca52f74bd1e6"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xb4f363283d5276f12a6c2c98c58484c6a6e8e3c7f5b3adfc044d2de76365bef427f8b9ac1e321baa7a611447010f9e8d"))), ]), @@ -2536,19 +2536,19 @@ suite "Eth1 monitor": ]), blob_gas_used: 0, excess_blob_gas: 9638659159857567769'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x0d7bd99094b190c06d115f727bab3974676f30feda394294d2fd7250443e3514868fca6c749b42bf6cf70c9fbea48d53")), withdrawal_credentials: Eth2Digest.fromHex("0x983b0d33e8325a806a21d0ac9bb262e565ca7e094d578876a89501a8985413d9"), amount: 6392806474408369626'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xac560bee8d8dd4dad94f2bd5b480e7799f7a8445adf3e0070747f8b5724d442453fbba2f332cc69af3a450dce80249b6b7afe19340f4fc5dc54a5c0e56cd4c484c94c61480bc56c75eef44e55c1288bd58739b8354caa93da5d2502bb38546df")), index: 7086745948630243467'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x91810ed86a3244c89274f94fd510532cf12d7074"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xbb480d96367f62ab5790cbfdeeac6344e21774681edd0afe64c50b48f4d07795e584468821788948c7d8c151733ad01f"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xe16b15a5256815cf6d338498a5cb0e8ec0d5bfec"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x79b49178606e2a5cda067c04b982d445df7b41d09d4361e5498b7a454d0e8a37a6975da56c3bd20694a3fcb467f7ff59"))), ]), @@ -2571,19 +2571,19 @@ suite "Eth1 monitor": withdrawals: List[capella.Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD].init(@[]), blob_gas_used: 4954178403284176013'u64, excess_blob_gas: 1, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x08396e3d726ff055f903e2b4e7b743fd8c128f4b"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x01c1c045960d8121bc8ab57c4728dfb3c07289818df71893c002352eca51c54f03db8840f608607bea01bd7b0f02284d"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xc7fefcefc468685bc9b8cdd3c4e1ae643952b254"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x816cae90cab4ca290dfaf9f32b7ad508bd82095ec815cd55b9399eee91208d30f79e548951bfdddc60b7e7560f2b9e1b"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x7eef42203641e2f5c21779289b6c48d24d578887"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x738dfea8a133b5fd384bd6242fa58f1119bcfed0cfca93899c95f1670d1460b905134cc91eabb429d2147b5f147d5d1f"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x032d5223828ee1c8943fdacfbcd25ce4bb2eacfd"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xf42315c025ae7ef0e8a04175441e9617b0e315a9e7c8fc5f0a0bba4efc9775fea3a8af9b40c4aa37633718ccb5b3260d"))), ]), @@ -2608,28 +2608,28 @@ suite "Eth1 monitor": ]), blob_gas_used: 0, excess_blob_gas: 4396492484488695305'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x9aa3ec3541db18dc4f7bd8e3111a3f00c0d7c5c096a4cf312e3c91a10ca1a91802c4b7b8bbd657dd30af4f3c365a70ba")), withdrawal_credentials: Eth2Digest.fromHex("0xf26e0fb84321ae08d027c81a3e8b113263c01ba0b5e8b258089e496854c4571f"), amount: 14325001783554754582'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xe3654532d224f33eba82bb7f487098c687c180592f8d6406af9d13e8019f417f4bac5ab12c4da72d85f90af2ba18ae4f1f27984033ee63687635db7a69375b38b48168575926def4ba0cd2322a3d970436ed788627fbb4889bba989114da9b82")), index: 0), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x5960755c394a07ae7c11ab0260a033eb22b0a0f957be785a513878d0ef04cd3b46af090fd6e2bbd930cc345f81f209e9")), withdrawal_credentials: Eth2Digest.fromHex("0xa86195129950eb6a8df3190107c2b84e8ad8fdff7b0720d84c42fab9de51e38a"), amount: 279514025671376926'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x121632563dca7d7a560e5b243d7f27dc7dc72319f1486f67cb41751c5f5a42bd9f8efdd14e3f811e03c84e3ba36295a0cb2313bb9792cfc7d80a1669f0adc30934440adbd665ef96b3c30a2762cbaf932e6eb1b4a1c93063ec7f0b6f6aa2a9db")), index: 10368232928814555152'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x7bee235a632b5f79831f376843209740d409b9f8"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x8f40af9186eb70dea2f3105785a930511368e60d2235055c34a0be1a591c5b580eed67542c89a0f8a024c4a6bd1f9bb7"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0x72fdf4c5a62970c6d6c9ee395eec4dfd6fcca4de"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x540a810f4e9ad62bca1d677e9135d519100012f6f12a8f5105623762ba5de3782cb3baaf63c4a32cf03a036127d6d009"))), - ExecutionLayerWithdrawalRequest( + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xd3a0f8518063d55c61423dce1bfcd2abd9a27a62"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x82bec5cd588df021e98087c703b995075ee1cfde2257eebed5e27f53a3a16903479fa2e6864ab3c3c397cd25b6ba3d4f"))), ]), @@ -2655,22 +2655,22 @@ suite "Eth1 monitor": ]), blob_gas_used: 11199168226748373856'u64, excess_blob_gas: 13194543368024635634'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xe4476f7d26f357eeb0a2c31eca0febf37a9bbd8bb28810101b3d62832fbc63ecf6ae6019bbea00bbf1b786ccd4e5143e")), withdrawal_credentials: Eth2Digest.fromHex("0xc9b68e2b8e85dc344cb56a8f2b1930ebad58094a8724e64d7de0b7d39178abb1"), amount: 6807629444642690487'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x742db20aaebafe1bde890ff9a00901d9b8e2ff5e1f27ec96d0adcd4d058fc4b7dc8545931f686c71180035d90eb61c107f96b6f401b75afaa4f4824bc9085c8bf7618f86e64e04d0b0779e54dfc6b9188c4dce82a70e383298403025ef634e6c")), index: 8242431675098722712'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x9cbfe60e6b7fd6ca80f047492eee67fe83391b71ae1d70e2e6e7143c096e4059897f3033cf01a266209b974f1accf9d1")), withdrawal_credentials: Eth2Digest.fromHex("0xdcfd039ba7148cc07212f227be45fdc329a499b8b0ab074dda9c6fa0f4534066"), amount: 17558068707432308727'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x8e274ccbdef898449a07a296386e5983ec423f7ddee02bb9d480ec99dca4f5074b8f6cf469758a45586f031e2ae0a5448aa133531cddf88e9bd2b9fae191fdc817c1989124f1866753fbc833f79fb78f89677df12bc6d288693e5362f2a972bd")), index: 15922103202526011942'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ExecutionLayerWithdrawalRequest( + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xe368e59ddc49ffac6818f01b4be692a517b6838e"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x9c7a489a7498cada308db339f80aafeeff5e38ef7dc5803344a725b3b7f23d6d6162a33798a69660417b8fffb51c3d50"))) ]) @@ -2698,39 +2698,39 @@ suite "Eth1 monitor": ]), blob_gas_used: 6943026604784588438'u64, excess_blob_gas: 4081254329996628499'u64, - deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD].init(@[ - DepositReceipt( + deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(@[ + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xdb77124f3289375b57590aa624baa5feabd0cb05d9b849ddf7fb6c6a19ae6e0e9b2b5f0b5619f8114d2e84f86387b8b1")), withdrawal_credentials: Eth2Digest.fromHex("0xda71d922d0c2f43e0e743d15acf61fbbc235cd7e5a6b5d3ddf0a8f99c09e5423"), amount: 8900470305881875693'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x0359d1b9bb630af7adedef569b58902f861eabd6832fdac38f4ea9fcee0687d5b32beb1762707bb7f197cc7cb7e56a2c5071f0c20647fe133bc807f8656d55ba454adc7c0c82e1d91b6ee2015c659595a29b20c75fdc9eb09c1dd181ca30cde3")), index: 7027910908460072698'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x766195f078501722f6c2250140a793ca7c7e4eedf04a08d7a9046790347feba8b43a07824c279c3382e30dac18e24dc9")), withdrawal_credentials: Eth2Digest.fromHex("0x8033ec1a06aba2965b7e5a44c3195aadf60c733e54cd737c3f08183ba15fc91c"), amount: 18016967842448743237'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xfe46ea45efda7361cfbc8a5436dac3d2906176f219f38e477106a7a1bcb7efa726097a058553f0df0336bc982fcc7ff0ec99a085032d853f0a865639581bf40c06d463a6341f40a0bb5a149e1052ee9cbb60948cb9e673d12dc26979b7c75150")), index: 2199989485519321583'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x3da140a6919e15bbce6592e20deb726c7f49490de1d785f2c6dccacf042a73b3baaf7a8a78b2b845bb91dd94bb4516e1")), withdrawal_credentials: Eth2Digest.fromHex("0xd7ca318f49e1acc9dd1b42088b59d7321cbf61ab08deb200b507569a84b45a6d"), amount: 0.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0xdb1d2894d5f853b0bf89dc64d977608ac2774d8c5f4f59566f4ee3a723caf13b4eb66aca7495dfced5068057516b1ba6106e2af198bb5a0a78ecc47cace8b6e0b570b13b23d58827f756f8947d12187c4f804b49924f9beaa669f5d8690513b0")), index: 2386861599472159894'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x551918d44e257d9a00f2e9307eb6735d5da6dcb6b372a0c80d35b167afca47f6087e0fb2fbd8d3846977bb1975b431b5")), withdrawal_credentials: Eth2Digest.fromHex("0x23d544fec453c12e55f24488f48870115d07946ba266621aa03997f8340ba0c9"), amount: 15504548595993808618'u64.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x8be2d5ec33930f835ba523c8db1d5c47e7719a8844a2339f9a7497df2687efe009dbee6429accd5794272609b3f75ba25c959c7daa30e87f0eada1268363de1afd86656162f95a5b7a76eebae76c8cb3619045fd0050224b77ff1567e590a42f")), index: 17558896845903288827'u64), - DepositReceipt( + DepositRequest( pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x920b41013a660d49b8ec1651d7ed869b0812cab03ff409e32b29beb8d8d74744d5d2375e40afa7da019408552026017a")), withdrawal_credentials: Eth2Digest.fromHex("0xb8f6d6891169e1fa957873ae437ac92f650dbf32f0ce5dbede96926ccf755d52"), amount: 0.Gwei, signature: ValidatorSig(blob: hexToByteArray[96]("0x232d34989ba30727e4ae0aa874a4bfc3934d61d0295d8f1c5f8416523f5cd05a3181a03543ff7318c4f4b9207d006267dde451177612bd888f69b43ebea83a4289cd6615526160d7ecf2a09842d4c2e90ae9f207a440a348ed8ef31e0cf1fe8b")), index: 4403524705240661292'u64), ]), - withdrawal_requests: List[ExecutionLayerWithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ + withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ ]) )] diff --git a/tests/testblockutil.nim b/tests/testblockutil.nim index 7820fb557..15b6c0980 100644 --- a/tests/testblockutil.nim +++ b/tests/testblockutil.nim @@ -229,7 +229,6 @@ proc addTestBlock*( BeaconBlockValidatorChanges(), sync_aggregate, execution_payload, - @[], noRollback, cache, verificationFlags = {skipBlsValidation}) diff --git a/vendor/nim-eth2-scenarios b/vendor/nim-eth2-scenarios index 54675b5f1..fc7a45a73 160000 --- a/vendor/nim-eth2-scenarios +++ b/vendor/nim-eth2-scenarios @@ -1 +1 @@ -Subproject commit 54675b5f1fd8156a508e75991693df57a281642e +Subproject commit fc7a45a731736248b96ad5827a8356c0e14d3b8c From 88fa8b17eab86a79c5960b00c1d8f8192a4201e5 Mon Sep 17 00:00:00 2001 From: tersec Date: Sun, 16 Jun 2024 00:59:25 +0000 Subject: [PATCH 02/68] automated consensus spec URL updating to v1.5.0-alpha.3 (#6364) --- beacon_chain/beacon_chain_db_immutable.nim | 2 +- beacon_chain/beacon_clock.nim | 2 +- .../attestation_pool.nim | 2 +- .../consensus_object_pools/blockchain_dag.nim | 4 ++-- .../sync_committee_msg_pool.nim | 2 +- beacon_chain/el/merkle_minimal.nim | 2 +- beacon_chain/fork_choice/fork_choice.nim | 4 ++-- .../gossip_processing/block_processor.nim | 2 +- .../gossip_processing/gossip_validation.nim | 4 ++-- beacon_chain/libnimbus_lc/libnimbus_lc.h | 16 ++++++++-------- beacon_chain/libnimbus_lc/libnimbus_lc.nim | 18 +++++++++--------- beacon_chain/networking/eth2_network.nim | 2 +- beacon_chain/nimbus_beacon_node.nim | 2 +- beacon_chain/rpc/rest_config_api.nim | 8 ++++---- beacon_chain/spec/beacon_time.nim | 14 +++++++------- beacon_chain/spec/beaconstate.nim | 18 +++++++++--------- beacon_chain/spec/datatypes/altair.nim | 18 +++++++++--------- beacon_chain/spec/datatypes/base.nim | 2 +- beacon_chain/spec/datatypes/bellatrix.nim | 12 ++++++------ beacon_chain/spec/datatypes/capella.nim | 18 +++++++++--------- beacon_chain/spec/datatypes/constants.nim | 2 +- beacon_chain/spec/datatypes/deneb.nim | 14 +++++++------- beacon_chain/spec/datatypes/electra.nim | 2 +- beacon_chain/spec/eth2_apis/rest_types.nim | 2 +- beacon_chain/spec/helpers.nim | 14 +++++++------- beacon_chain/spec/keystore.nim | 2 +- beacon_chain/spec/network.nim | 8 ++++---- beacon_chain/spec/presets.nim | 2 +- .../spec/presets/mainnet/altair_preset.nim | 2 +- .../spec/presets/mainnet/bellatrix_preset.nim | 2 +- .../spec/presets/mainnet/capella_preset.nim | 2 +- .../spec/presets/mainnet/deneb_preset.nim | 2 +- .../spec/presets/minimal/altair_preset.nim | 2 +- .../spec/presets/minimal/bellatrix_preset.nim | 2 +- .../spec/presets/minimal/capella_preset.nim | 2 +- .../spec/presets/minimal/deneb_preset.nim | 2 +- beacon_chain/spec/signatures.nim | 10 +++++----- beacon_chain/spec/state_transition.nim | 2 +- beacon_chain/spec/state_transition_block.nim | 8 ++++---- beacon_chain/spec/state_transition_epoch.nim | 12 ++++++------ beacon_chain/spec/weak_subjectivity.nim | 6 +++--- beacon_chain/sync/light_client_manager.nim | 2 +- beacon_chain/sync/light_client_protocol.nim | 2 +- beacon_chain/trusted_node_sync.nim | 2 +- beacon_chain/validators/beacon_validators.nim | 2 +- beacon_chain/validators/validator_pool.nim | 6 +++--- docs/the_nimbus_book/src/el-light-client.md | 4 ++-- docs/the_nimbus_book/src/web3signer.md | 2 +- ...test_fixture_light_client_sync_protocol.nim | 2 +- 49 files changed, 137 insertions(+), 137 deletions(-) diff --git a/beacon_chain/beacon_chain_db_immutable.nim b/beacon_chain/beacon_chain_db_immutable.nim index 4821ba304..2b3aef7c0 100644 --- a/beacon_chain/beacon_chain_db_immutable.nim +++ b/beacon_chain/beacon_chain_db_immutable.nim @@ -130,7 +130,7 @@ type current_sync_committee*: SyncCommittee # [New in Altair] next_sync_committee*: SyncCommittee # [New in Altair] - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#beaconstate + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#beaconstate # Memory-representation-equivalent to a Bellatrix BeaconState for in-place SSZ # reading and writing BellatrixBeaconStateNoImmutableValidators* = object diff --git a/beacon_chain/beacon_clock.nim b/beacon_chain/beacon_clock.nim index 19d2d6572..3aec4e75b 100644 --- a/beacon_chain/beacon_clock.nim +++ b/beacon_chain/beacon_clock.nim @@ -27,7 +27,7 @@ type ## which blocks are valid - in particular, blocks are not valid if they ## come from the future as seen from the local clock. ## - ## https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/phase0/fork-choice.md#fork-choice + ## https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/fork-choice.md#fork-choice ## # TODO consider NTP and network-adjusted timestamps as outlined here: # https://ethresear.ch/t/network-adjusted-timestamps/4187 diff --git a/beacon_chain/consensus_object_pools/attestation_pool.nim b/beacon_chain/consensus_object_pools/attestation_pool.nim index 9136d88a2..f4c847e45 100644 --- a/beacon_chain/consensus_object_pools/attestation_pool.nim +++ b/beacon_chain/consensus_object_pools/attestation_pool.nim @@ -1058,7 +1058,7 @@ proc getBeaconHead*( pool.dag.loadExecutionBlockHash(pool.dag.finalizedHead.blck) .get(ZERO_HASH) - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/fork_choice/safe-block.md#get_safe_execution_payload_hash + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/fork_choice/safe-block.md#get_safe_execution_payload_hash safeBlockRoot = pool.forkChoice.get_safe_beacon_block_root() safeBlock = pool.dag.getBlockRef(safeBlockRoot) safeExecutionBlockHash = diff --git a/beacon_chain/consensus_object_pools/blockchain_dag.nim b/beacon_chain/consensus_object_pools/blockchain_dag.nim index 69fcb661a..0cecc7f12 100644 --- a/beacon_chain/consensus_object_pools/blockchain_dag.nim +++ b/beacon_chain/consensus_object_pools/blockchain_dag.nim @@ -1178,7 +1178,7 @@ proc init*(T: type ChainDAGRef, cfg: RuntimeConfig, db: BeaconChainDB, # should have `previous_version` set to `current_version` while # this doesn't happen to be the case in network that go through # regular hard-fork upgrades. See for example: - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#testing + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#testing if stateFork.current_version != configFork.current_version: error "State from database does not match network, check --network parameter", tail = dag.tail, headRef, stateFork, configFork @@ -1972,7 +1972,7 @@ proc pruneBlocksDAG(dag: ChainDAGRef) = prunedHeads = hlen - dag.heads.len, dagPruneDur = Moment.now() - startTick -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/sync/optimistic.md#helpers +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/sync/optimistic.md#helpers func is_optimistic*(dag: ChainDAGRef, bid: BlockId): bool = let blck = if bid.slot <= dag.finalizedHead.slot: diff --git a/beacon_chain/consensus_object_pools/sync_committee_msg_pool.nim b/beacon_chain/consensus_object_pools/sync_committee_msg_pool.nim index 12181235e..3903246ca 100644 --- a/beacon_chain/consensus_object_pools/sync_committee_msg_pool.nim +++ b/beacon_chain/consensus_object_pools/sync_committee_msg_pool.nim @@ -349,7 +349,7 @@ proc produceSyncAggregate*( proc isEpochLeadTime*( pool: SyncCommitteeMsgPool, epochsToSyncPeriod: uint64): bool = - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#sync-committee-subnet-stability + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#sync-committee-subnet-stability # This ensures a uniform distribution without requiring additional state: # (1/4) = 1/4, 4 slots out # (3/4) * (1/3) = 1/4, 3 slots out diff --git a/beacon_chain/el/merkle_minimal.nim b/beacon_chain/el/merkle_minimal.nim index 4b603ceb6..1fe051b2c 100644 --- a/beacon_chain/el/merkle_minimal.nim +++ b/beacon_chain/el/merkle_minimal.nim @@ -7,7 +7,7 @@ {.push raises: [].} -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/tests/core/pyspec/eth2spec/utils/merkle_minimal.py +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/tests/core/pyspec/eth2spec/utils/merkle_minimal.py # Merkle tree helpers # --------------------------------------------------------------- diff --git a/beacon_chain/fork_choice/fork_choice.nim b/beacon_chain/fork_choice/fork_choice.nim index d6f3ed94d..0156a2b3d 100644 --- a/beacon_chain/fork_choice/fork_choice.nim +++ b/beacon_chain/fork_choice/fork_choice.nim @@ -113,7 +113,7 @@ proc update_justified( self.update_justified(dag, blck, justified.epoch) ok() -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/phase0/fork-choice.md#update_checkpoints +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/fork-choice.md#update_checkpoints proc update_checkpoints( self: var Checkpoints, dag: ChainDAGRef, checkpoints: FinalityCheckpoints): FcResult[void] = @@ -377,7 +377,7 @@ proc get_head*(self: var ForkChoice, self.checkpoints.justified.balances, self.checkpoints.proposer_boost_root) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/fork_choice/safe-block.md#get_safe_beacon_block_root +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/fork_choice/safe-block.md#get_safe_beacon_block_root func get_safe_beacon_block_root*(self: ForkChoice): Eth2Digest = # Use most recent justified block as a stopgap self.checkpoints.justified.checkpoint.root diff --git a/beacon_chain/gossip_processing/block_processor.nim b/beacon_chain/gossip_processing/block_processor.nim index bfef52d31..27a098036 100644 --- a/beacon_chain/gossip_processing/block_processor.nim +++ b/beacon_chain/gossip_processing/block_processor.nim @@ -838,7 +838,7 @@ proc processBlock( # - MUST NOT optimistically import the block. # - MUST NOT apply the block to the fork choice store. # - MAY queue the block for later processing. - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/sync/optimistic.md#execution-engine-errors + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/sync/optimistic.md#execution-engine-errors await sleepAsync(chronos.seconds(1)) self[].enqueueBlock( entry.src, entry.blck, entry.blobs, entry.resfut, entry.maybeFinalized, diff --git a/beacon_chain/gossip_processing/gossip_validation.nim b/beacon_chain/gossip_processing/gossip_validation.nim index 3f3a15c4c..c7b755670 100644 --- a/beacon_chain/gossip_processing/gossip_validation.nim +++ b/beacon_chain/gossip_processing/gossip_validation.nim @@ -302,7 +302,7 @@ template validateBeaconBlockBellatrix( # # `is_merge_transition_complete(state)` tests for # `state.latest_execution_payload_header != ExecutionPayloadHeader()`, while - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#block-processing + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#block-processing # shows that `state.latest_execution_payload_header` being default or not is # exactly equivalent to whether that block's execution payload is default or # not, so test cached block information rather than reconstructing a state. @@ -1181,7 +1181,7 @@ proc validateAggregate*( ok((attesting_indices, sig)) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/p2p-interface.md#bls_to_execution_change +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/p2p-interface.md#bls_to_execution_change proc validateBlsToExecutionChange*( pool: ValidatorChangePool, batchCrypto: ref BatchCrypto, signed_address_change: SignedBLSToExecutionChange, diff --git a/beacon_chain/libnimbus_lc/libnimbus_lc.h b/beacon_chain/libnimbus_lc/libnimbus_lc.h index bd6575f0d..7a107e133 100644 --- a/beacon_chain/libnimbus_lc/libnimbus_lc.h +++ b/beacon_chain/libnimbus_lc/libnimbus_lc.h @@ -94,7 +94,7 @@ typedef struct ETHConsensusConfig ETHConsensusConfig; * based on the given `config.yaml` file content - If successful. * @return `NULL` - If the given `config.yaml` is malformed or incompatible. * - * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/configs/README.md + * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/configs/README.md */ ETH_RESULT_USE_CHECK ETHConsensusConfig *ETHConsensusConfigCreateFromYaml(const char *configFileContent); @@ -151,9 +151,9 @@ typedef struct ETHBeaconState ETHBeaconState; * * @see https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#beaconstate * @see https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#beaconstate - * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#beaconstate - * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#beaconstate - * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/configs/README.md + * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#beaconstate + * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#beaconstate + * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/configs/README.md */ ETH_RESULT_USE_CHECK ETHBeaconState *ETHBeaconStateCreateFromSsz( @@ -325,8 +325,8 @@ typedef struct ETHLightClientStore ETHLightClientStore; * * @see https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.4.1#/Beacon/getLightClientBootstrap * @see https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.4.1#/Events/eventstream - * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/light-client.md - * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/phase0/weak-subjectivity.md#weak-subjectivity-period + * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/light-client.md + * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/weak-subjectivity.md#weak-subjectivity-period */ ETH_RESULT_USE_CHECK ETHLightClientStore *ETHLightClientStoreCreateFromBootstrap( @@ -597,8 +597,8 @@ const ETHLightClientHeader *ETHLightClientStoreGetFinalizedHeader( * * @return Whether or not the next sync committee is currently known. * - * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/sync-protocol.md#is_next_sync_committee_known - * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/light-client.md + * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/sync-protocol.md#is_next_sync_committee_known + * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/light-client.md */ ETH_RESULT_USE_CHECK bool ETHLightClientStoreIsNextSyncCommitteeKnown(const ETHLightClientStore *store); diff --git a/beacon_chain/libnimbus_lc/libnimbus_lc.nim b/beacon_chain/libnimbus_lc/libnimbus_lc.nim index cb0c7876b..062f4b016 100644 --- a/beacon_chain/libnimbus_lc/libnimbus_lc.nim +++ b/beacon_chain/libnimbus_lc/libnimbus_lc.nim @@ -78,7 +78,7 @@ proc ETHConsensusConfigCreateFromYaml( ## * `NULL` - If the given `config.yaml` is malformed or incompatible. ## ## See: - ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/configs/README.md + ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/configs/README.md let cfg = RuntimeConfig.new() try: cfg[] = readRuntimeConfig($configFileContent, "config.yaml")[0] @@ -144,9 +144,9 @@ proc ETHBeaconStateCreateFromSsz( ## See: ## * https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#beaconstate ## * https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#beaconstate - ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#beaconstate - ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#beaconstate - ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/configs/README.md + ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#beaconstate + ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#beaconstate + ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/configs/README.md let consensusFork = ConsensusFork.decodeString($consensusVersion).valueOr: return nil @@ -329,8 +329,8 @@ proc ETHLightClientStoreCreateFromBootstrap( ## See: ## * https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.4.1#/Beacon/getLightClientBootstrap ## * https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.4.1#/Events/eventstream - ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/light-client.md - ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/phase0/weak-subjectivity.md#weak-subjectivity-period + ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/light-client.md + ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/weak-subjectivity.md#weak-subjectivity-period let mediaType = MediaType.init($mediaType) consensusFork = ConsensusFork.decodeString($consensusVersion).valueOr: @@ -755,8 +755,8 @@ func ETHLightClientStoreIsNextSyncCommitteeKnown( ## * Whether or not the next sync committee is currently known. ## ## See: - ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/sync-protocol.md#is_next_sync_committee_known - ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/light-client.md + ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/sync-protocol.md#is_next_sync_committee_known + ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/light-client.md store[].is_next_sync_committee_known func ETHLightClientStoreGetOptimisticHeader( @@ -796,7 +796,7 @@ func ETHLightClientStoreGetSafetyThreshold( ## * Light client store safety threshold. ## ## See: - ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/sync-protocol.md#get_safety_threshold + ## * https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/sync-protocol.md#get_safety_threshold store[].get_safety_threshold.cint proc ETHLightClientHeaderCreateCopy( diff --git a/beacon_chain/networking/eth2_network.nim b/beacon_chain/networking/eth2_network.nim index 27616be19..abb900dff 100644 --- a/beacon_chain/networking/eth2_network.nim +++ b/beacon_chain/networking/eth2_network.nim @@ -2533,7 +2533,7 @@ proc updateStabilitySubnetMetadata*(node: Eth2Node, attnets: AttnetBits) = debug "Stability subnets changed; updated ENR attnets", attnets proc updateSyncnetsMetadata*(node: Eth2Node, syncnets: SyncnetBits) = - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#sync-committee-subnet-stability + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#sync-committee-subnet-stability if node.metadata.syncnets == syncnets: return diff --git a/beacon_chain/nimbus_beacon_node.nim b/beacon_chain/nimbus_beacon_node.nim index 69d089833..885647b00 100644 --- a/beacon_chain/nimbus_beacon_node.nim +++ b/beacon_chain/nimbus_beacon_node.nim @@ -1862,7 +1862,7 @@ proc installMessageValidators(node: BeaconNode) = MsgSource.gossip, msg))) when consensusFork >= ConsensusFork.Capella: - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/p2p-interface.md#bls_to_execution_change + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/p2p-interface.md#bls_to_execution_change node.network.addAsyncValidator( getBlsToExecutionChangeTopic(digest), proc ( msg: SignedBLSToExecutionChange diff --git a/beacon_chain/rpc/rest_config_api.nim b/beacon_chain/rpc/rest_config_api.nim index 818dbfe66..801c673f2 100644 --- a/beacon_chain/rpc/rest_config_api.nim +++ b/beacon_chain/rpc/rest_config_api.nim @@ -90,7 +90,7 @@ proc installConfigApiHandlers*(router: var RestRouter, node: BeaconNode) = MAX_VOLUNTARY_EXITS: Base10.toString(MAX_VOLUNTARY_EXITS), - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/presets/mainnet/altair.yaml + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/presets/mainnet/altair.yaml INACTIVITY_PENALTY_QUOTIENT_ALTAIR: Base10.toString(INACTIVITY_PENALTY_QUOTIENT_ALTAIR), MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR: @@ -106,7 +106,7 @@ proc installConfigApiHandlers*(router: var RestRouter, node: BeaconNode) = UPDATE_TIMEOUT: Base10.toString(UPDATE_TIMEOUT), - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/presets/mainnet/bellatrix.yaml + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/presets/mainnet/bellatrix.yaml INACTIVITY_PENALTY_QUOTIENT_BELLATRIX: Base10.toString(INACTIVITY_PENALTY_QUOTIENT_BELLATRIX), MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX: @@ -122,7 +122,7 @@ proc installConfigApiHandlers*(router: var RestRouter, node: BeaconNode) = MAX_EXTRA_DATA_BYTES: Base10.toString(uint64(MAX_EXTRA_DATA_BYTES)), - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/presets/mainnet/capella.yaml + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/presets/mainnet/capella.yaml MAX_BLS_TO_EXECUTION_CHANGES: Base10.toString(uint64(MAX_BLS_TO_EXECUTION_CHANGES)), MAX_WITHDRAWALS_PER_PAYLOAD: @@ -130,7 +130,7 @@ proc installConfigApiHandlers*(router: var RestRouter, node: BeaconNode) = MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP: Base10.toString(uint64(MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP)), - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/presets/mainnet/deneb.yaml + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/presets/mainnet/deneb.yaml FIELD_ELEMENTS_PER_BLOB: Base10.toString(deneb_preset.FIELD_ELEMENTS_PER_BLOB), MAX_BLOB_COMMITMENTS_PER_BLOCK: diff --git a/beacon_chain/spec/beacon_time.nim b/beacon_chain/spec/beacon_time.nim index d8aa9850f..e548d96c7 100644 --- a/beacon_chain/spec/beacon_time.nim +++ b/beacon_chain/spec/beacon_time.nim @@ -43,7 +43,7 @@ const GENESIS_SLOT* = Slot(0) GENESIS_EPOCH* = Epoch(0) # compute_epoch_at_slot(GENESIS_SLOT) - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/phase0/fork-choice.md#constant + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/fork-choice.md#constant INTERVALS_PER_SLOT* = 3 FAR_FUTURE_BEACON_TIME* = BeaconTime(ns_since_genesis: int64.high()) @@ -139,16 +139,16 @@ const # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#broadcast-aggregate aggregateSlotOffset* = TimeDiff(nanoseconds: NANOSECONDS_PER_SLOT.int64 * 2 div INTERVALS_PER_SLOT) - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#prepare-sync-committee-message + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#prepare-sync-committee-message syncCommitteeMessageSlotOffset* = TimeDiff(nanoseconds: NANOSECONDS_PER_SLOT.int64 div INTERVALS_PER_SLOT) - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#broadcast-sync-committee-contribution + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#broadcast-sync-committee-contribution syncContributionSlotOffset* = TimeDiff(nanoseconds: NANOSECONDS_PER_SLOT.int64 * 2 div INTERVALS_PER_SLOT) - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/p2p-interface.md#sync-committee + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/p2p-interface.md#sync-committee lightClientFinalityUpdateSlotOffset* = TimeDiff(nanoseconds: NANOSECONDS_PER_SLOT.int64 div INTERVALS_PER_SLOT) - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/p2p-interface.md#sync-committee + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/p2p-interface.md#sync-committee lightClientOptimisticUpdateSlotOffset* = TimeDiff(nanoseconds: NANOSECONDS_PER_SLOT.int64 div INTERVALS_PER_SLOT) @@ -188,7 +188,7 @@ func epoch*(slot: Slot): Epoch = # aka compute_epoch_at_slot if slot == FAR_FUTURE_SLOT: FAR_FUTURE_EPOCH else: Epoch(slot div SLOTS_PER_EPOCH) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/phase0/fork-choice.md#compute_slots_since_epoch_start +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/fork-choice.md#compute_slots_since_epoch_start func since_epoch_start*(slot: Slot): uint64 = # aka compute_slots_since_epoch_start ## How many slots since the beginning of the epoch (`[0..SLOTS_PER_EPOCH-1]`) (slot mod SLOTS_PER_EPOCH) @@ -216,7 +216,7 @@ iterator slots*(epoch: Epoch): Slot = for slot in start_slot ..< start_slot + SLOTS_PER_EPOCH: yield slot -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#sync-committee +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#sync-committee template sync_committee_period*(epoch: Epoch): SyncCommitteePeriod = if epoch == FAR_FUTURE_EPOCH: FAR_FUTURE_PERIOD else: SyncCommitteePeriod(epoch div EPOCHS_PER_SYNC_COMMITTEE_PERIOD) diff --git a/beacon_chain/spec/beaconstate.nim b/beacon_chain/spec/beaconstate.nim index 8cf203124..340448020 100644 --- a/beacon_chain/spec/beaconstate.nim +++ b/beacon_chain/spec/beaconstate.nim @@ -301,7 +301,7 @@ from ./datatypes/deneb import BeaconState # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#modified-slash_validator -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#modified-slash_validator +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#modified-slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#updated-slash_validator func get_slashing_penalty*( state: ForkyBeaconState, validator_effective_balance: Gwei): Gwei = @@ -319,7 +319,7 @@ func get_slashing_penalty*( # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#modified-slash_validator -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#modified-slash_validator +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#modified-slash_validator func get_whistleblower_reward*( state: phase0.BeaconState | altair.BeaconState | bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState, @@ -333,7 +333,7 @@ func get_whistleblower_reward*( # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#modified-slash_validator -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#modified-slash_validator +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#modified-slash_validator func get_proposer_reward(state: ForkyBeaconState, whistleblower_reward: Gwei): Gwei = when state is phase0.BeaconState: whistleblower_reward div PROPOSER_REWARD_QUOTIENT @@ -346,7 +346,7 @@ func get_proposer_reward(state: ForkyBeaconState, whistleblower_reward: Gwei): G # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#modified-slash_validator -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#modified-slash_validator +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#modified-slash_validator proc slash_validator*( cfg: RuntimeConfig, state: var ForkyBeaconState, slashed_index: ValidatorIndex, pre_exit_queue_info: ExitQueueInfo, @@ -419,7 +419,7 @@ func get_initial_beacon_block*(state: altair.HashedBeaconState): altair.TrustedSignedBeaconBlock( message: message, root: hash_tree_root(message)) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#testing +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#testing func get_initial_beacon_block*(state: bellatrix.HashedBeaconState): bellatrix.TrustedSignedBeaconBlock = # The genesis block is implicitly trusted @@ -431,7 +431,7 @@ func get_initial_beacon_block*(state: bellatrix.HashedBeaconState): bellatrix.TrustedSignedBeaconBlock( message: message, root: hash_tree_root(message)) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#testing +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#testing func get_initial_beacon_block*(state: capella.HashedBeaconState): capella.TrustedSignedBeaconBlock = # The genesis block is implicitly trusted @@ -1188,7 +1188,7 @@ func has_execution_withdrawal_credential*(validator: Validator): bool = has_compounding_withdrawal_credential(validator) or has_eth1_withdrawal_credential(validator) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#is_fully_withdrawable_validator +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#is_fully_withdrawable_validator # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#updated-is_fully_withdrawable_validator func is_fully_withdrawable_validator( fork: static ConsensusFork, validator: Validator, balance: Gwei, @@ -1506,8 +1506,8 @@ proc initialize_hashed_beacon_state_from_eth1*( cfg, eth1_block_hash, eth1_timestamp, deposits, flags)) result.root = hash_tree_root(result.data) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#testing -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#testing +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#testing +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#testing # https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/beacon-chain.md#testing proc initialize_beacon_state_from_eth1*( cfg: RuntimeConfig, diff --git a/beacon_chain/spec/datatypes/altair.nim b/beacon_chain/spec/datatypes/altair.nim index 5d866ceb4..3c3e8fbba 100644 --- a/beacon_chain/spec/datatypes/altair.nim +++ b/beacon_chain/spec/datatypes/altair.nim @@ -51,7 +51,7 @@ const PARTICIPATION_FLAG_WEIGHTS*: array[TimelyFlag, uint64] = [uint64 TIMELY_SOURCE_WEIGHT, TIMELY_TARGET_WEIGHT, TIMELY_HEAD_WEIGHT] - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#misc + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#misc TARGET_AGGREGATORS_PER_SYNC_SUBCOMMITTEE* = 16 SYNC_COMMITTEE_SUBNET_COUNT* = 4 @@ -60,7 +60,7 @@ const # The first member (`genesis_time`) is 32, subsequent members +1 each. # If there are ever more than 32 members in `BeaconState`, indices change! # `FINALIZED_ROOT_GINDEX` is one layer deeper, i.e., `52 * 2 + 1`. - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/ssz/merkle-proofs.md + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/ssz/merkle-proofs.md FINALIZED_ROOT_GINDEX* = 105.GeneralizedIndex # finalized_checkpoint > root CURRENT_SYNC_COMMITTEE_GINDEX* = 54.GeneralizedIndex # current_sync_committee NEXT_SYNC_COMMITTEE_GINDEX* = 55.GeneralizedIndex # next_sync_committee @@ -98,7 +98,7 @@ type pubkeys*: HashArray[Limit SYNC_COMMITTEE_SIZE, ValidatorPubKey] aggregate_pubkey*: ValidatorPubKey - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#synccommitteemessage + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#synccommitteemessage SyncCommitteeMessage* = object slot*: Slot ## Slot to which this contribution pertains @@ -112,7 +112,7 @@ type signature*: ValidatorSig ## Signature by the validator over the block root of `slot` - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#synccommitteecontribution + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#synccommitteecontribution SyncCommitteeAggregationBits* = BitArray[SYNC_SUBCOMMITTEE_SIZE] @@ -134,18 +134,18 @@ type signature*: ValidatorSig ## Signature by the validator(s) over the block root of `slot` - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#contributionandproof + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#contributionandproof ContributionAndProof* = object aggregator_index*: uint64 # `ValidatorIndex` after validation contribution*: SyncCommitteeContribution selection_proof*: ValidatorSig - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#signedcontributionandproof + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#signedcontributionandproof SignedContributionAndProof* = object message*: ContributionAndProof signature*: ValidatorSig - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#syncaggregatorselectiondata + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#syncaggregatorselectiondata SyncAggregatorSelectionData* = object slot*: Slot subcommittee_index*: uint64 # `SyncSubcommitteeIndex` after validation @@ -161,7 +161,7 @@ type NextSyncCommitteeBranch* = array[log2trunc(NEXT_SYNC_COMMITTEE_GINDEX), Eth2Digest] - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/sync-protocol.md#lightclientheader + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/sync-protocol.md#lightclientheader LightClientHeader* = object beacon*: BeaconBlockHeader ## Beacon block header @@ -665,7 +665,7 @@ chronicles.formatIt SyncCommitteeContribution: shortLog(it) chronicles.formatIt ContributionAndProof: shortLog(it) chronicles.formatIt SignedContributionAndProof: shortLog(it) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/sync-protocol.md#is_valid_light_client_header +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/sync-protocol.md#is_valid_light_client_header func is_valid_light_client_header*( header: LightClientHeader, cfg: RuntimeConfig): bool = true diff --git a/beacon_chain/spec/datatypes/base.nim b/beacon_chain/spec/datatypes/base.nim index 2c0249691..346be4637 100644 --- a/beacon_chain/spec/datatypes/base.nim +++ b/beacon_chain/spec/datatypes/base.nim @@ -400,7 +400,7 @@ type sync_committees*: Table[SyncCommitteePeriod, SyncCommitteeCache] # This matches the mutable state of the Solidity deposit contract - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/solidity_deposit_contract/deposit_contract.sol + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/solidity_deposit_contract/deposit_contract.sol DepositContractState* = object branch*: array[DEPOSIT_CONTRACT_TREE_DEPTH, Eth2Digest] deposit_count*: array[32, byte] # Uint256 diff --git a/beacon_chain/spec/datatypes/bellatrix.nim b/beacon_chain/spec/datatypes/bellatrix.nim index cc71e59c4..8e1043853 100644 --- a/beacon_chain/spec/datatypes/bellatrix.nim +++ b/beacon_chain/spec/datatypes/bellatrix.nim @@ -35,7 +35,7 @@ const NEWPAYLOAD_TIMEOUT* = 8.seconds type - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#custom-types + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#custom-types Transaction* = List[byte, Limit MAX_BYTES_PER_TRANSACTION] ExecutionAddress* = object @@ -44,7 +44,7 @@ type BloomLogs* = object data*: array[BYTES_PER_LOGS_BLOOM, byte] - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#executionpayload + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#executionpayload ExecutionPayload* = object # Execution block header fields parent_hash*: Eth2Digest @@ -72,7 +72,7 @@ type executionPayload*: ExecutionPayload blockValue*: Wei - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#executionpayloadheader + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#executionpayloadheader ExecutionPayloadHeader* = object # Execution block header fields parent_hash*: Eth2Digest @@ -96,13 +96,13 @@ type ExecutePayload* = proc( execution_payload: ExecutionPayload): bool {.gcsafe, raises: [].} - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/fork-choice.md#powblock + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/fork-choice.md#powblock PowBlock* = object block_hash*: Eth2Digest parent_hash*: Eth2Digest total_difficulty*: Eth2Digest # uint256 - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#beaconstate + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#beaconstate BeaconState* = object # Versioning genesis_time*: uint64 @@ -227,7 +227,7 @@ type state_root*: Eth2Digest body*: TrustedBeaconBlockBody - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#beaconblockbody + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#beaconblockbody BeaconBlockBody* = object randao_reveal*: ValidatorSig eth1_data*: Eth1Data diff --git a/beacon_chain/spec/datatypes/capella.nim b/beacon_chain/spec/datatypes/capella.nim index 24844269c..3c70337db 100644 --- a/beacon_chain/spec/datatypes/capella.nim +++ b/beacon_chain/spec/datatypes/capella.nim @@ -32,7 +32,7 @@ const # This index is rooted in `BeaconBlockBody`. # The first member (`randao_reveal`) is 16, subsequent members +1 each. # If there are ever more than 16 members in `BeaconBlockBody`, indices change! - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/ssz/merkle-proofs.md + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/ssz/merkle-proofs.md EXECUTION_PAYLOAD_GINDEX* = 25.GeneralizedIndex # execution_payload type @@ -52,12 +52,12 @@ type from_bls_pubkey*: ValidatorPubKey to_execution_address*: ExecutionAddress - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#signedblstoexecutionchange + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#signedblstoexecutionchange SignedBLSToExecutionChange* = object message*: BLSToExecutionChange signature*: ValidatorSig - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#historicalsummary + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#historicalsummary HistoricalSummary* = object # `HistoricalSummary` matches the components of the phase0 # `HistoricalBatch` making the two hash_tree_root-compatible. @@ -684,13 +684,13 @@ func is_valid_light_client_header*( get_subtree_index(EXECUTION_PAYLOAD_GINDEX), header.beacon.body_root) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/light-client/fork.md#upgrading-light-client-data +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/light-client/fork.md#upgrading-light-client-data func upgrade_lc_header_to_capella*( pre: altair.LightClientHeader): LightClientHeader = LightClientHeader( beacon: pre.beacon) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/light-client/fork.md#upgrading-light-client-data +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/light-client/fork.md#upgrading-light-client-data func upgrade_lc_bootstrap_to_capella*( pre: altair.LightClientBootstrap): LightClientBootstrap = LightClientBootstrap( @@ -698,7 +698,7 @@ func upgrade_lc_bootstrap_to_capella*( current_sync_committee: pre.current_sync_committee, current_sync_committee_branch: pre.current_sync_committee_branch) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/light-client/fork.md#upgrading-light-client-data +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/light-client/fork.md#upgrading-light-client-data func upgrade_lc_update_to_capella*( pre: altair.LightClientUpdate): LightClientUpdate = LightClientUpdate( @@ -710,7 +710,7 @@ func upgrade_lc_update_to_capella*( sync_aggregate: pre.sync_aggregate, signature_slot: pre.signature_slot) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/light-client/fork.md#upgrading-light-client-data +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/light-client/fork.md#upgrading-light-client-data func upgrade_lc_finality_update_to_capella*( pre: altair.LightClientFinalityUpdate): LightClientFinalityUpdate = LightClientFinalityUpdate( @@ -720,7 +720,7 @@ func upgrade_lc_finality_update_to_capella*( sync_aggregate: pre.sync_aggregate, signature_slot: pre.signature_slot) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/light-client/fork.md#upgrading-light-client-data +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/light-client/fork.md#upgrading-light-client-data func upgrade_lc_optimistic_update_to_capella*( pre: altair.LightClientOptimisticUpdate): LightClientOptimisticUpdate = LightClientOptimisticUpdate( @@ -771,7 +771,7 @@ chronicles.formatIt LightClientUpdate: shortLog(it) chronicles.formatIt LightClientFinalityUpdate: shortLog(it) chronicles.formatIt LightClientOptimisticUpdate: shortLog(it) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/light-client/fork.md#upgrading-the-store +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/light-client/fork.md#upgrading-the-store func upgrade_lc_store_to_capella*( pre: altair.LightClientStore): LightClientStore = let best_valid_update = diff --git a/beacon_chain/spec/datatypes/constants.nim b/beacon_chain/spec/datatypes/constants.nim index 1e0bb3e8d..fdb83ae4b 100644 --- a/beacon_chain/spec/datatypes/constants.nim +++ b/beacon_chain/spec/datatypes/constants.nim @@ -55,7 +55,7 @@ const DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF* = DomainType([byte 0x08, 0x00, 0x00, 0x00]) DOMAIN_CONTRIBUTION_AND_PROOF* = DomainType([byte 0x09, 0x00, 0x00, 0x00]) - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#domain-types + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#domain-types DOMAIN_BLS_TO_EXECUTION_CHANGE* = DomainType([byte 0x0a, 0x00, 0x00, 0x00]) # https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#domains diff --git a/beacon_chain/spec/datatypes/deneb.nim b/beacon_chain/spec/datatypes/deneb.nim index 248ae5b99..042b55664 100644 --- a/beacon_chain/spec/datatypes/deneb.nim +++ b/beacon_chain/spec/datatypes/deneb.nim @@ -606,7 +606,7 @@ func kzg_commitment_inclusion_proof_gindex*( # This index is rooted in `BeaconBlockBody`. # The first member (`randao_reveal`) is 16, subsequent members +1 each. # If there are ever more than 16 members in `BeaconBlockBody`, indices change! - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/ssz/merkle-proofs.md + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/ssz/merkle-proofs.md const # blob_kzg_commitments BLOB_KZG_COMMITMENTS_GINDEX = @@ -677,7 +677,7 @@ func is_valid_light_client_header*( get_subtree_index(EXECUTION_PAYLOAD_GINDEX), header.beacon.body_root) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/deneb/light-client/fork.md#upgrading-light-client-data +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/deneb/light-client/fork.md#upgrading-light-client-data func upgrade_lc_header_to_deneb*( pre: capella.LightClientHeader): LightClientHeader = LightClientHeader( @@ -702,7 +702,7 @@ func upgrade_lc_header_to_deneb*( excess_blob_gas: 0), # [New in Deneb:EIP4844] execution_branch: pre.execution_branch) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/deneb/light-client/fork.md#upgrading-light-client-data +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/deneb/light-client/fork.md#upgrading-light-client-data func upgrade_lc_bootstrap_to_deneb*( pre: capella.LightClientBootstrap): LightClientBootstrap = LightClientBootstrap( @@ -710,7 +710,7 @@ func upgrade_lc_bootstrap_to_deneb*( current_sync_committee: pre.current_sync_committee, current_sync_committee_branch: pre.current_sync_committee_branch) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/deneb/light-client/fork.md#upgrading-light-client-data +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/deneb/light-client/fork.md#upgrading-light-client-data func upgrade_lc_update_to_deneb*( pre: capella.LightClientUpdate): LightClientUpdate = LightClientUpdate( @@ -722,7 +722,7 @@ func upgrade_lc_update_to_deneb*( sync_aggregate: pre.sync_aggregate, signature_slot: pre.signature_slot) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/deneb/light-client/fork.md#upgrading-light-client-data +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/deneb/light-client/fork.md#upgrading-light-client-data func upgrade_lc_finality_update_to_deneb*( pre: capella.LightClientFinalityUpdate): LightClientFinalityUpdate = LightClientFinalityUpdate( @@ -732,7 +732,7 @@ func upgrade_lc_finality_update_to_deneb*( sync_aggregate: pre.sync_aggregate, signature_slot: pre.signature_slot) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/deneb/light-client/fork.md#upgrading-light-client-data +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/deneb/light-client/fork.md#upgrading-light-client-data func upgrade_lc_optimistic_update_to_deneb*( pre: capella.LightClientOptimisticUpdate): LightClientOptimisticUpdate = LightClientOptimisticUpdate( @@ -783,7 +783,7 @@ chronicles.formatIt LightClientUpdate: shortLog(it) chronicles.formatIt LightClientFinalityUpdate: shortLog(it) chronicles.formatIt LightClientOptimisticUpdate: shortLog(it) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/deneb/light-client/fork.md#upgrading-the-store +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/deneb/light-client/fork.md#upgrading-the-store func upgrade_lc_store_to_deneb*( pre: capella.LightClientStore): LightClientStore = let best_valid_update = diff --git a/beacon_chain/spec/datatypes/electra.nim b/beacon_chain/spec/datatypes/electra.nim index 2326c88d6..4fba931f9 100644 --- a/beacon_chain/spec/datatypes/electra.nim +++ b/beacon_chain/spec/datatypes/electra.nim @@ -43,7 +43,7 @@ const # The first member (`genesis_time`) is 64, subsequent members +1 each. # If there are ever more than 64 members in `BeaconState`, indices change! # `FINALIZED_ROOT_GINDEX` is one layer deeper, i.e., `84 * 2 + 1`. - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/ssz/merkle-proofs.md + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/ssz/merkle-proofs.md FINALIZED_ROOT_GINDEX = 169.GeneralizedIndex # finalized_checkpoint > root CURRENT_SYNC_COMMITTEE_GINDEX = 86.GeneralizedIndex # current_sync_committee NEXT_SYNC_COMMITTEE_GINDEX = 87.GeneralizedIndex # next_sync_committee diff --git a/beacon_chain/spec/eth2_apis/rest_types.nim b/beacon_chain/spec/eth2_apis/rest_types.nim index da21e5b21..1330c50aa 100644 --- a/beacon_chain/spec/eth2_apis/rest_types.nim +++ b/beacon_chain/spec/eth2_apis/rest_types.nim @@ -292,7 +292,7 @@ type RestWithdrawalPrefix* = distinct array[1, byte] - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#executionpayload + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#executionpayload RestExecutionPayload* = object # Execution block header fields parent_hash*: Eth2Digest diff --git a/beacon_chain/spec/helpers.nim b/beacon_chain/spec/helpers.nim index f0d2d0091..e54671aa7 100644 --- a/beacon_chain/spec/helpers.nim +++ b/beacon_chain/spec/helpers.nim @@ -25,7 +25,7 @@ import export eth2_merkleization, forks, rlp, ssz_codec -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/phase0/weak-subjectivity.md#constants +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/weak-subjectivity.md#constants const ETH_TO_GWEI = 1_000_000_000.Gwei func toEther*(gwei: Gwei): Ether = @@ -271,7 +271,7 @@ template is_finality_update*(update: SomeForkyLightClientUpdate): bool = else: false -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/sync-protocol.md#is_next_sync_committee_known +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/sync-protocol.md#is_next_sync_committee_known template is_next_sync_committee_known*(store: ForkyLightClientStore): bool = store.next_sync_committee != static(default(typeof(store.next_sync_committee))) @@ -384,7 +384,7 @@ func contextEpoch*(bootstrap: ForkyLightClientBootstrap): Epoch = func contextEpoch*(update: SomeForkyLightClientUpdate): Epoch = update.attested_header.beacon.slot.epoch -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#is_merge_transition_complete +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#is_merge_transition_complete func is_merge_transition_complete*( state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState | electra.BeaconState): bool = @@ -392,7 +392,7 @@ func is_merge_transition_complete*( default(typeof(state.latest_execution_payload_header)) state.latest_execution_payload_header != defaultExecutionPayloadHeader -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/sync/optimistic.md#helpers +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/sync/optimistic.md#helpers func is_execution_block*(blck: SomeForkyBeaconBlock): bool = when typeof(blck).kind >= ConsensusFork.Bellatrix: const defaultExecutionPayload = @@ -401,7 +401,7 @@ func is_execution_block*(blck: SomeForkyBeaconBlock): bool = else: false -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#is_merge_transition_block +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#is_merge_transition_block func is_merge_transition_block( state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState | electra.BeaconState, @@ -417,7 +417,7 @@ func is_merge_transition_block( not is_merge_transition_complete(state) and body.execution_payload != defaultExecutionPayload -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#is_execution_enabled +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#is_execution_enabled func is_execution_enabled*( state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState | electra.BeaconState, @@ -431,7 +431,7 @@ func is_execution_enabled*( electra.SigVerifiedBeaconBlockBody): bool = is_merge_transition_block(state, body) or is_merge_transition_complete(state) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#compute_timestamp_at_slot +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#compute_timestamp_at_slot func compute_timestamp_at_slot*(state: ForkyBeaconState, slot: Slot): uint64 = # Note: This function is unsafe with respect to overflows and underflows. let slots_since_genesis = slot - GENESIS_SLOT diff --git a/beacon_chain/spec/keystore.nim b/beacon_chain/spec/keystore.nim index 636c8faca..2cc14ff16 100644 --- a/beacon_chain/spec/keystore.nim +++ b/beacon_chain/spec/keystore.nim @@ -1386,7 +1386,7 @@ func makeWithdrawalCredentials*(k: ValidatorPubKey): Eth2Digest = bytes.data[0] = BLS_WITHDRAWAL_PREFIX.uint8 bytes -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/phase0/deposit-contract.md#withdrawal-credentials +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/deposit-contract.md#withdrawal-credentials func makeWithdrawalCredentials*(k: CookedPubKey): Eth2Digest = makeWithdrawalCredentials(k.toPubKey()) diff --git a/beacon_chain/spec/network.nim b/beacon_chain/spec/network.nim index 221253d6e..d456184cc 100644 --- a/beacon_chain/spec/network.nim +++ b/beacon_chain/spec/network.nim @@ -15,7 +15,7 @@ export base const # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/phase0/p2p-interface.md#topics-and-messages - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/p2p-interface.md#topics-and-messages + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/p2p-interface.md#topics-and-messages topicBeaconBlocksSuffix* = "beacon_block/ssz_snappy" topicVoluntaryExitsSuffix* = "voluntary_exit/ssz_snappy" topicProposerSlashingsSuffix* = "proposer_slashing/ssz_snappy" @@ -63,7 +63,7 @@ func getAttesterSlashingsTopic*(forkDigest: ForkDigest): string = func getAggregateAndProofsTopic*(forkDigest: ForkDigest): string = eth2Prefix(forkDigest) & topicAggregateAndProofsSuffix -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/p2p-interface.md#topics-and-messages +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/p2p-interface.md#topics-and-messages func getBlsToExecutionChangeTopic*(forkDigest: ForkDigest): string = eth2Prefix(forkDigest) & topicBlsToExecutionChangeSuffix @@ -197,7 +197,7 @@ func getTargetGossipState*( targetForks func nearSyncCommitteePeriod*(epoch: Epoch): Opt[uint64] = - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#sync-committee-subnet-stability + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#sync-committee-subnet-stability if epoch.is_sync_committee_period(): return Opt.some 0'u64 let epochsBefore = @@ -216,7 +216,7 @@ func getSyncSubnets*( if not nodeHasPubkey(pubkey): continue - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#broadcast-sync-committee-message + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#broadcast-sync-committee-message # The first quarter of the pubkeys map to subnet 0, the second quarter to # subnet 1, the third quarter to subnet 2 and the final quarter to subnet # 3. diff --git a/beacon_chain/spec/presets.nim b/beacon_chain/spec/presets.nim index 98cf3743b..6278acbab 100644 --- a/beacon_chain/spec/presets.nim +++ b/beacon_chain/spec/presets.nim @@ -787,7 +787,7 @@ proc readRuntimeConfig*( "MAX_REQUEST_BLOB_SIDECARS" checkCompatibility BLOB_SIDECAR_SUBNET_COUNT - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/phase0/fork-choice.md#configuration + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/fork-choice.md#configuration # Isn't being used as a preset in the usual way: at any time, there's one correct value checkCompatibility PROPOSER_SCORE_BOOST checkCompatibility REORG_HEAD_WEIGHT_THRESHOLD diff --git a/beacon_chain/spec/presets/mainnet/altair_preset.nim b/beacon_chain/spec/presets/mainnet/altair_preset.nim index 7fcc1479b..104b6725c 100644 --- a/beacon_chain/spec/presets/mainnet/altair_preset.nim +++ b/beacon_chain/spec/presets/mainnet/altair_preset.nim @@ -8,7 +8,7 @@ {.push raises: [].} # Mainnet preset - Altair -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/presets/mainnet/altair.yaml +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/presets/mainnet/altair.yaml const # Updated penalty values # --------------------------------------------------------------- diff --git a/beacon_chain/spec/presets/mainnet/bellatrix_preset.nim b/beacon_chain/spec/presets/mainnet/bellatrix_preset.nim index 36d5a5084..5acf0a1eb 100644 --- a/beacon_chain/spec/presets/mainnet/bellatrix_preset.nim +++ b/beacon_chain/spec/presets/mainnet/bellatrix_preset.nim @@ -8,7 +8,7 @@ {.push raises: [].} # Mainnet preset - Bellatrix -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/presets/mainnet/bellatrix.yaml +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/presets/mainnet/bellatrix.yaml const # Updated penalty values # --------------------------------------------------------------- diff --git a/beacon_chain/spec/presets/mainnet/capella_preset.nim b/beacon_chain/spec/presets/mainnet/capella_preset.nim index df1654b1f..593c0f870 100644 --- a/beacon_chain/spec/presets/mainnet/capella_preset.nim +++ b/beacon_chain/spec/presets/mainnet/capella_preset.nim @@ -8,7 +8,7 @@ {.push raises: [].} # Mainnet preset - Capella -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/presets/mainnet/capella.yaml +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/presets/mainnet/capella.yaml const # Max operations per block # --------------------------------------------------------------- diff --git a/beacon_chain/spec/presets/mainnet/deneb_preset.nim b/beacon_chain/spec/presets/mainnet/deneb_preset.nim index 0b31728f4..cd3f91edb 100644 --- a/beacon_chain/spec/presets/mainnet/deneb_preset.nim +++ b/beacon_chain/spec/presets/mainnet/deneb_preset.nim @@ -8,7 +8,7 @@ {.push raises: [].} # Mainnet preset - Deneb -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/presets/mainnet/deneb.yaml +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/presets/mainnet/deneb.yaml const # `uint64(4096)` FIELD_ELEMENTS_PER_BLOB*: uint64 = 4096 diff --git a/beacon_chain/spec/presets/minimal/altair_preset.nim b/beacon_chain/spec/presets/minimal/altair_preset.nim index 5ccc0967f..365a94d59 100644 --- a/beacon_chain/spec/presets/minimal/altair_preset.nim +++ b/beacon_chain/spec/presets/minimal/altair_preset.nim @@ -8,7 +8,7 @@ {.push raises: [].} # Minimal preset - Altair -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/presets/minimal/altair.yaml +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/presets/minimal/altair.yaml const # Updated penalty values # --------------------------------------------------------------- diff --git a/beacon_chain/spec/presets/minimal/bellatrix_preset.nim b/beacon_chain/spec/presets/minimal/bellatrix_preset.nim index 511fc3859..631e3f85c 100644 --- a/beacon_chain/spec/presets/minimal/bellatrix_preset.nim +++ b/beacon_chain/spec/presets/minimal/bellatrix_preset.nim @@ -8,7 +8,7 @@ {.push raises: [].} # Minimal preset - Bellatrix -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/presets/minimal/bellatrix.yaml +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/presets/minimal/bellatrix.yaml const # Updated penalty values # --------------------------------------------------------------- diff --git a/beacon_chain/spec/presets/minimal/capella_preset.nim b/beacon_chain/spec/presets/minimal/capella_preset.nim index b6f82850e..7851d1a87 100644 --- a/beacon_chain/spec/presets/minimal/capella_preset.nim +++ b/beacon_chain/spec/presets/minimal/capella_preset.nim @@ -8,7 +8,7 @@ {.push raises: [].} # Minimal preset - Capella -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/presets/minimal/capella.yaml +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/presets/minimal/capella.yaml const # Max operations per block # --------------------------------------------------------------- diff --git a/beacon_chain/spec/presets/minimal/deneb_preset.nim b/beacon_chain/spec/presets/minimal/deneb_preset.nim index 83666cd42..dfc17a87b 100644 --- a/beacon_chain/spec/presets/minimal/deneb_preset.nim +++ b/beacon_chain/spec/presets/minimal/deneb_preset.nim @@ -8,7 +8,7 @@ {.push raises: [].} # Minimal preset - Deneb -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/presets/minimal/deneb.yaml +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/presets/minimal/deneb.yaml const # `uint64(4096)` FIELD_ELEMENTS_PER_BLOB*: uint64 = 4096 diff --git a/beacon_chain/spec/signatures.nim b/beacon_chain/spec/signatures.nim index 12f2a0c72..f48e790af 100644 --- a/beacon_chain/spec/signatures.nim +++ b/beacon_chain/spec/signatures.nim @@ -269,7 +269,7 @@ proc verify_voluntary_exit_signature*( blsVerify(pubkey, signing_root.data, signature) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#prepare-sync-committee-message +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#prepare-sync-committee-message func compute_sync_committee_message_signing_root*( fork: Fork, genesis_validators_root: Eth2Digest, slot: Slot, beacon_block_root: Eth2Digest): Eth2Digest = @@ -304,7 +304,7 @@ proc verify_sync_committee_signature*( blsFastAggregateVerify(pubkeys, signing_root.data, signature) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#aggregation-selection +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#aggregation-selection func compute_sync_committee_selection_proof_signing_root*( fork: Fork, genesis_validators_root: Eth2Digest, slot: Slot, subcommittee_index: SyncSubcommitteeIndex): Eth2Digest = @@ -335,7 +335,7 @@ proc verify_sync_committee_selection_proof*( blsVerify(pubkey, signing_root.data, signature) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#signature +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#signature func compute_contribution_and_proof_signing_root*( fork: Fork, genesis_validators_root: Eth2Digest, msg: ContributionAndProof): Eth2Digest = @@ -353,7 +353,7 @@ proc get_contribution_and_proof_signature*( blsSign(privkey, signing_root.data) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#aggregation-selection +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#aggregation-selection func is_sync_committee_aggregator*(signature: ValidatorSig): bool = let signatureDigest = eth2digest(signature.blob) @@ -393,7 +393,7 @@ proc verify_builder_signature*( let signing_root = compute_builder_signing_root(fork, msg) blsVerify(pubkey, signing_root.data, signature) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#new-process_bls_to_execution_change +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#new-process_bls_to_execution_change func compute_bls_to_execution_change_signing_root*( genesisFork: Fork, genesis_validators_root: Eth2Digest, msg: BLSToExecutionChange): Eth2Digest = diff --git a/beacon_chain/spec/state_transition.nim b/beacon_chain/spec/state_transition.nim index 664c0a46a..3b72df934 100644 --- a/beacon_chain/spec/state_transition.nim +++ b/beacon_chain/spec/state_transition.nim @@ -385,7 +385,7 @@ func partialBeaconBlock*( when consensusFork >= ConsensusFork.Altair: res.body.sync_aggregate = sync_aggregate - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/validator.md#block-proposal + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/validator.md#block-proposal when consensusFork >= ConsensusFork.Bellatrix: res.body.execution_payload = execution_payload.executionPayload diff --git a/beacon_chain/spec/state_transition_block.nim b/beacon_chain/spec/state_transition_block.nim index c77fdc32d..035666e19 100644 --- a/beacon_chain/spec/state_transition_block.nim +++ b/beacon_chain/spec/state_transition_block.nim @@ -10,8 +10,8 @@ # State transition - block processing, as described in # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#block-processing # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#block-processing -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#block-processing -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#block-processing +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#block-processing +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#block-processing # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#block-processing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.1/specs/electra/beacon-chain.md#block-processing # @@ -1023,7 +1023,7 @@ proc process_execution_payload*( ok() -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#new-process_withdrawals +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#new-process_withdrawals # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#updated-process_withdrawals func process_withdrawals*( state: var (capella.BeaconState | deneb.BeaconState | electra.BeaconState), @@ -1146,7 +1146,7 @@ proc process_block*( ok(operations_rewards) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#block-processing +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/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 diff --git a/beacon_chain/spec/state_transition_epoch.nim b/beacon_chain/spec/state_transition_epoch.nim index 633ff7540..cad91c038 100644 --- a/beacon_chain/spec/state_transition_epoch.nim +++ b/beacon_chain/spec/state_transition_epoch.nim @@ -10,7 +10,7 @@ # State transition - epoch processing, as described in # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#epoch-processing # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#epoch-processing -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#epoch-processing +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#epoch-processing # https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/capella/beacon-chain.md#epoch-processing # # The entry point is `process_epoch`, which is at the bottom of this file. @@ -701,7 +701,7 @@ func get_active_increments*( # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#get_flag_index_deltas # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#modified-get_inactivity_penalty_deltas -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#modified-get_inactivity_penalty_deltas +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#modified-get_inactivity_penalty_deltas # Combines get_flag_index_deltas() and get_inactivity_penalty_deltas() template get_flag_and_inactivity_delta( state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState | @@ -961,7 +961,7 @@ func process_registry_updates*( # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#slashings -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#slashings +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#slashings func get_adjusted_total_slashing_balance*( state: ForkyBeaconState, total_balance: Gwei): Gwei = const multiplier = @@ -980,14 +980,14 @@ func get_adjusted_total_slashing_balance*( # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#slashings -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#slashings +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#slashings func slashing_penalty_applies*(validator: Validator, epoch: Epoch): bool = validator.slashed and epoch + EPOCHS_PER_SLASHINGS_VECTOR div 2 == validator.withdrawable_epoch # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#slashings -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#slashings +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#slashings func get_slashing_penalty*(validator: Validator, adjusted_total_slashing_balance, total_balance: Gwei): Gwei = @@ -999,7 +999,7 @@ func get_slashing_penalty*(validator: Validator, # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#slashings -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#slashings +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#slashings func process_slashings*(state: var ForkyBeaconState, total_balance: Gwei) = let epoch = get_current_epoch(state) diff --git a/beacon_chain/spec/weak_subjectivity.nim b/beacon_chain/spec/weak_subjectivity.nim index da5c02d83..2fe449015 100644 --- a/beacon_chain/spec/weak_subjectivity.nim +++ b/beacon_chain/spec/weak_subjectivity.nim @@ -10,10 +10,10 @@ import ./datatypes/base, ./beaconstate, ./forks, ./helpers -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/phase0/weak-subjectivity.md#configuration +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/weak-subjectivity.md#configuration const SAFETY_DECAY* = 10'u64 -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/phase0/weak-subjectivity.md#compute_weak_subjectivity_period +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/weak-subjectivity.md#compute_weak_subjectivity_period func compute_weak_subjectivity_period( cfg: RuntimeConfig, state: ForkyBeaconState): uint64 = ## Returns the weak subjectivity period for the current ``state``. @@ -49,7 +49,7 @@ func compute_weak_subjectivity_period( ws_period -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/phase0/weak-subjectivity.md#is_within_weak_subjectivity_period +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/weak-subjectivity.md#is_within_weak_subjectivity_period func is_within_weak_subjectivity_period*(cfg: RuntimeConfig, current_slot: Slot, ws_state: ForkedHashedBeaconState, ws_checkpoint: Checkpoint): bool = diff --git a/beacon_chain/sync/light_client_manager.nim b/beacon_chain/sync/light_client_manager.nim index 157efe00e..f8b8bc5a4 100644 --- a/beacon_chain/sync/light_client_manager.nim +++ b/beacon_chain/sync/light_client_manager.nim @@ -328,7 +328,7 @@ template query[E]( ): Future[bool].Raising([CancelledError]) = self.query(e, Nothing()) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/light-client.md#light-client-sync-process +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/light-client.md#light-client-sync-process proc loop(self: LightClientManager) {.async: (raises: [CancelledError]).} = var nextSyncTaskTime = self.getBeaconTime() while true: diff --git a/beacon_chain/sync/light_client_protocol.nim b/beacon_chain/sync/light_client_protocol.nim index d08ecd19c..909549732 100644 --- a/beacon_chain/sync/light_client_protocol.nim +++ b/beacon_chain/sync/light_client_protocol.nim @@ -90,7 +90,7 @@ p2pProtocol LightClientSync(version = 1, debug "LC bootstrap request done", peer, blockRoot - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/p2p-interface.md#lightclientupdatesbyrange + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/p2p-interface.md#lightclientupdatesbyrange proc lightClientUpdatesByRange( peer: Peer, startPeriod: SyncCommitteePeriod, diff --git a/beacon_chain/trusted_node_sync.nim b/beacon_chain/trusted_node_sync.nim index 380fcfcaf..dfc4c40b5 100644 --- a/beacon_chain/trusted_node_sync.nim +++ b/beacon_chain/trusted_node_sync.nim @@ -171,7 +171,7 @@ proc doTrustedNodeSync*( let stateId = case syncTarget.kind of TrustedNodeSyncKind.TrustedBlockRoot: - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/light-client.md#light-client-sync-process + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/light-client.md#light-client-sync-process const lcDataFork = LightClientDataFork.high var bestViableCheckpoint: Opt[tuple[slot: Slot, state_root: Eth2Digest]] func trackBestViableCheckpoint(store: lcDataFork.LightClientStore) = diff --git a/beacon_chain/validators/beacon_validators.nim b/beacon_chain/validators/beacon_validators.nim index 583c93ff6..f6316bd89 100644 --- a/beacon_chain/validators/beacon_validators.nim +++ b/beacon_chain/validators/beacon_validators.nim @@ -1965,7 +1965,7 @@ proc handleValidatorDuties*(node: BeaconNode, lastSlot, slot: Slot) {.async: (ra updateValidatorMetrics(node) # the important stuff is done, update the vanity numbers # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#broadcast-aggregate - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#broadcast-sync-committee-contribution + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#broadcast-sync-committee-contribution # Wait 2 / 3 of the slot time to allow messages to propagate, then collect # the result in aggregates static: diff --git a/beacon_chain/validators/validator_pool.nim b/beacon_chain/validators/validator_pool.nim index 98df8a2f5..6d9ccab93 100644 --- a/beacon_chain/validators/validator_pool.nim +++ b/beacon_chain/validators/validator_pool.nim @@ -767,7 +767,7 @@ proc getAggregateAndProofSignature*(v: AttachedValidator, fork, genesis_validators_root, aggregate_and_proof) await v.signData(request) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#prepare-sync-committee-message +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#prepare-sync-committee-message proc getSyncCommitteeMessage*(v: AttachedValidator, fork: Fork, genesis_validators_root: Eth2Digest, @@ -798,7 +798,7 @@ proc getSyncCommitteeMessage*(v: AttachedValidator, ) ) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#aggregation-selection +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#aggregation-selection proc getSyncCommitteeSelectionProof*(v: AttachedValidator, fork: Fork, genesis_validators_root: Eth2Digest, slot: Slot, @@ -818,7 +818,7 @@ proc getSyncCommitteeSelectionProof*(v: AttachedValidator, fork: Fork, ) await v.signData(request) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#broadcast-sync-committee-contribution +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#broadcast-sync-committee-contribution proc getContributionAndProofSignature*(v: AttachedValidator, fork: Fork, genesis_validators_root: Eth2Digest, contribution_and_proof: ContributionAndProof diff --git a/docs/the_nimbus_book/src/el-light-client.md b/docs/the_nimbus_book/src/el-light-client.md index eb29ebede..2c896089d 100644 --- a/docs/the_nimbus_book/src/el-light-client.md +++ b/docs/the_nimbus_book/src/el-light-client.md @@ -104,7 +104,7 @@ The following sections explain how to do this for certain EL clients. ## Running the light client The light client starts syncing from a trusted block. -This trusted block should be somewhat recent ([~1-2 weeks](https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/phase0/weak-subjectivity.md)) and needs to be configured each time when starting the light client. +This trusted block should be somewhat recent ([~1-2 weeks](https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/weak-subjectivity.md)) and needs to be configured each time when starting the light client. ### 1. Obtaining a trusted block root @@ -186,7 +186,7 @@ INF 2022-11-21 18:04:03.982+01:00 New LC optimistic header opt ``` !!! note - The [light client protocol](https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/light-client/sync-protocol.md) depends on consensus layer (CL) full nodes to serve additional data. + The [light client protocol](https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/sync-protocol.md) depends on consensus layer (CL) full nodes to serve additional data. As this is a new protocol, not all implementations are supporting it yet. Therefore, it may take several minutes to discover supporting peers, during which no log messages may be produced. diff --git a/docs/the_nimbus_book/src/web3signer.md b/docs/the_nimbus_book/src/web3signer.md index a4ab2acd3..2ec45d2e5 100644 --- a/docs/the_nimbus_book/src/web3signer.md +++ b/docs/the_nimbus_book/src/web3signer.md @@ -135,7 +135,7 @@ If you are already using a threshold signing setup (e.g. based on Vouch and Dirk The verifying Web3Signer is an experimental extension to the [Web3Signer protocol](https://consensys.github.io/web3signer/web3signer-eth2.html#tag/Signing/operation/ETH2_SIGN) which allows the remote signer to verify certain details of the signed blocks before creating a signature (for example, the signer may require the signed block to have a particular fee recipient value). -To enable this use case, the `BLOCK_V2` request type of the `/api/v1/eth2/sign/{identifier}` endpoint is extended with an additional array field named `proofs`. The array consists of objects with the properties `index`, `proof` and `value`, where `index` is an arbitrary [generalized index](https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/ssz/merkle-proofs.md#generalized-merkle-tree-index) of any property nested under the block body and `proof` is its corresponding Merkle proof against the block body root included in the request. The `value` property is optional and it is included only when the SSZ hash of the field included in the Merkle proof doesn't match its value. +To enable this use case, the `BLOCK_V2` request type of the `/api/v1/eth2/sign/{identifier}` endpoint is extended with an additional array field named `proofs`. The array consists of objects with the properties `index`, `proof` and `value`, where `index` is an arbitrary [generalized index](https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/ssz/merkle-proofs.md#generalized-merkle-tree-index) of any property nested under the block body and `proof` is its corresponding Merkle proof against the block body root included in the request. The `value` property is optional and it is included only when the SSZ hash of the field included in the Merkle proof doesn't match its value. Since the generalized index of a particular field may change in a hard-fork, in the remote keystore format the proven fields are usually specified by their name: diff --git a/tests/consensus_spec/altair/test_fixture_light_client_sync_protocol.nim b/tests/consensus_spec/altair/test_fixture_light_client_sync_protocol.nim index 51fa84578..7e8def2a4 100644 --- a/tests/consensus_spec/altair/test_fixture_light_client_sync_protocol.nim +++ b/tests/consensus_spec/altair/test_fixture_light_client_sync_protocol.nim @@ -23,7 +23,7 @@ import # Test utilities ../../testutil, ../../testblockutil -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/tests/core/pyspec/eth2spec/test/helpers/sync_committee.py#L27-L44 +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/tests/core/pyspec/eth2spec/test/helpers/sync_committee.py#L27-L44 proc compute_aggregate_sync_committee_signature( cfg: RuntimeConfig, forked: ForkedHashedBeaconState, From 350c4eaa39c7f002f3c872ae3f75586471edbfc5 Mon Sep 17 00:00:00 2001 From: tersec Date: Mon, 17 Jun 2024 09:40:41 +0000 Subject: [PATCH 03/68] rm Goerli remnant; add explanatory comment about opt sync validation (#6365) --- beacon_chain/el/el_manager.nim | 1 - beacon_chain/gossip_processing/block_processor.nim | 9 ++++++--- beacon_chain/networking/network_metadata.nim | 1 - beacon_chain/spec/signatures_batch.nim | 4 ---- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/beacon_chain/el/el_manager.nim b/beacon_chain/el/el_manager.nim index 20650b6fd..1bcef2392 100644 --- a/beacon_chain/el/el_manager.nim +++ b/beacon_chain/el/el_manager.nim @@ -1529,7 +1529,6 @@ proc exchangeConfigWithSingleEL( # https://chainid.network/ expectedChain = case m.eth1Network.get of mainnet: 1.Quantity - of goerli: 5.Quantity of sepolia: 11155111.Quantity of holesky: 17000.Quantity if expectedChain != providerChain: diff --git a/beacon_chain/gossip_processing/block_processor.nim b/beacon_chain/gossip_processing/block_processor.nim index 27a098036..37e1174be 100644 --- a/beacon_chain/gossip_processing/block_processor.nim +++ b/beacon_chain/gossip_processing/block_processor.nim @@ -545,11 +545,16 @@ proc storeBlock( # TODO run https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/beacon-chain.md#blob-kzg-commitments # https://github.com/ethereum/execution-apis/blob/main/src/engine/experimental/blob-extension.md#specification - # "This validation MUST be instantly run in all cases even during active sync process." + # "This validation MUST be instantly run in all cases even during active + # sync process." # # Client software MUST validate `blockHash` value as being equivalent to # `Keccak256(RLP(ExecutionBlockHeader))` # https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.3/src/engine/paris.md#specification + # + # This should simulate an unsynced EL, which still must perform these + # checks. This means it must be able to do so without context, beyond + # whatever data the block itself contains. when typeof(signedBlock).kind >= ConsensusFork.Bellatrix and typeof(signedBlock).kind <= ConsensusFork.Deneb: debugComment "electra can do this in principle" template payload(): auto = signedBlock.message.body.execution_payload @@ -562,8 +567,6 @@ proc storeBlock( doAssert strictVerification notin dag.updateFlags self.consensusManager.quarantine[].addUnviable(signedBlock.root) return err((VerifierError.Invalid, ProcessingStatus.completed)) - else: - discard let newPayloadTick = Moment.now() diff --git a/beacon_chain/networking/network_metadata.nim b/beacon_chain/networking/network_metadata.nim index 3ba5f45b7..2f2dfce39 100644 --- a/beacon_chain/networking/network_metadata.nim +++ b/beacon_chain/networking/network_metadata.nim @@ -47,7 +47,6 @@ type Eth1Network* = enum mainnet - goerli sepolia holesky diff --git a/beacon_chain/spec/signatures_batch.nim b/beacon_chain/spec/signatures_batch.nim index 7e1700c49..5374b68f5 100644 --- a/beacon_chain/spec/signatures_batch.nim +++ b/beacon_chain/spec/signatures_batch.nim @@ -462,10 +462,6 @@ proc collectSignatureSets*( genesis_fork, genesis_validators_root, bls_change.message, validator_pubkey, sig) - block: - # 9. Consolidations - debugComment "check consolidations signatures" - ok() proc batchVerify*(verifier: var BatchVerifier, sigs: openArray[SignatureSet]): bool = From 3a0e037c7d5cf7f3ca337ffae50d2a20a5dfae71 Mon Sep 17 00:00:00 2001 From: Eugene Kabanov Date: Tue, 18 Jun 2024 03:08:40 +0300 Subject: [PATCH 04/68] Bump nim-stew. (#6367) --- vendor/nim-stew | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/nim-stew b/vendor/nim-stew index a0a53c911..bb086e69d 160000 --- a/vendor/nim-stew +++ b/vendor/nim-stew @@ -1 +1 @@ -Subproject commit a0a53c911606cace989074f6b806eb0546a64ef6 +Subproject commit bb086e69da967ad235ed6c31247769e75b318e61 From 597f47317f8056c494f4e7a762aff73e5b0415b8 Mon Sep 17 00:00:00 2001 From: Miran Date: Tue, 18 Jun 2024 03:54:15 +0200 Subject: [PATCH 05/68] use Nim 2.0.6 (#6366) --- .github/workflows/ci.yml | 4 ++-- ci/Jenkinsfile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1bd584a67..8aa3aebbd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,7 +35,7 @@ jobs: cpu: amd64 - os: windows cpu: amd64 - branch: [~, upstream/version-1-6, upstream/version-2-0] + branch: [~, upstream/version-1-6, v2.0.6] exclude: - target: os: macos @@ -49,7 +49,7 @@ jobs: include: - branch: upstream/version-1-6 branch-short: version-1-6 - - branch: upstream/version-2-0 + - branch: v2.0.6 branch-short: version-2-0 nimflags-extra: --mm:refc - target: diff --git a/ci/Jenkinsfile b/ci/Jenkinsfile index 296247da9..097ce0be4 100644 --- a/ci/Jenkinsfile +++ b/ci/Jenkinsfile @@ -183,5 +183,5 @@ def getAgentLabel() { } def nimCommitForJob() { - return JOB_NAME.contains('nimv2') ? 'upstream/version-2-0' : '' + return JOB_NAME.contains('nimv2') ? 'v2.0.6' : '' } From bfd1a36fcf7ee9a454f89330d970ae5d1f6028c7 Mon Sep 17 00:00:00 2001 From: tersec Date: Tue, 18 Jun 2024 05:35:36 +0000 Subject: [PATCH 06/68] add engine API consolidation requests support for getPayloadV4/newPayloadV4 (#6368) --- beacon_chain/el/el_manager.nim | 48 ++++++++++++------ tests/test_el_manager.nim | 90 +++++++++++++++++++++++++++++++++- vendor/nim-web3 | 2 +- 3 files changed, 122 insertions(+), 18 deletions(-) diff --git a/beacon_chain/el/el_manager.nim b/beacon_chain/el/el_manager.nim index 1bcef2392..85eab9dc5 100644 --- a/beacon_chain/el/el_manager.nim +++ b/beacon_chain/el/el_manager.nim @@ -502,7 +502,7 @@ func asConsensusType*(rpcExecutionPayload: ExecutionPayloadV4): template getTransaction(tt: TypedTransaction): bellatrix.Transaction = bellatrix.Transaction.init(tt.distinctBase) - template getDepositRequest(dr: DepositReceiptV1): DepositRequest = + template getDepositRequest(dr: DepositRequestV1): DepositRequest = DepositRequest( pubkey: ValidatorPubKey(blob: dr.pubkey.distinctBase), withdrawal_credentials: dr.withdrawalCredentials.asEth2Digest, @@ -510,13 +510,19 @@ func asConsensusType*(rpcExecutionPayload: ExecutionPayloadV4): signature: ValidatorSig(blob: dr.signature.distinctBase), index: dr.index.uint64) - template getExecutionLayerWithdrawalRequest(elwr: WithdrawalRequestV1): - WithdrawalRequest = + template getWithdrawalRequest(wr: WithdrawalRequestV1): WithdrawalRequest = WithdrawalRequest( - source_address: ExecutionAddress(data: elwr.sourceAddress.distinctBase), + source_address: ExecutionAddress(data: wr.sourceAddress.distinctBase), validator_pubkey: ValidatorPubKey( - blob: elwr.validatorPublicKey.distinctBase), - amount: elwr.amount.Gwei) + blob: wr.validatorPublicKey.distinctBase), + amount: wr.amount.Gwei) + + template getConsolidationRequest(cr: ConsolidationRequestV1): + ConsolidationRequest = + ConsolidationRequest( + source_address: ExecutionAddress(data: cr.sourceAddress.distinctBase), + source_pubkey: ValidatorPubKey(blob: cr.sourcePubkey.distinctBase), + target_pubkey: ValidatorPubKey(blob: cr.targetPubkey.distinctBase)) electra.ExecutionPayload( parent_hash: rpcExecutionPayload.parentHash.asEth2Digest, @@ -543,11 +549,14 @@ func asConsensusType*(rpcExecutionPayload: ExecutionPayloadV4): deposit_requests: List[electra.DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init( mapIt(rpcExecutionPayload.depositRequests, it.getDepositRequest)), - withdrawal_requests: - List[electra.WithdrawalRequest, - MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init( - mapIt(rpcExecutionPayload.withdrawalRequests, - it.getExecutionLayerWithdrawalRequest))) + withdrawal_requests: List[electra.WithdrawalRequest, + MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init( + mapIt(rpcExecutionPayload.withdrawalRequests, + it.getWithdrawalRequest)), + consolidation_requests: List[electra.ConsolidationRequest, + Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init( + mapIt(rpcExecutionPayload.consolidationRequests, + it.getConsolidationRequest))) func asConsensusType*(payload: engine_api.GetPayloadV4Response): electra.ExecutionPayloadForSigning = @@ -647,8 +656,8 @@ func asEngineExecutionPayload*(executionPayload: electra.ExecutionPayload): template getTypedTransaction(tt: bellatrix.Transaction): TypedTransaction = TypedTransaction(tt.distinctBase) - template getDepositRequest(dr: DepositRequest): DepositReceiptV1 = - DepositReceiptV1( + template getDepositRequest(dr: DepositRequest): DepositRequestV1 = + DepositRequestV1( pubkey: FixedBytes[RawPubKeySize](dr.pubkey.blob), withdrawalCredentials: FixedBytes[32](dr.withdrawal_credentials.data), amount: dr.amount.Quantity, @@ -661,6 +670,13 @@ func asEngineExecutionPayload*(executionPayload: electra.ExecutionPayload): validatorPublicKey: FixedBytes[RawPubKeySize](wr.validator_pubkey.blob), amount: wr.amount.Quantity) + template getConsolidationRequest(cr: ConsolidationRequest): + ConsolidationRequestV1 = + ConsolidationRequestV1( + sourceAddress: Address(cr.source_address.data), + sourcePubkey: FixedBytes[RawPubKeySize](cr.source_pubkey.blob), + targetPubkey: FixedBytes[RawPubKeySize](cr.target_pubkey.blob)) + engine_api.ExecutionPayloadV4( parentHash: executionPayload.parent_hash.asBlockHash, feeRecipient: Address(executionPayload.fee_recipient.data), @@ -682,8 +698,10 @@ func asEngineExecutionPayload*(executionPayload: electra.ExecutionPayload): excessBlobGas: Quantity(executionPayload.excess_blob_gas), depositRequests: mapIt( executionPayload.deposit_requests, it.getDepositRequest), - withdrawalRequests: - mapIt(executionPayload.withdrawal_requests, it.getWithdrawalRequest)) + withdrawalRequests: mapIt( + executionPayload.withdrawal_requests, it.getWithdrawalRequest), + consolidationRequests: mapIt( + executionPayload.consolidation_requests, it.getConsolidationRequest)) func isConnected(connection: ELConnection): bool = connection.web3.isSome diff --git a/tests/test_el_manager.nim b/tests/test_el_manager.nim index e61de7f3a..de3e8d63b 100644 --- a/tests/test_el_manager.nim +++ b/tests/test_el_manager.nim @@ -1643,6 +1643,8 @@ suite "Eth1 monitor": ]), withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0x2cb54ddf357864102f4ab6bce57317a75cee972f303449bf7047f4e0e5809127"), @@ -1710,6 +1712,8 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0x462f156d8d950c7ffd40d7ba149bcc34093bbdb7"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xd6d7f2281c2b9c98a8a5dc0b7f41783eb91b838973207239852e817ed412e164e330003ac9ab0e96bc65886e15b5cbe9"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0xac5a7347865f503e1578d1b47271c8e60027b5ba24b0da8e7c3733bcdbeda220"), @@ -1806,6 +1810,8 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0x44754b90f7b23eee1dddafa745ac723dcc147404"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x8d13edc45159cdcf6ed780fc7b93e74434fa392b0842dfa92458cc59515aaac127317df24def9701eb6d5ea060eaffea"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0x06504beb0dc3bae44ef75678d29ec5138d87da68d307ca7d43e259cede60fda6"), @@ -1843,6 +1849,8 @@ suite "Eth1 monitor": ]), withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0xb5d4a5eae3a1ea004ed573b0b8f8a22c847616758c0faf1e7e9589f16e55415c"), @@ -1892,6 +1900,12 @@ suite "Eth1 monitor": ]), withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ConsolidationRequest( + source_address: ExecutionAddress.fromHex("0xf059ccccbe2c2c647c9eb7443e500f59b185a682"), + source_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xebb87808992003e0482b3e56df9b966fb33c46798b637a6663239157d19655d48f1e553905f7bc49f61d1f42223bb475")), + target_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xb5ff2f18bf7efc34ee68ecfae0ff51611f382e9fc7dc34634f32a1b4387c3010e996dbdee44e26f591aa2e69c3b58f8c"))) + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0x2629683cfc70198038837270bde3c60176c2a4aeeced0d4a4f14dc99a380c377"), @@ -1952,6 +1966,8 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0x4bd763bcdfcf9fd2ce667c75408bc1157fa9730a"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xdf62e8946d1457a50ce017fae0c36e5dc5177e642c18b74dd6df192620f8a32bef5f02453f0835583f6082f213df7245"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0x86d7b430f69b215ab5ae863998ce41f01a5016376c8bec7f5b7a6e16a2326d92"), @@ -2010,6 +2026,12 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0x4cff44c8f0353fa6dee31f6c87e4b8c3bcaf1c38"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x3166f8e41daae4a0af1549a00b95ad9280d73e91a882d49c827bc078c88300264e7171cbbf50e3598da77bcdb175a203"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ConsolidationRequest( + source_address: ExecutionAddress.fromHex("0x6a8481544d310f4ab07679dc86cff400e403f789"), + source_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x5a89a8355effbeee155130234f8cb602f5648a01290f216272d532cf8a6c2996a55875a804012d4dd2217d4f11353b94")), + target_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x9fe9b12de144e810792b4a82bcbaa538249fd5809df54b5a83f32fc9f290b4ce222575e589d59291cc9c0adc4ccedb8f"))) + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0xc51bf481df9be981c6656081e3854ffcf27551e2b4fdaed4ab12b355f247f4e1"), @@ -2065,6 +2087,8 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0xc61710d4969b77326cfe3ee23b65023c23e8789e"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xb2952e0f7d6581c3032f95f4908bf76f6df8d7e866b7b67996254597ef73ce9a15dac375b78a3456d4f7f156af2b5ed5"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0x8b3e7e8d447527b9d00693389928260e7ea9da6855efd99369182bd9c213988a"), @@ -2094,6 +2118,12 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0x95137ca91b36a9a753441d911bdf91677931615c"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x0e223fadbfa2985e293f13e083bbe22a9a208d0e9f37fd99d24be92b3e329d77f1d40d61b891e2bdfed12ca746eeec50"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ConsolidationRequest( + source_address: ExecutionAddress.fromHex("0xbcd0cbd6a0bf406f2af8b28c0d7509f80bc020ae"), + source_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xd51d34ca13ca3ae5c9f2821414457e0a0e19ac03057e84371954b0f20d4e834997d9592c9e5c3b548097a2497fa4b230")), + target_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x097c5ccdf7e60c886c2fced51dedd5be62f20aed504898cb89e215d655bd5cc450a2219b805717497c978c1fabd7faa0"))) + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0xa4854e346d2e9a921cc6b3c4ce9fc739c99795cf10002924089f9886f8624d59"), @@ -2143,6 +2173,8 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0x9892501906b7abf06fdb6893b8e1767884bc17f5"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x30099e0ee2adf0d51a0a96d10fd2fd5cf6f17cdb4b4ea88b5a0e205bd10d40319595e0403891aaa1bac82b980ef76f23"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0x5e7b12465e0461e5dfa59a3254282378c55961b0e411023ce89d968bbdc33e9c"), @@ -2181,6 +2213,8 @@ suite "Eth1 monitor": ]), withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0xa8f90a617f1f230506d200c6026bd60e38f599930ed04f90cdc320a6d45bb022"), @@ -2215,6 +2249,8 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0xf55f4b626328f2b7a725d8a3f8485072eebf7f6e"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x3eb1812d045ff1d2f7d96f919c41230db2993ed8194de6ba564fad54047e3b45fb925e5216cc47f69e184a4e2c45ce39"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0xc914f63464f3f1588a32d3751900d415bbf1fe002c42068650f5c7c588b1935c"), @@ -2275,6 +2311,12 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0x04fb4574aa211ef818aa9c13135f20f4694b8ce3"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x8d381b3ee22253692bd5861ede4c0d62cb2f6c90df6afd180831ec183ac3f8bcccbbfb5fa1f3ee38d5c3871ca8e28ba3"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ConsolidationRequest( + source_address: ExecutionAddress.fromHex("0x459b669c12e0acba7faa0ba7e6233644ee3d6b80"), + source_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x6d00f156d7db5c9f2a0f1dd38917c5a0062f7ed54436f35e6e363e5db15ea60434482236614e41e37a25b0fcaf19ea5c")), + target_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xc13b30ba7af6c7be66f9af3bf6c6b837a54eb67a88ca19b156285327da4ad7a24205356a862bb7805ccae30f78b2bcc9"))) + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0x086322b79160568c7d096747ef351338ddc93f252dab1df3ef65aaf24723d2c3"), @@ -2314,6 +2356,8 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0x1e6d99ec506e2b79322f77283f3e18dfc0561346"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x25931e58a52265a5a90f7004706cd736fdb762d50aff67039d5e0242039dfc49fd6670e6f4cf62639d7debe3efe5298b"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0xcfba7f4aa4ff01d3d9de84dbe1761c79627a10c3188fb0a7c8adfa0d489e6441"), @@ -2366,6 +2410,12 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0x722d597ea5a6f82a0f9b06bd8af0449d18f78795"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x1de64f16597d52214d1a5987abc026398d310712ad0db48d48e747e7783204579a886bbd9a58a47704d9874a83726a50"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ConsolidationRequest( + source_address: ExecutionAddress.fromHex("0x70ce642845a24bd208442a6aeb263b5d9977926f"), + source_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x581a1e6d7b11b2512426c8aacdc735470ba2b85e164a65062fabbf1341f6cd994ca0c8b2fa8640d679ad481abaa70555")), + target_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x17d58eca3304640ac6da21ac5a629b32573cc99602971e7a751db3ec253e3e75810488fcd60c59dd43cc80ad9cbf66a1"))) + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0x063bc56b731eeeff8bf1c33d88523a04a14fa0c745eb3c750139842d88244982"), @@ -2398,6 +2448,12 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0x748168ee6835196ae76808fe3232a422b40e42a7"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x5e024d736b5c4d340929745f59b7d681eeb151107f895a87d534491b5af13fbf7bed890a2f41dc8debacf2f65fce2c20"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ConsolidationRequest( + source_address: ExecutionAddress.fromHex("0xc80ff3b9e9f68f8a64b9207600adfe37ba1fad50"), + source_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x9495309c1e65aa3ba8097bf1bee00be1f067910a8abcc897f5752eab5962387973e394caf9c873ea71c958c3c08e1b4f")), + target_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xf1a12eaa4fe32257839694fdf8fb17083d6c35fe20d045db01ffa1b45721021b68efc2a7f7f5360493bc1f0902ff121e"))) + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0xb31c41d39ef7e9a9b905cc93d82264415024d7daef48d886f1b3bc0fd6545edb"), @@ -2448,6 +2504,12 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0x308d3b908ce2fb2ebd207120422994608d8c3354"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x3deec67ff0f69aeeeddf322043b694ed4ec79aa2cd2414797bb95da5691b2b9731d3fe3d3627684d022241f80504f3ad"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ConsolidationRequest( + source_address: ExecutionAddress.fromHex("0xfa3b832100b4deb83db5776ebb5c920b88c5ee4f"), + source_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xc414a06a2bfafdb6ccde87c98b99de8124cfedf66b86832cae0ada7005c4939608282a7b947d43b322918765f1cdb1fd")), + target_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x0b4c6a47a37b9fa0633348712fc45033dbd7ab958c8aa8a2c99dbdb325917728586b4dab8846da152df1a51c8301fd9f"))) + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0xf6cba3ced37c08da230babbf9d1e360661e5a21ac235fefa75cbe756f15809de"), @@ -2515,6 +2577,8 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0x14bce680ec1a632aac5f77cb4d5eca52f74bd1e6"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xb4f363283d5276f12a6c2c98c58484c6a6e8e3c7f5b3adfc044d2de76365bef427f8b9ac1e321baa7a611447010f9e8d"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0x62ce6a6d68578309c4730f96f98a809d4b4225fc3d37a285daf26288b10f9590"), @@ -2552,6 +2616,8 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0xe16b15a5256815cf6d338498a5cb0e8ec0d5bfec"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x79b49178606e2a5cda067c04b982d445df7b41d09d4361e5498b7a454d0e8a37a6975da56c3bd20694a3fcb467f7ff59"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0x4f8251c361a23171de8648d1e96c91fea2cc5a691dcd884e3a957dc8f6a8802a"), @@ -2587,6 +2653,12 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0x032d5223828ee1c8943fdacfbcd25ce4bb2eacfd"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0xf42315c025ae7ef0e8a04175441e9617b0e315a9e7c8fc5f0a0bba4efc9775fea3a8af9b40c4aa37633718ccb5b3260d"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ConsolidationRequest( + source_address: ExecutionAddress.fromHex("0x548760f25ecda293ef4950d60520003770b31964"), + source_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x1e384047c673119fbed6c635e11f4db74edddd17cc6e51634f5eea100a21a07012fc9b89d2c7677c282bab0d1136cead")), + target_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x9454bddf457231bf55c91db6a018a0501e97e31d0cb2e7fa180910b75aa1a98e80739885ba4a878df2ef7ac3f2db9fad"))) + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0x0c67b44b492590ffb9e6d2a63c84714821be7526ce1c337c06276e33a62b7b93"), @@ -2633,6 +2705,8 @@ suite "Eth1 monitor": source_address: ExecutionAddress.fromHex("0xd3a0f8518063d55c61423dce1bfcd2abd9a27a62"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x82bec5cd588df021e98087c703b995075ee1cfde2257eebed5e27f53a3a16903479fa2e6864ab3c3c397cd25b6ba3d4f"))), ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0x7a9d6ab34c0314959d5bdceb0bd80f142e59e5e2addedcd178612303897e7a8a"), @@ -2673,7 +2747,13 @@ suite "Eth1 monitor": WithdrawalRequest( source_address: ExecutionAddress.fromHex("0xe368e59ddc49ffac6818f01b4be692a517b6838e"), validator_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x9c7a489a7498cada308db339f80aafeeff5e38ef7dc5803344a725b3b7f23d6d6162a33798a69660417b8fffb51c3d50"))) - ]) + ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ConsolidationRequest( + source_address: ExecutionAddress.fromHex("0x45c3398e59b885ccf52ef5d36ab2acc3c3f9d584"), + source_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x47faa2f4d2bc6e1b2c8366db1e4300fb6fb099f26c9e0cd53b87b22f4fd038751b8fef08f6c1e636116c95874bab5bb1")), + target_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x632e3e022a91046f0a6769abfd159b998321363c79d77b7bc139359fafb4cce331322599fc05fd8c5b1d6aef94e810ed"))) + ]), ), (electra.ExecutionPayload)( parent_hash: Eth2Digest.fromHex("0x806a868f0f31e8f519fa6339ad18c414dba17feb03aaf6ca3775b152bac64f3b"), @@ -2731,7 +2811,13 @@ suite "Eth1 monitor": index: 4403524705240661292'u64), ]), withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(@[ - ]) + ]), + consolidation_requests: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(@[ + ConsolidationRequest( + source_address: ExecutionAddress.fromHex("0xaa3e4b371bd5d3c907eae23ce4c4f6b5dfe0cb65"), + source_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x5bfc2cffb681249ff93734c176a8bac7cb207859a77658019f7fadf0a49f8f5b2496c7fcb2a270ea99f9a80f15b95ac1")), + target_pubkey: ValidatorPubKey(blob: hexToByteArray[48]("0x495170003efda9e294e95cd4d80c903b4fe6c48846b1c8fcbca71b21837e6ca8ffecd0f224aead3e1088ae755a882ae5"))) + ]), )] for executionPayload in executionPayloads: diff --git a/vendor/nim-web3 b/vendor/nim-web3 index b705f8164..fc226d451 160000 --- a/vendor/nim-web3 +++ b/vendor/nim-web3 @@ -1 +1 @@ -Subproject commit b705f816439f0068ece8c234336bc7093222d00f +Subproject commit fc226d4511199aa57a3fcd5cc44695c6b365a6bf From cb2c379b373d429c12f22d13a61b6dd4b0cbbcde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Soko=C5=82owski?= Date: Tue, 18 Jun 2024 09:03:41 +0200 Subject: [PATCH 07/68] update links to public API endpoints in readme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jakub Sokołowski --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6aff067f1..8f78b4e85 100644 --- a/README.md +++ b/README.md @@ -38,9 +38,11 @@ The [Quickstart](https://nimbus.guide/quick-start.html) in particular will help The [Nimbus REST api](https://nimbus.guide/rest-api.html) is now available from: -* http://testing.mainnet.beacon-api.nimbus.team/ * http://unstable.mainnet.beacon-api.nimbus.team/ -* http://unstable.prater.beacon-api.nimbus.team/ +* http://testing.mainnet.beacon-api.nimbus.team/ +* http://unstable.sepolia.beacon-api.nimbus.team/ +* http://testing.holesky.beacon-api.nimbus.team/ +* http://unstable.holesky.beacon-api.nimbus.team/ Note that right now these are very much unstable testing instances. They may be unresponsive at times - so **please do not rely on them for validating**. We may also disable them at any time. From 7a8c1d818a835312cc661e941154556ace0d70b4 Mon Sep 17 00:00:00 2001 From: Kim De Mey Date: Tue, 18 Jun 2024 23:46:51 +0200 Subject: [PATCH 08/68] Bump nim-eth for Opt changes and make Opt related adjustments (#6369) --- beacon_chain/networking/eth2_discovery.nim | 2 +- beacon_chain/networking/eth2_network.nim | 2 +- beacon_chain/nimbus_beacon_node.nim | 6 +++--- ncli/ncli_testnet.nim | 6 +++--- tests/test_discovery.nim | 4 ++-- vendor/nim-eth | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/beacon_chain/networking/eth2_discovery.nim b/beacon_chain/networking/eth2_discovery.nim index e9495e25a..7ead407f7 100644 --- a/beacon_chain/networking/eth2_discovery.nim +++ b/beacon_chain/networking/eth2_discovery.nim @@ -78,7 +78,7 @@ proc loadBootstrapFile*(bootstrapFile: string, proc new*(T: type Eth2DiscoveryProtocol, config: BeaconNodeConf | LightClientConf, - enrIp: Option[IpAddress], enrTcpPort, enrUdpPort: Option[Port], + enrIp: Opt[IpAddress], enrTcpPort, enrUdpPort: Opt[Port], pk: PrivateKey, enrFields: openArray[(string, seq[byte])], rng: ref HmacDrbgContext): T = diff --git a/beacon_chain/networking/eth2_network.nim b/beacon_chain/networking/eth2_network.nim index abb900dff..f2f5fd81a 100644 --- a/beacon_chain/networking/eth2_network.nim +++ b/beacon_chain/networking/eth2_network.nim @@ -1765,7 +1765,7 @@ proc new(T: type Eth2Node, enrForkId: ENRForkID, discoveryForkId: ENRForkID, forkDigests: ref ForkDigests, getBeaconTime: GetBeaconTimeFn, switch: Switch, pubsub: GossipSub, - ip: Option[IpAddress], tcpPort, udpPort: Option[Port], + ip: Opt[IpAddress], tcpPort, udpPort: Opt[Port], privKey: keys.PrivateKey, discovery: bool, directPeers: DirectPeers, rng: ref HmacDrbgContext): T {.raises: [CatchableError].} = diff --git a/beacon_chain/nimbus_beacon_node.nim b/beacon_chain/nimbus_beacon_node.nim index 885647b00..e862c31ee 100644 --- a/beacon_chain/nimbus_beacon_node.nim +++ b/beacon_chain/nimbus_beacon_node.nim @@ -2271,9 +2271,9 @@ proc doRecord(config: BeaconNodeConf, rng: var HmacDrbgContext) {. let record = enr.Record.init( config.seqNumber, netKeys.seckey.asEthKey, - some(config.ipExt), - some(config.tcpPortExt), - some(config.udpPortExt), + Opt.some(config.ipExt), + Opt.some(config.tcpPortExt), + Opt.some(config.udpPortExt), fieldPairs).expect("Record within size limits") echo record.toURI() diff --git a/ncli/ncli_testnet.nim b/ncli/ncli_testnet.nim index de8c98b65..4a4d742ea 100644 --- a/ncli/ncli_testnet.nim +++ b/ncli/ncli_testnet.nim @@ -379,9 +379,9 @@ proc createEnr(rng: var HmacDrbgContext, bootstrapEnr = enr.Record.init( 1, # sequence number networkKeys.seckey.asEthKey, - some(address), - some(port), - some(port), + Opt.some(address), + Opt.some(port), + Opt.some(port), [ toFieldPair(enrForkIdField, forkId), toFieldPair(enrAttestationSubnetsField, SSZ.encode(netMetadata.attnets)) diff --git a/tests/test_discovery.nim b/tests/test_discovery.nim index f33ed569a..662e47e73 100644 --- a/tests/test_discovery.nim +++ b/tests/test_discovery.nim @@ -17,7 +17,7 @@ import proc new(T: type Eth2DiscoveryProtocol, pk: keys.PrivateKey, - enrIp: Option[IpAddress], enrTcpPort, enrUdpPort: Option[Port], + enrIp: Opt[IpAddress], enrTcpPort, enrUdpPort: Opt[Port], bindPort: Port, bindIp: IpAddress, enrFields: openArray[(string, seq[byte])] = [], rng: ref HmacDrbgContext): T = @@ -32,7 +32,7 @@ proc generateNode(rng: ref HmacDrbgContext, port: Port, except ValueError: raiseAssert "Argument is a valid IP address" Eth2DiscoveryProtocol.new(keys.PrivateKey.random(rng[]), - some(ip), some(port), some(port), port, ip, enrFields, rng = rng) + Opt.some(ip), Opt.some(port), Opt.some(port), port, ip, enrFields, rng = rng) # TODO: Add tests with a syncnets preference const noSyncnetsPreference = SyncnetBits() diff --git a/vendor/nim-eth b/vendor/nim-eth index f169068df..26212c881 160000 --- a/vendor/nim-eth +++ b/vendor/nim-eth @@ -1 +1 @@ -Subproject commit f169068df6c11a2aeba27584c60e354e19c42e94 +Subproject commit 26212c881b464ed64cac20442fb45144d3ecd3b3 From f30f670584f33071bc1eb21c45c48711007dbe17 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 19 Jun 2024 05:31:07 +0200 Subject: [PATCH 09/68] bump nim-sqlite3-abi to `262fa35f092cb254abd6eff2a9d46b99392a6dca` (#6356) - bump `sqlite-amalgamation` to `3.45.3` --- vendor/nim-sqlite3-abi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/nim-sqlite3-abi b/vendor/nim-sqlite3-abi index 1453b19b1..262fa35f0 160000 --- a/vendor/nim-sqlite3-abi +++ b/vendor/nim-sqlite3-abi @@ -1 +1 @@ -Subproject commit 1453b19b1a3cac24002dead15e02bd978cb52355 +Subproject commit 262fa35f092cb254abd6eff2a9d46b99392a6dca From 61610fd243d6311635db05c5f74dbe513100a92a Mon Sep 17 00:00:00 2001 From: Eugene Kabanov Date: Thu, 20 Jun 2024 21:57:08 +0300 Subject: [PATCH 10/68] BN: Disable genesis sync via long-range-sync argument. (#6361) * Initial commit. * Update options.md. * Add pre-database initialization weak subjectivity period check. * Add proper log message. --- beacon_chain/beacon_node.nim | 1 + beacon_chain/conf.nim | 9 +++++ beacon_chain/nimbus_beacon_node.nim | 53 +++++++++++++++++++++++++++-- beacon_chain/sync/sync_manager.nim | 30 ++++++++++++++-- beacon_chain/sync/sync_queue.nim | 3 +- docs/the_nimbus_book/src/options.md | 1 + 6 files changed, 91 insertions(+), 6 deletions(-) diff --git a/beacon_chain/beacon_node.nim b/beacon_chain/beacon_node.nim index a7a4f0f76..d85e7113b 100644 --- a/beacon_chain/beacon_node.nim +++ b/beacon_chain/beacon_node.nim @@ -106,6 +106,7 @@ type ## Number of validators that we've checked for activation processingDelay*: Opt[Duration] lastValidAttestedBlock*: Opt[BlockSlot] + shutdownEvent*: AsyncEvent template findIt*(s: openArray, predicate: untyped): int = var res = -1 diff --git a/beacon_chain/conf.nim b/beacon_chain/conf.nim index 454878b3d..8ec54e6ea 100644 --- a/beacon_chain/conf.nim +++ b/beacon_chain/conf.nim @@ -131,6 +131,10 @@ type url*: Uri provenBlockProperties*: seq[string] # empty if this is not a verifying Web3Signer + LongRangeSyncMode* {.pure.} = enum + Light = "light", + Lenient = "lenient" + BeaconNodeConf* = object configFile* {. desc: "Loads the configuration from a TOML file" @@ -557,6 +561,11 @@ type desc: "Maximum number of sync committee periods to retain light client data" name: "light-client-data-max-periods" .}: Option[uint64] + longRangeSync* {. + desc: "Enable long-range syncing (genesis sync)", + defaultValue: LongRangeSyncMode.Light, + name: "long-range-sync".}: LongRangeSyncMode + inProcessValidators* {. desc: "Disable the push model (the beacon node tells a signing process with the private keys of the validators what to sign and when) and load the validators in the beacon node itself" defaultValue: true # the use of the nimbus_signing_process binary by default will be delayed until async I/O over stdin/stdout is developed for the child process. diff --git a/beacon_chain/nimbus_beacon_node.nim b/beacon_chain/nimbus_beacon_node.nim index e862c31ee..6fc2187e8 100644 --- a/beacon_chain/nimbus_beacon_node.nim +++ b/beacon_chain/nimbus_beacon_node.nim @@ -373,6 +373,21 @@ proc initFullNode( func getFrontfillSlot(): Slot = max(dag.frontfill.get(BlockId()).slot, dag.horizon) + proc isWithinWeakSubjectivityPeriod(): bool = + let + currentSlot = node.beaconClock.now().slotOrZero() + checkpoint = Checkpoint( + epoch: epoch(getStateField(node.dag.headState, slot)), + root: getStateField(node.dag.headState, latest_block_header).state_root) + is_within_weak_subjectivity_period(node.dag.cfg, currentSlot, + node.dag.headState, checkpoint) + + proc eventWaiter(): Future[void] {.async: (raises: [CancelledError]).} = + await node.shutdownEvent.wait() + bnStatus = BeaconNodeStatus.Stopping + + asyncSpawn eventWaiter() + let quarantine = newClone( Quarantine.init()) @@ -441,19 +456,29 @@ proc initFullNode( blockProcessor, node.validatorMonitor, dag, attestationPool, validatorChangePool, node.attachedValidators, syncCommitteeMsgPool, lightClientPool, quarantine, blobQuarantine, rng, getBeaconTime, taskpool) + syncManagerFlags = + if node.config.longRangeSync != LongRangeSyncMode.Lenient: + {SyncManagerFlag.NoGenesisSync} + else: + {} syncManager = newSyncManager[Peer, PeerId]( node.network.peerPool, dag.cfg.DENEB_FORK_EPOCH, dag.cfg.MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS, SyncQueueKind.Forward, getLocalHeadSlot, getLocalWallSlot, getFirstSlotAtFinalizedEpoch, getBackfillSlot, - getFrontfillSlot, dag.tail.slot, blockVerifier) + getFrontfillSlot, isWithinWeakSubjectivityPeriod, + dag.tail.slot, blockVerifier, + shutdownEvent = node.shutdownEvent, + flags = syncManagerFlags) backfiller = newSyncManager[Peer, PeerId]( node.network.peerPool, dag.cfg.DENEB_FORK_EPOCH, dag.cfg.MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS, SyncQueueKind.Backward, getLocalHeadSlot, getLocalWallSlot, getFirstSlotAtFinalizedEpoch, getBackfillSlot, - getFrontfillSlot, dag.backfill.slot, blockVerifier, - maxHeadAge = 0) + getFrontfillSlot, isWithinWeakSubjectivityPeriod, + dag.backfill.slot, blockVerifier, maxHeadAge = 0, + shutdownEvent = node.shutdownEvent, + flags = syncManagerFlags) router = (ref MessageRouter)( processor: processor, network: node.network) @@ -554,6 +579,27 @@ proc init*(T: type BeaconNode, template cfg: auto = metadata.cfg template eth1Network: auto = metadata.eth1Network + if not(isDir(config.databaseDir)): + # If database directory missing, we going to use genesis state to check + # for weak_subjectivity_period. + let + genesisState = + await fetchGenesisState( + metadata, config.genesisState, config.genesisStateUrl) + genesisTime = getStateField(genesisState[], genesis_time) + beaconClock = BeaconClock.init(genesisTime).valueOr: + fatal "Invalid genesis time in genesis state", genesisTime + quit 1 + currentSlot = beaconClock.now().slotOrZero() + checkpoint = Checkpoint( + epoch: epoch(getStateField(genesisState[], slot)), + root: getStateField(genesisState[], latest_block_header).state_root) + if config.longRangeSync == LongRangeSyncMode.Light: + if not is_within_weak_subjectivity_period(metadata.cfg, currentSlot, + genesisState[], checkpoint): + fatal WeakSubjectivityLogMessage, current_slot = currentSlot + quit 1 + try: if config.numThreads < 0: fatal "The number of threads --numThreads cannot be negative." @@ -885,6 +931,7 @@ proc init*(T: type BeaconNode, beaconClock: beaconClock, validatorMonitor: validatorMonitor, stateTtlCache: stateTtlCache, + shutdownEvent: newAsyncEvent(), dynamicFeeRecipientsStore: newClone(DynamicFeeRecipientsStore.init())) node.initLightClient( diff --git a/beacon_chain/sync/sync_manager.nim b/beacon_chain/sync/sync_manager.nim index 0e6fa9f3d..6e7c17764 100644 --- a/beacon_chain/sync/sync_manager.nim +++ b/beacon_chain/sync/sync_manager.nim @@ -8,7 +8,7 @@ {.push raises: [].} import std/[strutils, sequtils, algorithm] -import stew/base10, chronos, chronicles +import stew/base10, chronos, chronicles, results import ../spec/datatypes/[phase0, altair], ../spec/eth2_apis/rest_types, @@ -34,13 +34,20 @@ const StatusExpirationTime* = chronos.minutes(2) ## Time time it takes for the peer's status information to expire. + WeakSubjectivityLogMessage* = + "Database state missing or too old, cannot sync - resync the client " & + "using a trusted node or allow lenient long-range syncing with the " & + "`--long-range-sync=lenient` option. See " & + "https://nimbus.guide/faq.html#what-is-long-range-sync " & + "for more information" + type SyncWorkerStatus* {.pure.} = enum Sleeping, WaitingPeer, UpdatingStatus, Requesting, Downloading, Queueing, Processing SyncManagerFlag* {.pure.} = enum - NoMonitor + NoMonitor, NoGenesisSync SyncWorker*[A, B] = object future: Future[void].Raising([CancelledError]) @@ -52,6 +59,7 @@ type MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: uint64 responseTimeout: chronos.Duration maxHeadAge: uint64 + isWithinWeakSubjectivityPeriod: GetBoolCallback getLocalHeadSlot: GetSlotCallback getLocalWallSlot: GetSlotCallback getSafeSlot: GetSlotCallback @@ -60,6 +68,7 @@ type progressPivot: Slot workers: array[SyncWorkersCount, SyncWorker[A, B]] notInSyncEvent: AsyncEvent + shutdownEvent: AsyncEvent rangeAge: uint64 chunkSize: uint64 queue: SyncQueue[A] @@ -124,8 +133,10 @@ proc newSyncManager*[A, B](pool: PeerPool[A, B], getFinalizedSlotCb: GetSlotCallback, getBackfillSlotCb: GetSlotCallback, getFrontfillSlotCb: GetSlotCallback, + weakSubjectivityPeriodCb: GetBoolCallback, progressPivot: Slot, blockVerifier: BlockVerifier, + shutdownEvent: AsyncEvent, maxHeadAge = uint64(SLOTS_PER_EPOCH * 1), chunkSize = uint64(SLOTS_PER_EPOCH), flags: set[SyncManagerFlag] = {}, @@ -143,6 +154,7 @@ proc newSyncManager*[A, B](pool: PeerPool[A, B], MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: minEpochsForBlobSidecarsRequests, getLocalHeadSlot: getLocalHeadSlotCb, getLocalWallSlot: getLocalWallSlotCb, + isWithinWeakSubjectivityPeriod: weakSubjectivityPeriodCb, getSafeSlot: getSafeSlot, getFirstSlot: getFirstSlot, getLastSlot: getLastSlot, @@ -152,6 +164,7 @@ proc newSyncManager*[A, B](pool: PeerPool[A, B], blockVerifier: blockVerifier, notInSyncEvent: newAsyncEvent(), direction: direction, + shutdownEvent: shutdownEvent, ident: ident, flags: flags ) @@ -566,6 +579,11 @@ proc startWorkers[A, B](man: SyncManager[A, B]) = for i in 0 ..< len(man.workers): man.workers[i].future = syncWorker[A, B](man, i) +proc stopWorkers[A, B](man: SyncManager[A, B]) {.async: (raises: []).} = + # Cancelling all the synchronization workers. + let pending = man.workers.mapIt(it.future.cancelAndWait()) + await noCancel allFutures(pending) + proc toTimeLeftString*(d: Duration): string = if d == InfiniteDuration: "--h--m" @@ -711,6 +729,14 @@ proc syncLoop[A, B](man: SyncManager[A, B]) {.async.} = man.avgSyncSpeed.formatBiggestFloat(ffDecimal, 4) & "slots/s (" & map & ":" & currentSlot & ")" + if (man.queue.kind == SyncQueueKind.Forward) and + (SyncManagerFlag.NoGenesisSync in man.flags): + if not(man.isWithinWeakSubjectivityPeriod()): + fatal WeakSubjectivityLogMessage, current_slot = wallSlot + await man.stopWorkers() + man.shutdownEvent.fire() + return + if man.remainingSlots() <= man.maxHeadAge: man.notInSyncEvent.clear() # We are marking SyncManager as not working only when we are in sync and diff --git a/beacon_chain/sync/sync_queue.nim b/beacon_chain/sync/sync_queue.nim index 10f0a9fb2..85b932e88 100644 --- a/beacon_chain/sync/sync_queue.nim +++ b/beacon_chain/sync/sync_queue.nim @@ -8,7 +8,7 @@ {.push raises: [].} import std/[heapqueue, tables, strutils, sequtils, math] -import stew/base10, chronos, chronicles +import stew/base10, chronos, chronicles, results import ../spec/datatypes/[base, phase0, altair], ../spec/[helpers, forks], @@ -24,6 +24,7 @@ logScope: type GetSlotCallback* = proc(): Slot {.gcsafe, raises: [].} + GetBoolCallback* = proc(): bool {.gcsafe, raises: [].} ProcessingCallback* = proc() {.gcsafe, raises: [].} BlockVerifier* = proc(signedBlock: ForkedSignedBeaconBlock, blobs: Opt[BlobSidecars], maybeFinalized: bool): diff --git a/docs/the_nimbus_book/src/options.md b/docs/the_nimbus_book/src/options.md index 670bf7955..16242d407 100644 --- a/docs/the_nimbus_book/src/options.md +++ b/docs/the_nimbus_book/src/options.md @@ -112,6 +112,7 @@ The following options are available: --light-client-data-import-mode Which classes of light client data to import. Must be one of: none, only-new, full (slow startup), on-demand (may miss validator duties) [=only-new]. --light-client-data-max-periods Maximum number of sync committee periods to retain light client data. + --long-range-sync Enable long-range syncing (genesis sync) [=LongRangeSyncMode.Light]. --in-process-validators Disable the push model (the beacon node tells a signing process with the private keys of the validators what to sign and when) and load the validators in the beacon node itself [=true]. From 22b5bc6256c2a5e16f47380eb744453509a20f5a Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Thu, 20 Jun 2024 21:09:41 +0200 Subject: [PATCH 11/68] cleanup Electra fork references (#6372) Adjust two fork references to match surrounding code style. --- beacon_chain/spec/beaconstate.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beacon_chain/spec/beaconstate.nim b/beacon_chain/spec/beaconstate.nim index 340448020..8d4801ca9 100644 --- a/beacon_chain/spec/beaconstate.nim +++ b/beacon_chain/spec/beaconstate.nim @@ -1155,7 +1155,7 @@ func get_next_sync_committee_keys( random_byte = eth2digest(hash_buffer).data[i mod 32] effective_balance = state.validators[candidate_index].effective_balance const meb = - when typeof(state).kind >= Electra: + when typeof(state).kind >= ConsensusFork.Electra: MAX_EFFECTIVE_BALANCE_ELECTRA.Gwei # [Modified in Electra:EIP7251] else: MAX_EFFECTIVE_BALANCE.Gwei @@ -1262,7 +1262,7 @@ func switch_to_compounding_validator*( # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-get_pending_balance_to_withdraw func get_pending_balance_to_withdraw*( - state: Electra.BeaconState, validator_index: ValidatorIndex): Gwei = + state: electra.BeaconState, validator_index: ValidatorIndex): Gwei = var pending_balance: Gwei for withdrawal in state.pending_partial_withdrawals: if withdrawal.index == validator_index: From 31653d58691c012646c3dab095f6537bb22f55d4 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Fri, 21 Jun 2024 14:39:38 +0200 Subject: [PATCH 12/68] fix DB size estimates for light client data (#6373) Addresses two inaccuracies in light client data size documentation: 1. `SyncCommittee` pubkeys serialize are 48 bytes not 64 bytes 2. Some of the estimates used 1000 vs 1024 bytes/KB, aligned to 1024 --- beacon_chain/beacon_chain_db_light_client.nim | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/beacon_chain/beacon_chain_db_light_client.nim b/beacon_chain/beacon_chain_db_light_client.nim index 500e02f3b..8c7cdddd2 100644 --- a/beacon_chain/beacon_chain_db_light_client.nim +++ b/beacon_chain/beacon_chain_db_light_client.nim @@ -26,8 +26,8 @@ logScope: topics = "lcdata" # needs to be bundled together with other data to fulfill requests. # Mainnet data size (all columns): # - Altair: ~38 KB per `SyncCommitteePeriod` (~1.0 MB per month) -# - Capella: ~222 KB per `SyncCommitteePeriod` (~6.1 MB per month) -# - Deneb: ~230 KB per `SyncCommitteePeriod` (~6.3 MB per month) +# - Capella: ~221 KB per `SyncCommitteePeriod` (~6.0 MB per month) +# - Deneb: ~225 KB per `SyncCommitteePeriod` (~6.2 MB per month) # # `lc_altair_current_branches` holds Merkle proofs needed to # construct `LightClientBootstrap` objects. @@ -42,7 +42,7 @@ logScope: topics = "lcdata" # SSZ because this data does not compress well, and because this data # needs to be bundled together with other data to fulfill requests. # Mainnet data size (all columns): -# - Altair ... Deneb: ~32 KB per `SyncCommitteePeriod` (~0.9 MB per month) +# - Altair ... Deneb: ~24 KB per `SyncCommitteePeriod` (~0.7 MB per month) # # `lc_best_updates` holds full `LightClientUpdate` objects in SSZ form. # These objects are frequently queried in bulk, but there is only one per @@ -56,9 +56,9 @@ logScope: topics = "lcdata" # the fork digest, because the same storage format may be used across forks. # SSZ storage selected due to the small size and reduced logic complexity. # Mainnet data size (all columns): -# - Altair: ~33 KB per `SyncCommitteePeriod` (~0.9 MB per month) -# - Capella: ~34 KB per `SyncCommitteePeriod` (~0.9 MB per month) -# - Deneb: ~34 KB per `SyncCommitteePeriod` (~0.9 MB per month) +# - Altair: ~25 KB per `SyncCommitteePeriod` (~0.7 MB per month) +# - Capella: ~26 KB per `SyncCommitteePeriod` (~0.7 MB per month) +# - Deneb: ~26 KB per `SyncCommitteePeriod` (~0.7 MB per month) # # `lc_sealed_periods` contains the sync committee periods for which # full light client data was imported. Data for these periods may no longer @@ -66,6 +66,31 @@ logScope: topics = "lcdata" # when restarting the program. # Mainnet data size (all columns): # - All forks: 8 bytes per `SyncCommitteePeriod` (~0.0 MB per month) +# +# Header computations: +# - Altair: 256*(112+40)/1024*28/1024 +# - Capella: 256*(112+4+600+128+40)/1024*28/1024 +# 600 = 32+20+32+32+256+32+8+8+8+8+4+32+32+32+32+32 +# - Deneb: 256*(112+4+616+128+40)/1024*28/1024 +# 616 = 32+20+32+32+256+32+8+8+8+8+4+32+32+32+32+32+8+8 +# +# Committee branch computations: +# - Altair: 256*(5*32+8)/1024*28/1024 +# +# Finality branch computations: +# - Altair: 256*(6*32+8)/1024*28/1024 +# +# Committee computations: +# - Altair: (24624+8)/1024*28/1024 +# 513*48 = 24624 +# +# Aggregate computations: +# - Altair: 112 = 512/8+48 +# +# Update computations: +# - Altair: (112+24624+5*32+112+6*32+112+8+9)/1024*28/1024 +# - Capella: (4+884+24624+5*32+4+884+6*32+112+8+9)/1024*28/1024 +# - Deneb: (4+900+24624+5*32+4+900+6*32+112+8+9)/1024*28/1024 type LightClientHeaderStore = object From 784a5d3e02e3ee58abe9ec14614430a90444fbf3 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Fri, 21 Jun 2024 22:06:54 +0200 Subject: [PATCH 13/68] remove prater reference from era file docs (#6378) Prater network is no longer relevant, remove reference from docs. --- docs/e2store.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/e2store.md b/docs/e2store.md index 382cbb427..492a672c0 100644 --- a/docs/e2store.md +++ b/docs/e2store.md @@ -183,7 +183,7 @@ Each era is identified by when it ends. Thus, the genesis era is era `0`, follow `.era` file names follow a simple convention: `---.era`: -* `config-name` is the `CONFIG_NAME` field of the runtime configation (`mainnet`, `prater`, `sepolia`, `holesky`, etc) +* `config-name` is the `CONFIG_NAME` field of the runtime configation (`mainnet`, `sepolia`, `holesky`, etc) * `era-number` is the number of the _first_ era stored in the file - for example, the genesis era file has number 0 - as a 5-digit 0-filled decimal integer * `short-era-root` is the first 4 bytes of the last historical root in the _last_ state in the era file, lower-case hex-encoded (8 characters), except the genesis era which instead uses the `genesis_validators_root` field from the genesis state. * The root is available as `state.historical_roots[era - 1]` except for genesis, which is `state.genesis_validators_root` From 573e0f09e1d58646f95499eeb91ba57c49773660 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Fri, 21 Jun 2024 22:09:18 +0200 Subject: [PATCH 14/68] bump nim-libbacktrace to `4db9cae5ac0225e3439f577f5c5cd67086232b3f` (#6380) - bump whereami to `f5e3eac441acbb4ec1fe3e2c32646248ae463398` --- vendor/nim-libbacktrace | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/nim-libbacktrace b/vendor/nim-libbacktrace index aab85b6d2..4db9cae5a 160000 --- a/vendor/nim-libbacktrace +++ b/vendor/nim-libbacktrace @@ -1 +1 @@ -Subproject commit aab85b6d242df38706664373f089675235953ab8 +Subproject commit 4db9cae5ac0225e3439f577f5c5cd67086232b3f From 35c6e68d8452ab092e4c37694f703ebede1f2b54 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Fri, 21 Jun 2024 22:23:16 +0200 Subject: [PATCH 15/68] bump nim-ssz-serialization to `b71ebc41c8e5027580be77a9707df1a64e6d9c8b` (#6381) - Digest fallback when using llvm-mingw on Windows --- vendor/nim-ssz-serialization | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/nim-ssz-serialization b/vendor/nim-ssz-serialization index f8b6e036a..b71ebc41c 160000 --- a/vendor/nim-ssz-serialization +++ b/vendor/nim-ssz-serialization @@ -1 +1 @@ -Subproject commit f8b6e036a00b227c8c0f7cae1394718b5c556f03 +Subproject commit b71ebc41c8e5027580be77a9707df1a64e6d9c8b From 8bc53bde7135080b3401defc93516f1a02b089d9 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Fri, 21 Jun 2024 23:51:25 +0200 Subject: [PATCH 16/68] bump holesky to `874c199423ccd180607320c38cbaca05d9a1573a` (#6377) - Add Chainlens explorer for Holesky - update repository layout --- beacon_chain/networking/network_metadata.nim | 2 +- vendor/holesky | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/beacon_chain/networking/network_metadata.nim b/beacon_chain/networking/network_metadata.nim index 2f2dfce39..c7c0c27d7 100644 --- a/beacon_chain/networking/network_metadata.nim +++ b/beacon_chain/networking/network_metadata.nim @@ -303,7 +303,7 @@ elif const_preset == "mainnet": useBakedInGenesis = Opt.some "mainnet") holeskyMetadata = loadCompileTimeNetworkMetadata( - vendorDir & "/holesky/custom_config_data", + vendorDir & "/holesky/metadata", Opt.some holesky, downloadGenesisFrom = Opt.some DownloadInfo( url: "https://github.com/status-im/nimbus-eth2/releases/download/v23.9.1/holesky-genesis.ssz.sz", diff --git a/vendor/holesky b/vendor/holesky index bc5dfed5d..874c19942 160000 --- a/vendor/holesky +++ b/vendor/holesky @@ -1 +1 @@ -Subproject commit bc5dfed5d939f611ad519a89d84ae227e83b5570 +Subproject commit 874c199423ccd180607320c38cbaca05d9a1573a From b759038ba889f60b40961493562a23b8978b76ca Mon Sep 17 00:00:00 2001 From: tersec Date: Fri, 21 Jun 2024 22:14:28 +0000 Subject: [PATCH 17/68] increase TNS state download timeout to 90 (#6363) --- beacon_chain/trusted_node_sync.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon_chain/trusted_node_sync.nim b/beacon_chain/trusted_node_sync.nim index dfc4c40b5..42b57787a 100644 --- a/beacon_chain/trusted_node_sync.nim +++ b/beacon_chain/trusted_node_sync.nim @@ -21,7 +21,7 @@ import from presto import RestDecodingError const - largeRequestsTimeout = 60.seconds # Downloading large items such as states. + largeRequestsTimeout = 90.seconds # Downloading large items such as states. smallRequestsTimeout = 30.seconds # Downloading smaller items such as blocks and deposit snapshots. proc fetchDepositSnapshot( From 9b6b42c8f9792e657397bb3669a80b57da470c04 Mon Sep 17 00:00:00 2001 From: tersec Date: Sat, 22 Jun 2024 05:28:19 +0000 Subject: [PATCH 18/68] some consensus spec URL updates to v1.5.0-alpha.3 (#6382) --- .../consensus_object_pools/spec_cache.nim | 2 +- beacon_chain/libnimbus_lc/libnimbus_lc.h | 2 +- beacon_chain/networking/eth2_network.nim | 2 +- beacon_chain/spec/beacon_time.nim | 2 +- beacon_chain/spec/beaconstate.nim | 20 +++++++++---------- beacon_chain/spec/datatypes/altair.nim | 2 +- beacon_chain/spec/datatypes/base.nim | 6 +++--- beacon_chain/spec/datatypes/capella.nim | 4 ++-- beacon_chain/spec/datatypes/constants.nim | 2 +- beacon_chain/spec/datatypes/deneb.nim | 6 +++--- beacon_chain/spec/datatypes/electra.nim | 8 ++++---- beacon_chain/spec/helpers.nim | 4 ++-- beacon_chain/spec/keystore.nim | 2 +- beacon_chain/spec/network.nim | 2 +- beacon_chain/spec/signatures_batch.nim | 2 +- beacon_chain/spec/state_transition.nim | 2 +- beacon_chain/spec/state_transition_block.nim | 2 +- beacon_chain/spec/state_transition_epoch.nim | 12 +++++------ beacon_chain/spec/validator.nim | 4 ++-- beacon_chain/sync/light_client_protocol.nim | 2 +- beacon_chain/validators/beacon_validators.nim | 2 +- .../validators/slashing_protection_v2.nim | 2 +- docs/attestation_flow.md | 2 +- docs/block_flow.md | 2 +- 24 files changed, 48 insertions(+), 48 deletions(-) diff --git a/beacon_chain/consensus_object_pools/spec_cache.nim b/beacon_chain/consensus_object_pools/spec_cache.nim index a1f114f76..650d1b898 100644 --- a/beacon_chain/consensus_object_pools/spec_cache.nim +++ b/beacon_chain/consensus_object_pools/spec_cache.nim @@ -53,7 +53,7 @@ iterator get_beacon_committee*( committees_per_slot * SLOTS_PER_EPOCH ): yield (index_in_committee, idx) -# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#get_beacon_committee +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#get_beacon_committee func get_beacon_committee*( shufflingRef: ShufflingRef, slot: Slot, committee_index: CommitteeIndex): seq[ValidatorIndex] = diff --git a/beacon_chain/libnimbus_lc/libnimbus_lc.h b/beacon_chain/libnimbus_lc/libnimbus_lc.h index 7a107e133..397b62ef2 100644 --- a/beacon_chain/libnimbus_lc/libnimbus_lc.h +++ b/beacon_chain/libnimbus_lc/libnimbus_lc.h @@ -579,7 +579,7 @@ typedef struct ETHLightClientHeader ETHLightClientHeader; * * @return Latest finalized header. * - * @see https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/light-client/sync-protocol.md#modified-lightclientheader + * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/light-client/sync-protocol.md#modified-lightclientheader */ ETH_RESULT_USE_CHECK const ETHLightClientHeader *ETHLightClientStoreGetFinalizedHeader( diff --git a/beacon_chain/networking/eth2_network.nim b/beacon_chain/networking/eth2_network.nim index f2f5fd81a..a2e08871c 100644 --- a/beacon_chain/networking/eth2_network.nim +++ b/beacon_chain/networking/eth2_network.nim @@ -2520,7 +2520,7 @@ proc updateStabilitySubnetMetadata*(node: Eth2Node, attnets: AttnetBits) = node.metadata.seq_number += 1 node.metadata.attnets = attnets - # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/phase0/p2p-interface.md#attestation-subnet-subscription + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/p2p-interface.md#attestation-subnet-subscription # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.4/specs/phase0/p2p-interface.md#attestation-subnet-bitfield let res = node.discovery.updateRecord({ enrAttestationSubnetsField: SSZ.encode(node.metadata.attnets) diff --git a/beacon_chain/spec/beacon_time.nim b/beacon_chain/spec/beacon_time.nim index e548d96c7..868620efd 100644 --- a/beacon_chain/spec/beacon_time.nim +++ b/beacon_chain/spec/beacon_time.nim @@ -196,7 +196,7 @@ func since_epoch_start*(slot: Slot): uint64 = # aka compute_slots_since_epoch_st template is_epoch*(slot: Slot): bool = slot.since_epoch_start == 0 -# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#compute_start_slot_at_epoch +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#compute_start_slot_at_epoch func start_slot*(epoch: Epoch): Slot = # aka compute_start_slot_at_epoch ## Return the start slot of ``epoch``. const maxEpoch = Epoch(FAR_FUTURE_SLOT div SLOTS_PER_EPOCH) diff --git a/beacon_chain/spec/beaconstate.nim b/beacon_chain/spec/beaconstate.nim index 8d4801ca9..6a93204fb 100644 --- a/beacon_chain/spec/beaconstate.nim +++ b/beacon_chain/spec/beaconstate.nim @@ -67,7 +67,7 @@ func get_validator_from_deposit*( effective_balance: effective_balance ) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#updated-get_validator_from_deposit +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#updated-get_validator_from_deposit func get_validator_from_deposit*( state: electra.BeaconState, deposit: DepositData): Validator = Validator( @@ -86,7 +86,7 @@ func compute_activation_exit_epoch*(epoch: Epoch): Epoch = ## ``epoch`` take effect. epoch + 1 + MAX_SEED_LOOKAHEAD -# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#get_validator_churn_limit +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#get_validator_churn_limit func get_validator_churn_limit*( cfg: RuntimeConfig, state: ForkyBeaconState, cache: var StateCache): uint64 = @@ -589,7 +589,7 @@ iterator get_attesting_indices_iter*(state: ForkyBeaconState, if bits[index_in_committee]: yield validator_index -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#modified-get_attesting_indices +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#modified-get_attesting_indices iterator get_attesting_indices_iter*( state: electra.BeaconState, data: AttestationData, @@ -617,7 +617,7 @@ func get_attesting_indices*( toSeq(get_attesting_indices_iter(state, data, aggregation_bits, cache)) -# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#get_attesting_indices +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#get_attesting_indices func get_attesting_indices*( state: ForkyBeaconState, data: AttestationData, aggregation_bits: ElectraCommitteeValidatorsBits, committee_bits: auto, @@ -734,7 +734,7 @@ func check_attestation_target_epoch( # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#attestations # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#modified-process_attestation -# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#modified-process_attestation +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/deneb/beacon-chain.md#modified-process_attestation func check_attestation_inclusion( consensusFork: static ConsensusFork, attestation_slot: Slot, current_slot: Slot): Result[void, cstring] = @@ -763,7 +763,7 @@ func check_attestation_index( Result[CommitteeIndex, cstring] = check_attestation_index(data.index, committees_per_slot) -# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#get_attestation_participation_flag_indices +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/beacon-chain.md#get_attestation_participation_flag_indices func get_attestation_participation_flag_indices( state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState, data: AttestationData, inclusion_delay: uint64): set[TimelyFlag] = @@ -1166,17 +1166,17 @@ func get_next_sync_committee_keys( i += 1'u64 res -# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#has_eth1_withdrawal_credential +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#has_eth1_withdrawal_credential func has_eth1_withdrawal_credential*(validator: Validator): bool = ## Check if ``validator`` has an 0x01 prefixed "eth1" withdrawal credential. validator.withdrawal_credentials.data[0] == ETH1_ADDRESS_WITHDRAWAL_PREFIX -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-is_compounding_withdrawal_credential +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#new-is_compounding_withdrawal_credential func is_compounding_withdrawal_credential*( withdrawal_credentials: Eth2Digest): bool = withdrawal_credentials.data[0] == COMPOUNDING_WITHDRAWAL_PREFIX -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-has_compounding_withdrawal_credential +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#new-has_compounding_withdrawal_credential func has_compounding_withdrawal_credential*(validator: Validator): bool = ## Check if ``validator`` has an 0x02 prefixed "compounding" withdrawal ## credential. @@ -1859,7 +1859,7 @@ func upgrade_to_capella*(cfg: RuntimeConfig, pre: bellatrix.BeaconState): # historical_summaries initialized to correct default automatically ) -# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/deneb/fork.md#upgrading-the-state +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/deneb/fork.md#upgrading-the-state func upgrade_to_deneb*(cfg: RuntimeConfig, pre: capella.BeaconState): ref deneb.BeaconState = let diff --git a/beacon_chain/spec/datatypes/altair.nim b/beacon_chain/spec/datatypes/altair.nim index 3c3e8fbba..69b22ab05 100644 --- a/beacon_chain/spec/datatypes/altair.nim +++ b/beacon_chain/spec/datatypes/altair.nim @@ -175,7 +175,7 @@ type ## Current sync committee corresponding to `header.beacon.state_root` current_sync_committee_branch*: CurrentSyncCommitteeBranch - # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/sync-protocol.md#lightclientupdate + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/sync-protocol.md#lightclientupdate LightClientUpdate* = object attested_header*: LightClientHeader ## Header attested to by the sync committee diff --git a/beacon_chain/spec/datatypes/base.nim b/beacon_chain/spec/datatypes/base.nim index 346be4637..3e440c724 100644 --- a/beacon_chain/spec/datatypes/base.nim +++ b/beacon_chain/spec/datatypes/base.nim @@ -326,7 +326,7 @@ type withdrawable_epoch*: Epoch ## When validator can withdraw funds - # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#pendingattestation + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#pendingattestation PendingAttestation* = object aggregation_bits*: CommitteeValidatorsBits data*: AttestationData @@ -335,7 +335,7 @@ type proposer_index*: uint64 # `ValidatorIndex` after validation - # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#historicalbatch + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#historicalbatch HistoricalBatch* = object block_roots* : array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest] state_roots* : array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest] @@ -371,7 +371,7 @@ type state_root*: Eth2Digest body_root*: Eth2Digest - # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#signingdata + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#signingdata SigningData* = object object_root*: Eth2Digest domain*: Eth2Domain diff --git a/beacon_chain/spec/datatypes/capella.nim b/beacon_chain/spec/datatypes/capella.nim index 3c70337db..82c956486 100644 --- a/beacon_chain/spec/datatypes/capella.nim +++ b/beacon_chain/spec/datatypes/capella.nim @@ -132,7 +132,7 @@ type ## Execution payload header corresponding to `beacon.body_root` (from Capella onward) execution_branch*: ExecutionBranch - # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/sync-protocol.md#lightclientbootstrap + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/sync-protocol.md#lightclientbootstrap LightClientBootstrap* = object header*: LightClientHeader ## Header matching the requested beacon block root @@ -221,7 +221,7 @@ type ## (used to compute safety threshold) current_max_active_participants*: uint64 - # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#beaconstate + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#beaconstate BeaconState* = object # Versioning genesis_time*: uint64 diff --git a/beacon_chain/spec/datatypes/constants.nim b/beacon_chain/spec/datatypes/constants.nim index fdb83ae4b..2a84749a1 100644 --- a/beacon_chain/spec/datatypes/constants.nim +++ b/beacon_chain/spec/datatypes/constants.nim @@ -87,5 +87,5 @@ const UNSET_DEPOSIT_REQUESTS_START_INDEX*: uint64 = not 0'u64 FULL_EXIT_REQUEST_AMOUNT*: uint64 = 0 - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#withdrawal-prefixes + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#withdrawal-prefixes COMPOUNDING_WITHDRAWAL_PREFIX* = 0x02 diff --git a/beacon_chain/spec/datatypes/deneb.nim b/beacon_chain/spec/datatypes/deneb.nim index 042b55664..810be1717 100644 --- a/beacon_chain/spec/datatypes/deneb.nim +++ b/beacon_chain/spec/datatypes/deneb.nim @@ -76,7 +76,7 @@ type kzg_commitment*: KzgCommitment versioned_hash*: string # TODO should be string; VersionedHash not distinct - # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/deneb/p2p-interface.md#blobidentifier + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/deneb/p2p-interface.md#blobidentifier BlobIdentifier* = object block_root*: Eth2Digest index*: BlobIndex @@ -382,7 +382,7 @@ type state_root*: Eth2Digest body*: TrustedBeaconBlockBody - # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#beaconblockbody + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/deneb/beacon-chain.md#beaconblockbody BeaconBlockBody* = object randao_reveal*: ValidatorSig eth1_data*: Eth1Data @@ -466,7 +466,7 @@ type bls_to_execution_changes*: SignedBLSToExecutionChangeList blob_kzg_commitments*: KzgCommitments # [New in Deneb] - # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#signedbeaconblock + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#signedbeaconblock SignedBeaconBlock* = object message*: BeaconBlock signature*: ValidatorSig diff --git a/beacon_chain/spec/datatypes/electra.nim b/beacon_chain/spec/datatypes/electra.nim index 4fba931f9..954950069 100644 --- a/beacon_chain/spec/datatypes/electra.nim +++ b/beacon_chain/spec/datatypes/electra.nim @@ -57,7 +57,7 @@ type signature*: ValidatorSig index*: uint64 - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#indexedattestation + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#indexedattestation IndexedAttestation* = object attesting_indices*: List[uint64, Limit MAX_VALIDATORS_PER_COMMITTEE * MAX_COMMITTEES_PER_SLOT] @@ -191,7 +191,7 @@ type NextSyncCommitteeBranch = array[log2trunc(NEXT_SYNC_COMMITTEE_GINDEX), Eth2Digest] - # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#aggregateandproof + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/validator.md#aggregateandproof AggregateAndProof* = object aggregator_index*: uint64 # `ValidatorIndex` after validation aggregate*: Attestation @@ -211,7 +211,7 @@ type ## Execution payload header corresponding to `beacon.body_root` (from Capella onward) execution_branch*: capella.ExecutionBranch - # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/sync-protocol.md#lightclientbootstrap + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/sync-protocol.md#lightclientbootstrap LightClientBootstrap* = object header*: LightClientHeader ## Header matching the requested beacon block root @@ -395,7 +395,7 @@ type data*: BeaconState root*: Eth2Digest # hash_tree_root(data) - # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#beaconblock + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/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 diff --git a/beacon_chain/spec/helpers.nim b/beacon_chain/spec/helpers.nim index e54671aa7..5c244eb72 100644 --- a/beacon_chain/spec/helpers.nim +++ b/beacon_chain/spec/helpers.nim @@ -159,7 +159,7 @@ func compute_domain*( result[0..3] = domain_type.data result[4..31] = fork_data_root.data.toOpenArray(0, 27) -# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#get_domain +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#get_domain func get_domain*( fork: Fork, domain_type: DomainType, @@ -255,7 +255,7 @@ func create_blob_sidecars*( res.add(sidecar) res -# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/sync-protocol.md#is_sync_committee_update +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/sync-protocol.md#is_sync_committee_update template is_sync_committee_update*(update: SomeForkyLightClientUpdate): bool = when update is SomeForkyLightClientUpdateWithSyncCommittee: update.next_sync_committee_branch != diff --git a/beacon_chain/spec/keystore.nim b/beacon_chain/spec/keystore.nim index 2cc14ff16..bd32f6871 100644 --- a/beacon_chain/spec/keystore.nim +++ b/beacon_chain/spec/keystore.nim @@ -1380,7 +1380,7 @@ proc createWallet*(kdfKind: KdfKind, crypto: crypto, nextAccount: nextAccount.get(0)) -# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#bls_withdrawal_prefix +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/validator.md#bls_withdrawal_prefix func makeWithdrawalCredentials*(k: ValidatorPubKey): Eth2Digest = var bytes = eth2digest(k.toRaw()) bytes.data[0] = BLS_WITHDRAWAL_PREFIX.uint8 diff --git a/beacon_chain/spec/network.nim b/beacon_chain/spec/network.nim index d456184cc..d36fe7112 100644 --- a/beacon_chain/spec/network.nim +++ b/beacon_chain/spec/network.nim @@ -14,7 +14,7 @@ import export base const - # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/phase0/p2p-interface.md#topics-and-messages + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/p2p-interface.md#topics-and-messages # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/p2p-interface.md#topics-and-messages topicBeaconBlocksSuffix* = "beacon_block/ssz_snappy" topicVoluntaryExitsSuffix* = "voluntary_exit/ssz_snappy" diff --git a/beacon_chain/spec/signatures_batch.nim b/beacon_chain/spec/signatures_batch.nim index 5374b68f5..02c0564de 100644 --- a/beacon_chain/spec/signatures_batch.nim +++ b/beacon_chain/spec/signatures_batch.nim @@ -83,7 +83,7 @@ func aggregateAttesters( # Aggregation spec requires non-empty collection # - https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04 # Consensus specs require at least one attesting index in attestation - # - https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#is_valid_indexed_attestation + # - https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#is_valid_indexed_attestation return err("aggregateAttesters: no attesting indices") let diff --git a/beacon_chain/spec/state_transition.nim b/beacon_chain/spec/state_transition.nim index 3b72df934..ef922b96b 100644 --- a/beacon_chain/spec/state_transition.nim +++ b/beacon_chain/spec/state_transition.nim @@ -365,7 +365,7 @@ func partialBeaconBlock*( ): auto = const consensusFork = typeof(state).kind - # https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/phase0/validator.md#preparing-for-a-beaconblock + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/validator.md#preparing-for-a-beaconblock var res = consensusFork.BeaconBlock( slot: state.data.slot, proposer_index: proposer_index.uint64, diff --git a/beacon_chain/spec/state_transition_block.nim b/beacon_chain/spec/state_transition_block.nim index 035666e19..e9ad6237e 100644 --- a/beacon_chain/spec/state_transition_block.nim +++ b/beacon_chain/spec/state_transition_block.nim @@ -135,7 +135,7 @@ func is_slashable_validator(validator: Validator, epoch: Epoch): bool = (validator.activation_epoch <= epoch) and (epoch < validator.withdrawable_epoch) -# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#proposer-slashings +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#proposer-slashings proc check_proposer_slashing*( state: ForkyBeaconState, proposer_slashing: SomeProposerSlashing, flags: UpdateFlags): diff --git a/beacon_chain/spec/state_transition_epoch.nim b/beacon_chain/spec/state_transition_epoch.nim index cad91c038..ddcd62653 100644 --- a/beacon_chain/spec/state_transition_epoch.nim +++ b/beacon_chain/spec/state_transition_epoch.nim @@ -535,7 +535,7 @@ func get_attestation_component_delta( else: RewardDelta(penalties: base_reward) -# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#components-of-attestation-deltas +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#components-of-attestation-deltas func get_source_delta*( validator: RewardStatus, base_reward: Gwei, @@ -694,7 +694,7 @@ func get_unslashed_participating_increment*( flag_index: TimelyFlag): uint64 = info.balances.previous_epoch[flag_index] div EFFECTIVE_BALANCE_INCREMENT.Gwei -# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#get_flag_index_deltas +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/beacon-chain.md#get_flag_index_deltas func get_active_increments*( info: altair.EpochInfo | bellatrix.BeaconState): uint64 = info.balances.current_epoch div EFFECTIVE_BALANCE_INCREMENT.Gwei @@ -986,7 +986,7 @@ func slashing_penalty_applies*(validator: Validator, epoch: Epoch): bool = epoch + EPOCHS_PER_SLASHINGS_VECTOR div 2 == validator.withdrawable_epoch # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slashings -# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#slashings +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#slashings func get_slashing_penalty*(validator: Validator, adjusted_total_slashing_balance, @@ -1113,7 +1113,7 @@ func process_historical_roots_update*(state: var ForkyBeaconState) = if next_epoch mod (SLOTS_PER_HISTORICAL_ROOT div SLOTS_PER_EPOCH) == 0: # Equivalent to hash_tree_root(foo: HistoricalBatch), but without using # significant additional stack or heap. - # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#historicalbatch + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#historicalbatch # In response to https://github.com/status-im/nimbus-eth2/issues/921 if not state.historical_roots.add state.compute_historical_root(): raiseAssert "no more room for historical roots, so long and thanks for the fish!" @@ -1202,7 +1202,7 @@ func process_inactivity_updates*( if pre_inactivity_score != inactivity_score: state.inactivity_scores[index] = inactivity_score -# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#historical-summaries-updates +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#historical-summaries-updates func process_historical_summaries_update*( state: var (capella.BeaconState | deneb.BeaconState | electra.BeaconState)): Result[void, cstring] = @@ -1369,7 +1369,7 @@ func init*( deneb.BeaconState | electra.BeaconState): T = init(result, state) -# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#epoch-processing +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/beacon-chain.md#epoch-processing proc process_epoch*( cfg: RuntimeConfig, state: var (altair.BeaconState | bellatrix.BeaconState), diff --git a/beacon_chain/spec/validator.nim b/beacon_chain/spec/validator.nim index b10fa09b3..cc04b33ce 100644 --- a/beacon_chain/spec/validator.nim +++ b/beacon_chain/spec/validator.nim @@ -158,7 +158,7 @@ func get_shuffled_active_validator_indices*( withState(state): cache.get_shuffled_active_validator_indices(forkyState.data, epoch) -# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#get_active_validator_indices +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#get_active_validator_indices func count_active_validators*(state: ForkyBeaconState, epoch: Epoch, cache: var StateCache): uint64 = @@ -394,7 +394,7 @@ func compute_proposer_index(state: ForkyBeaconState, ## Return from ``indices`` a random index sampled by effective balance. compute_proposer_index(state, indices, seed, shuffled_index) -# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#get_beacon_proposer_index +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#get_beacon_proposer_index func get_beacon_proposer_index*( state: ForkyBeaconState, cache: var StateCache, slot: Slot): Opt[ValidatorIndex] = diff --git a/beacon_chain/sync/light_client_protocol.nim b/beacon_chain/sync/light_client_protocol.nim index 909549732..339313c00 100644 --- a/beacon_chain/sync/light_client_protocol.nim +++ b/beacon_chain/sync/light_client_protocol.nim @@ -134,7 +134,7 @@ p2pProtocol LightClientSync(version = 1, debug "LC updates by range request done", peer, startPeriod, count, found - # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/p2p-interface.md#getlightclientfinalityupdate + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/p2p-interface.md#getlightclientfinalityupdate proc lightClientFinalityUpdate( peer: Peer, response: SingleChunkResponse[ForkedLightClientFinalityUpdate]) diff --git a/beacon_chain/validators/beacon_validators.nim b/beacon_chain/validators/beacon_validators.nim index f6316bd89..7c99c28b7 100644 --- a/beacon_chain/validators/beacon_validators.nim +++ b/beacon_chain/validators/beacon_validators.nim @@ -1964,7 +1964,7 @@ proc handleValidatorDuties*(node: BeaconNode, lastSlot, slot: Slot) {.async: (ra updateValidatorMetrics(node) # the important stuff is done, update the vanity numbers - # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#broadcast-aggregate + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/validator.md#broadcast-aggregate # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/validator.md#broadcast-sync-committee-contribution # Wait 2 / 3 of the slot time to allow messages to propagate, then collect # the result in aggregates diff --git a/beacon_chain/validators/slashing_protection_v2.nim b/beacon_chain/validators/slashing_protection_v2.nim index 0f1e201f4..96359db80 100644 --- a/beacon_chain/validators/slashing_protection_v2.nim +++ b/beacon_chain/validators/slashing_protection_v2.nim @@ -36,7 +36,7 @@ export results # - https://notes.ethereum.org/@djrtwo/Bkn3zpwxB#Validator-responsibilities # # Phase 0 spec - Honest Validator - how to avoid slashing -# - https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#how-to-avoid-slashing +# - https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/validator.md#how-to-avoid-slashing # # In-depth reading on slashing conditions # diff --git a/docs/attestation_flow.md b/docs/attestation_flow.md index 31c792d37..9e48bceaf 100644 --- a/docs/attestation_flow.md +++ b/docs/attestation_flow.md @@ -6,7 +6,7 @@ This is a WIP document to explain the attestation flows. It is important to distinguish attestation `validation` from attestation `verification`. - Attestation `validation` is defined in the P2P specs. Validated attestations can be forwarded on GossipSub. - - Aggregated: https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.1/specs/phase0/p2p-interface.md#beacon_aggregate_and_proof + - Aggregated: https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/p2p-interface.md#beacon_aggregate_and_proof - Unaggregated: https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/p2p-interface.md#beacon_attestation_subnet_id - Attestation `verification` is defined in the consensus specs. Verified attestations can affect fork choice and may be included in a block. - https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#attestations diff --git a/docs/block_flow.md b/docs/block_flow.md index ec6be43c1..9c37f2154 100644 --- a/docs/block_flow.md +++ b/docs/block_flow.md @@ -9,7 +9,7 @@ Important distinction: https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/p2p-interface.md#beacon_block. A validated block can be forwarded on gossipsub. - and we distinguish `verification` which is defined in consensus specs: - https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#block-processing + https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/beacon-chain.md#block-processing A block needs to be verified to enter fork choice, the DAG and the BeaconChainDB In particular in terms of costly checks validating a block only requires checking: From 6d0c9d37fa4ac794068bf8509298e66723ebe260 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Sun, 23 Jun 2024 15:06:58 +0200 Subject: [PATCH 19/68] produce Elctra attestations when running tests (#6383) Test blocks don't include Electra attestations currently so finality breaks and tests fail if prolonged. Fix that. --- tests/testblockutil.nim | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/testblockutil.nim b/tests/testblockutil.nim index 15b6c0980..1e8e05a8b 100644 --- a/tests/testblockutil.nim +++ b/tests/testblockutil.nim @@ -611,11 +611,17 @@ iterator makeTestBlocks*( let parent_root = withState(state[]): forkyState.latest_block_root attestations = - if attested: + if attested and state.kind < ConsensusFork.Electra: makeFullAttestations( state[], parent_root, getStateField(state[], slot), cache) else: @[] + electraAttestations = + if attested and state.kind >= ConsensusFork.Electra: + makeFullElectraAttestations( + state[], parent_root, getStateField(state[], slot), cache) + else: + @[] stateEth1 = getStateField(state[], eth1_data) stateDepositIndex = getStateField(state[], eth1_deposit_index) deposits = @@ -633,7 +639,8 @@ iterator makeTestBlocks*( state[], cache, eth1_data = eth1_data, attestations = attestations, + electraAttestations = electraAttestations, deposits = deposits, sync_aggregate = sync_aggregate, graffiti = graffiti, - cfg = cfg) \ No newline at end of file + cfg = cfg) From e4efe9ed7543d080bd94141f264e265428dd3c9a Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Mon, 24 Jun 2024 01:35:56 +0200 Subject: [PATCH 20/68] ensure that rarely ran files are compiled on PR (#6379) * ensure that rarely ran files are compiled on PR Add some missing files to `isMainModule` developer internal builds CI. * fix fork choice compilation * fix `rest_api_benchmark` compilation * skip linking * fix loop * fix `mock_genesis` * fix signedness --- .github/workflows/ci.yml | 15 +++++++++++++-- beacon_chain/fork_choice/fork_choice.nim | 4 ++-- benchmarks/rest_api_benchmark.nim | 19 ++++++++++++++----- tests/mocking/mock_genesis.nim | 2 +- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8aa3aebbd..19bbff1ee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -226,9 +226,20 @@ jobs: - name: Build files with isMainModule run: | + executables=( + "beacon_chain/el/deposit_contract" + "beacon_chain/fork_choice/fork_choice" + "beacon_chain/fork_choice/proto_array" + "beacon_chain/networking/network_metadata_downloads" + "beacon_chain/era_db" + "beacon_chain/trusted_node_sync" + "benchmarks/rest_api_benchmark" + "tests/mocking/mock_genesis" + ) source env.sh - nim c beacon_chain/era_db - nim c beacon_chain/trusted_node_sync + for executable in "${executables[@]}"; do + nim c --passC:-fsyntax-only --noLinking:on -d:chronicles_log_level=TRACE "${executable}" + done lint: name: "Lint" diff --git a/beacon_chain/fork_choice/fork_choice.nim b/beacon_chain/fork_choice/fork_choice.nim index 0156a2b3d..6b638ce58 100644 --- a/beacon_chain/fork_choice/fork_choice.nim +++ b/beacon_chain/fork_choice/fork_choice.nim @@ -502,8 +502,8 @@ when isMainModule: for i in 0 ..< validator_count: indices.add fakeHash(i), i votes.add default(VoteTracker) - old_balances.add 0 - new_balances.add 0 + old_balances.add 0.Gwei + new_balances.add 0.Gwei let err = deltas.compute_deltas( indices, indices_offset = 0, votes, old_balances, new_balances diff --git a/benchmarks/rest_api_benchmark.nim b/benchmarks/rest_api_benchmark.nim index 00050e3ab..c496ef62f 100644 --- a/benchmarks/rest_api_benchmark.nim +++ b/benchmarks/rest_api_benchmark.nim @@ -1,3 +1,12 @@ +# beacon_chain +# Copyright (c) 2022-2024 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. + +{.push raises: [].} + import chronicles, chronicles/[topics_registry, timings], confutils, confutils/std/net, @@ -6,11 +15,11 @@ import type Config = object serverIpAddress {. - defaultValue: ValidIpAddress.init("127.0.0.1") + defaultValue: static(parseIpAddress("127.0.0.1")) defaultValueDesc: "127.0.0.1" desc: "IP address of the beacon node's REST server" abbr: "a" - name: "address" }: ValidIpAddress + name: "address" }: IpAddress serverPort {. defaultValue: 5052 @@ -29,7 +38,7 @@ type abbr: "n" name: "count" }: uint -proc main = +proc main() {.raises: [ConfigurationError, HttpError, OSError].} = let config = Config.load let serverAddress = initTAddress(config.serverIpAddress, config.serverPort) let client = RestClientRef.new(serverAddress) @@ -43,10 +52,10 @@ proc main = info.logTime(apiName): for slot in config.startSlot ..< (config.startSlot + config.requestsCount): let ident = StateIdent(kind: StateQueryKind.Slot, slot: slot.Slot) - discard waitFor client.`apiNameIdent`(ident) + discard waitFor noCancel client.`apiNameIdent`(ident) benchmark(getStateRoot) - benchmark(getStateFork) + benchmark(getStateForkPlain) benchmark(getStateFinalityCheckpoints) benchmark(getStateValidatorBalances) diff --git a/tests/mocking/mock_genesis.nim b/tests/mocking/mock_genesis.nim index 0e0b74c9f..66bb6ace2 100644 --- a/tests/mocking/mock_genesis.nim +++ b/tests/mocking/mock_genesis.nim @@ -39,4 +39,4 @@ proc initGenesisState*( when isMainModule: # Smoke test let state = initGenesisState(num_validators = SLOTS_PER_EPOCH) - doAssert state.validators.len == SLOTS_PER_EPOCH \ No newline at end of file + doAssert getStateField(state[], validators).lenu64 == SLOTS_PER_EPOCH From cd4de1357a954b1af89b10135acb2d6bf71e56e8 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Mon, 24 Jun 2024 11:13:15 +0200 Subject: [PATCH 21/68] during proposal duties, perform sync aggregation duties if not received (#6384) Including sync contributions into a block affects validator rewards. When we have not received aggregate sync contributions, but have seen individual messages, we can produce the contributions locally, improving validator rewards when subscribing to all subnets or when having a non-aggregating attached validator in the sync committee. --- .../sync_committee_msg_pool.nim | 63 ++++++++++++------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/beacon_chain/consensus_object_pools/sync_committee_msg_pool.nim b/beacon_chain/consensus_object_pools/sync_committee_msg_pool.nim index 3903246ca..89fc6ce7e 100644 --- a/beacon_chain/consensus_object_pools/sync_committee_msg_pool.nim +++ b/beacon_chain/consensus_object_pools/sync_committee_msg_pool.nim @@ -217,15 +217,16 @@ func produceContribution*( else: false -func addAggregateAux(bestVotes: var BestSyncSubcommitteeContributions, - contribution: SyncCommitteeContribution) = +func addContribution( + contributions: var BestSyncSubcommitteeContributions, + contribution: SyncCommitteeContribution) = let currentBestTotalParticipants = - bestVotes.subnets[contribution.subcommittee_index].totalParticipants + contributions.subnets[contribution.subcommittee_index].totalParticipants newBestTotalParticipants = countOnes(contribution.aggregation_bits) if newBestTotalParticipants > currentBestTotalParticipants: - bestVotes.subnets[contribution.subcommittee_index] = + contributions.subnets[contribution.subcommittee_index] = BestSyncSubcommitteeContribution( totalParticipants: newBestTotalParticipants, participationBits: contribution.aggregation_bits, @@ -241,10 +242,10 @@ func isSeen*( seenKey in pool.seenContributionByAuthor func covers( - bestVotes: BestSyncSubcommitteeContributions, + contributions: BestSyncSubcommitteeContributions, contribution: SyncCommitteeContribution): bool = contribution.aggregation_bits.isSubsetOf( - bestVotes.subnets[contribution.subcommittee_index].participationBits) + contributions.subnets[contribution.subcommittee_index].participationBits) func covers*( pool: var SyncCommitteeMsgPool, @@ -271,22 +272,12 @@ proc addContribution(pool: var SyncCommitteeMsgPool, pool.seenContributionByAuthor.incl seenKey let target = pool.cfg.toSyncMsgTarget(bid, contribution.slot) - if target notin pool.bestContributions: - let totalParticipants = countOnes(contribution.aggregation_bits) - var initialBestContributions = BestSyncSubcommitteeContributions() - - initialBestContributions.subnets[contribution.subcommittee_index] = - BestSyncSubcommitteeContribution( - totalParticipants: totalParticipants, - participationBits: contribution.aggregation_bits, - signature: signature) - - pool.bestContributions[target] = initialBestContributions - else: - try: - addAggregateAux(pool.bestContributions[target], contribution) - except KeyError: - raiseAssert "We have checked for the key upfront" + pool.bestContributions.withValue(target, contributions): + contributions[].addContribution(contribution) + do: + var contributions: BestSyncSubcommitteeContributions + contributions.addContribution(contribution) + pool.bestContributions[target] = contributions proc addContribution*(pool: var SyncCommitteeMsgPool, scproof: SignedContributionAndProof, @@ -334,11 +325,35 @@ proc produceSyncAggregateAux( aggregate proc produceSyncAggregate*( - pool: SyncCommitteeMsgPool, + pool: var SyncCommitteeMsgPool, bid: BlockId, signatureSlot: Slot): SyncAggregate = # Sync committee signs previous slot, relative to when new block is produced - let target = pool.cfg.toSyncMsgTarget(bid, max(signatureSlot, 1.Slot) - 1) + let + slot = max(signatureSlot, 1.Slot) - 1 + target = pool.cfg.toSyncMsgTarget(bid, slot) + + var contribution {.noinit.}: SyncCommitteeContribution + pool.bestContributions.withValue(target, contributions): + for subcommitteeIdx in SyncSubcommitteeIndex: + if contributions.subnets[subcommitteeIdx].totalParticipants == 0 and + pool.produceContribution(slot, bid, subcommitteeIdx, contribution): + debug "Did not receive contribution, did aggregate locally", + target, subcommitteeIdx + contributions[].addContribution(contribution) + do: + var + contributions: BestSyncSubcommitteeContributions + didAggregate = false + for subcommitteeIdx in SyncSubcommitteeIndex: + if pool.produceContribution(slot, bid, subcommitteeIdx, contribution): + debug "Did not receive contribution, did aggregate locally", + target, subcommitteeIdx + contributions.addContribution(contribution) + didAggregate = true + if didAggregate: + pool.bestContributions[target] = contributions + if target in pool.bestContributions: try: produceSyncAggregateAux(pool.bestContributions[target]) From 7b680bb72dfb75e2b66247141db941210e71967f Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Mon, 24 Jun 2024 12:05:01 +0200 Subject: [PATCH 22/68] bump nim-libp2p to `v1.2.1-rc` (#6354) - chore(README): small PRs - Send IDONTWANT before validating message - chore(peer-scoring): enhance score trace logs (x2) - chore: fix typos - fix(multicodec): remove unnecessary "!=" operator --- vendor/nim-libp2p | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/nim-libp2p b/vendor/nim-libp2p index 2fa2c4425..8cb7dbb42 160000 --- a/vendor/nim-libp2p +++ b/vendor/nim-libp2p @@ -1 +1 @@ -Subproject commit 2fa2c4425f4bb835c0517efc03009925dcd28239 +Subproject commit 8cb7dbb425df1124b17c6b3142a19a380114a693 From 2d4ece0c3b81152ecc48b8c8fb0557d017a10d0b Mon Sep 17 00:00:00 2001 From: tersec Date: Mon, 24 Jun 2024 22:02:16 +0000 Subject: [PATCH 23/68] bump nimbus-build-system to use Nim v2.0.6 (#6386) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * bump nimbus-build-system to use Nim v2.0.6 * fix: update name and hash for csources of Nim v2 Otherwise we get errors like: ``` Building: Nim compiler /build/source/vendor/nimbus-build-system/vendor/Nim /build/source cmd: git clone -q --depth 1 -b master https://github.com/nim-lang/csources_v2.git csources_v2 24.6.0-dirty cmd: cd csources_v2 ci/funs.sh: line 10: cd: csources_v2: No such file or directory make[1]: *** [vendor/nimbus-build-system/makefiles/targets.mk:81: build-nim] Error 1 ``` Also need to add source for `checksums` repository. Signed-off-by: Jakub Sokołowski --------- Signed-off-by: Jakub Sokołowski Co-authored-by: Jakub Sokołowski --- .github/workflows/ci.yml | 13 ++++--------- nix/checksums.nix | 12 ++++++++++++ nix/csources.nix | 4 ++-- nix/default.nix | 11 +++++------ vendor/nimbus-build-system | 2 +- 5 files changed, 24 insertions(+), 18 deletions(-) create mode 100644 nix/checksums.nix diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 19bbff1ee..bb3025379 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,21 +35,16 @@ jobs: cpu: amd64 - os: windows cpu: amd64 - branch: [~, upstream/version-1-6, v2.0.6] + branch: [~, upstream/version-2-0] exclude: - target: os: macos - branch: upstream/version-1-6 + branch: upstream/version-2-0 - target: os: windows - branch: upstream/version-1-6 - - target: - os: windows - branch: ~ + branch: upstream/version-2-0 include: - - branch: upstream/version-1-6 - branch-short: version-1-6 - - branch: v2.0.6 + - branch: upstream/version-2-0 branch-short: version-2-0 nimflags-extra: --mm:refc - target: diff --git a/nix/checksums.nix b/nix/checksums.nix new file mode 100644 index 000000000..c3b322e3a --- /dev/null +++ b/nix/checksums.nix @@ -0,0 +1,12 @@ +{ pkgs ? import { } }: + +let + tools = pkgs.callPackage ./tools.nix {}; + sourceFile = ../vendor/nimbus-build-system/vendor/Nim/koch.nim; +in pkgs.fetchFromGitHub { + owner = "nim-lang"; + repo = "checksums"; + rev = tools.findKeyValue "^ +ChecksumsStableCommit = \"([a-f0-9]+)\"$" sourceFile; + # WARNING: Requires manual updates when Nim compiler version changes. + hash = "sha256-AIiMBqLcGJCTkINHfJ2dN3ogitU7Za9Z9Sv9zjKeOQk="; +} diff --git a/nix/csources.nix b/nix/csources.nix index ed217e5cf..33cd9d0fc 100644 --- a/nix/csources.nix +++ b/nix/csources.nix @@ -5,8 +5,8 @@ let sourceFile = ../vendor/nimbus-build-system/vendor/Nim/config/build_config.txt; in pkgs.fetchFromGitHub { owner = "nim-lang"; - repo = "csources_v1"; + repo = "csources_v2"; rev = tools.findKeyValue "^nim_csourcesHash=([a-f0-9]+)$" sourceFile; # WARNING: Requires manual updates when Nim compiler version changes. - hash = "sha256-gwBFuR7lzO4zttR/6rgdjXMRxVhwKeLqDwpmOwMyU7A="; + hash = "sha256-UCLtoxOcGYjBdvHx7A47x6FjLMi6VZqpSs65MN7fpBs="; } diff --git a/nix/default.nix b/nix/default.nix index a86470974..a444329eb 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -19,9 +19,7 @@ let inherit (pkgs) stdenv lib writeScriptBin callPackage; - nimble = callPackage ./nimble.nix {}; - csources = callPackage ./csources.nix {}; - revision = lib.substring 0 8 (src.rev or "dirty"); + revision = lib.substring 0 8 (src.rev or "unknown"); in stdenv.mkDerivation rec { pname = "nimbus-eth2"; version = "${callPackage ./version.nix {}}-${revision}"; @@ -60,9 +58,10 @@ in stdenv.mkDerivation rec { preBuild = '' pushd vendor/nimbus-build-system/vendor/Nim mkdir dist - cp -r ${nimble} dist/nimble - cp -r ${csources} csources_v1 - chmod 777 -R dist/nimble csources_v1 + cp -r ${callPackage ./nimble.nix {}} dist/nimble + cp -r ${callPackage ./checksums.nix {}} dist/checksums + cp -r ${callPackage ./csources.nix {}} csources_v2 + chmod 777 -R dist/nimble csources_v2 sed -i 's/isGitRepo(destDir)/false/' tools/deps.nim popd ''; diff --git a/vendor/nimbus-build-system b/vendor/nimbus-build-system index 8cdaec502..09a356878 160000 --- a/vendor/nimbus-build-system +++ b/vendor/nimbus-build-system @@ -1 +1 @@ -Subproject commit 8cdaec502b5a48f2514e11209f0d81a001d2a2b1 +Subproject commit 09a35687897041c152986f13473466fa55f987ca From 288540e794f62d544e0630881f460242c152ebca Mon Sep 17 00:00:00 2001 From: tersec Date: Wed, 26 Jun 2024 08:48:49 +0000 Subject: [PATCH 24/68] fix UnnamedBreak deprecation build warnings (#6388) --- .../consensus_object_pools/spec_cache.nim | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/beacon_chain/consensus_object_pools/spec_cache.nim b/beacon_chain/consensus_object_pools/spec_cache.nim index 650d1b898..323546559 100644 --- a/beacon_chain/consensus_object_pools/spec_cache.nim +++ b/beacon_chain/consensus_object_pools/spec_cache.nim @@ -123,21 +123,21 @@ iterator get_attesting_indices*(shufflingRef: ShufflingRef, iterator get_attesting_indices*( dag: ChainDAGRef, attestation: phase0.TrustedAttestation, on_chain: static bool = true): ValidatorIndex = - block: # `return` is not allowed in an inline iterator + block gaiBlock: # `return` is not allowed in an inline iterator let slot = check_attestation_slot_target(attestation.data).valueOr: warn "Invalid attestation slot in trusted attestation", attestation = shortLog(attestation) doAssert strictVerification notin dag.updateFlags - break + break gaiBlock blck = dag.getBlockRef(attestation.data.beacon_block_root).valueOr: # Attestation block unknown - this is fairly common because we # discard alternative histories on restart debug "Pruned block in trusted attestation", attestation = shortLog(attestation) - break + break gaiBlock target = blck.atCheckpoint(attestation.data.target).valueOr: # This may happen when there's no block at the epoch boundary slot @@ -148,7 +148,7 @@ iterator get_attesting_indices*( blck = shortLog(blck), attestation = shortLog(attestation) doAssert strictVerification notin dag.updateFlags - break + break gaiBlock shufflingRef = dag.getShufflingRef(target.blck, target.slot.epoch, false).valueOr: warn "Attestation shuffling not found", @@ -156,7 +156,7 @@ iterator get_attesting_indices*( attestation = shortLog(attestation) doAssert strictVerification notin dag.updateFlags - break + break gaiBlock committeesPerSlot = get_committee_count_per_slot(shufflingRef) committeeIndex = @@ -166,7 +166,7 @@ iterator get_attesting_indices*( attestation = shortLog(attestation) doAssert strictVerification notin dag.updateFlags - break + break gaiBlock for validator in get_attesting_indices( shufflingRef, slot, committeeIndex, attestation.aggregation_bits): @@ -175,21 +175,21 @@ iterator get_attesting_indices*( iterator get_attesting_indices*( dag: ChainDAGRef, attestation: electra.TrustedAttestation, on_chain: static bool): ValidatorIndex = - block: # `return` is not allowed in an inline iterator + block gaiBlock: # `return` is not allowed in an inline iterator let slot = check_attestation_slot_target(attestation.data).valueOr: warn "Invalid attestation slot in trusted attestation", attestation = shortLog(attestation) doAssert strictVerification notin dag.updateFlags - break + break gaiBlock blck = dag.getBlockRef(attestation.data.beacon_block_root).valueOr: # Attestation block unknown - this is fairly common because we # discard alternative histories on restart debug "Pruned block in trusted attestation", attestation = shortLog(attestation) - break + break gaiBlock target = blck.atCheckpoint(attestation.data.target).valueOr: # This may happen when there's no block at the epoch boundary slot @@ -200,7 +200,7 @@ iterator get_attesting_indices*( blck = shortLog(blck), attestation = shortLog(attestation) doAssert strictVerification notin dag.updateFlags - break + break gaiBlock shufflingRef = dag.getShufflingRef(target.blck, target.slot.epoch, false).valueOr: warn "Attestation shuffling not found", @@ -208,7 +208,7 @@ iterator get_attesting_indices*( attestation = shortLog(attestation) doAssert strictVerification notin dag.updateFlags - break + break gaiBlock for validator in get_attesting_indices( shufflingRef, slot, attestation.committee_bits, From 3da85e593f45a056646e9ebb7bf192cd2a3e50af Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 26 Jun 2024 14:31:36 +0200 Subject: [PATCH 25/68] update references for LC related Nim issues (#6389) Addresses feedback from #6375 that is applicable to pre-existing code moreso than to the new PR. --- beacon_chain/spec/datatypes/altair.nim | 2 +- beacon_chain/spec/datatypes/capella.nim | 6 ++--- beacon_chain/spec/datatypes/deneb.nim | 6 ++--- beacon_chain/spec/forks_light_client.nim | 32 ++++++++++++++++-------- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/beacon_chain/spec/datatypes/altair.nim b/beacon_chain/spec/datatypes/altair.nim index 69b22ab05..f2e5c6512 100644 --- a/beacon_chain/spec/datatypes/altair.nim +++ b/beacon_chain/spec/datatypes/altair.nim @@ -684,7 +684,7 @@ func shortLog*(v: LightClientUpdate): auto = ( attested: shortLog(v.attested_header), has_next_sync_committee: - v.next_sync_committee != default(typeof(v.next_sync_committee)), + v.next_sync_committee != static(default(typeof(v.next_sync_committee))), finalized: shortLog(v.finalized_header), num_active_participants: v.sync_aggregate.num_active_participants, signature_slot: v.signature_slot diff --git a/beacon_chain/spec/datatypes/capella.nim b/beacon_chain/spec/datatypes/capella.nim index 82c956486..a69edd52d 100644 --- a/beacon_chain/spec/datatypes/capella.nim +++ b/beacon_chain/spec/datatypes/capella.nim @@ -674,8 +674,8 @@ func is_valid_light_client_header*( if epoch < cfg.CAPELLA_FORK_EPOCH: return - header.execution == default(ExecutionPayloadHeader) and - header.execution_branch == default(ExecutionBranch) + header.execution == static(default(ExecutionPayloadHeader)) and + header.execution_branch == static(default(ExecutionBranch)) is_valid_merkle_branch( get_lc_execution_root(header, cfg), @@ -745,7 +745,7 @@ func shortLog*(v: LightClientUpdate): auto = ( attested: shortLog(v.attested_header), has_next_sync_committee: - v.next_sync_committee != default(typeof(v.next_sync_committee)), + v.next_sync_committee != static(default(typeof(v.next_sync_committee))), finalized: shortLog(v.finalized_header), num_active_participants: v.sync_aggregate.num_active_participants, signature_slot: v.signature_slot diff --git a/beacon_chain/spec/datatypes/deneb.nim b/beacon_chain/spec/datatypes/deneb.nim index 810be1717..1f136ed9a 100644 --- a/beacon_chain/spec/datatypes/deneb.nim +++ b/beacon_chain/spec/datatypes/deneb.nim @@ -667,8 +667,8 @@ func is_valid_light_client_header*( if epoch < cfg.CAPELLA_FORK_EPOCH: return - header.execution == default(ExecutionPayloadHeader) and - header.execution_branch == default(ExecutionBranch) + header.execution == static(default(ExecutionPayloadHeader)) and + header.execution_branch == static(default(ExecutionBranch)) is_valid_merkle_branch( get_lc_execution_root(header, cfg), @@ -757,7 +757,7 @@ func shortLog*(v: LightClientUpdate): auto = ( attested: shortLog(v.attested_header), has_next_sync_committee: - v.next_sync_committee != default(typeof(v.next_sync_committee)), + v.next_sync_committee != static(default(typeof(v.next_sync_committee))), finalized: shortLog(v.finalized_header), num_active_participants: v.sync_aggregate.num_active_participants, signature_slot: v.signature_slot diff --git a/beacon_chain/spec/forks_light_client.nim b/beacon_chain/spec/forks_light_client.nim index 780ba4739..1c3de1d0e 100644 --- a/beacon_chain/spec/forks_light_client.nim +++ b/beacon_chain/spec/forks_light_client.nim @@ -159,7 +159,8 @@ func lcDataForkAtEpoch*( LightClientDataFork.None template kind*( - x: typedesc[ # `SomeLightClientObject` doesn't work here (Nim 1.6) + # `SomeLightClientObject`: https://github.com/nim-lang/Nim/issues/18095 + x: typedesc[ altair.LightClientHeader | altair.LightClientBootstrap | altair.LightClientUpdate | @@ -169,7 +170,8 @@ template kind*( LightClientDataFork.Altair template kind*( - x: typedesc[ # `SomeLightClientObject` doesn't work here (Nim 1.6) + # `SomeLightClientObject`: https://github.com/nim-lang/Nim/issues/18095 + x: typedesc[ capella.LightClientHeader | capella.LightClientBootstrap | capella.LightClientUpdate | @@ -179,7 +181,8 @@ template kind*( LightClientDataFork.Capella template kind*( - x: typedesc[ # `SomeLightClientObject` doesn't work here (Nim 1.6) + # `SomeLightClientObject`: https://github.com/nim-lang/Nim/issues/18095 + x: typedesc[ deneb.LightClientHeader | deneb.LightClientBootstrap | deneb.LightClientUpdate | @@ -831,7 +834,8 @@ func migratingToDataFork*[ # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/full-node.md#block_to_light_client_header func toAltairLightClientHeader( - blck: # `SomeSignedBeaconBlock` doesn't work here (Nim 1.6) + # `SomeSignedBeaconBlock`: https://github.com/nim-lang/Nim/issues/18095 + blck: phase0.SignedBeaconBlock | phase0.TrustedSignedBeaconBlock | altair.SignedBeaconBlock | altair.TrustedSignedBeaconBlock | bellatrix.SignedBeaconBlock | bellatrix.TrustedSignedBeaconBlock @@ -841,7 +845,8 @@ func toAltairLightClientHeader( # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/light-client/full-node.md#modified-block_to_light_client_header func toCapellaLightClientHeader( - blck: # `SomeSignedBeaconBlock` doesn't work here (Nim 1.6) + # `SomeSignedBeaconBlock`: https://github.com/nim-lang/Nim/issues/18095 + blck: phase0.SignedBeaconBlock | phase0.TrustedSignedBeaconBlock | altair.SignedBeaconBlock | altair.TrustedSignedBeaconBlock | bellatrix.SignedBeaconBlock | bellatrix.TrustedSignedBeaconBlock @@ -856,7 +861,8 @@ func toCapellaLightClientHeader( beacon: blck.message.toBeaconBlockHeader()) func toCapellaLightClientHeader( - blck: # `SomeSignedBeaconBlock` doesn't work here (Nim 1.6) + # `SomeSignedBeaconBlock`: https://github.com/nim-lang/Nim/issues/18095 + blck: capella.SignedBeaconBlock | capella.TrustedSignedBeaconBlock ): capella.LightClientHeader = template payload: untyped = blck.message.body.execution_payload @@ -883,7 +889,8 @@ func toCapellaLightClientHeader( # https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.0/specs/deneb/light-client/full-node.md#modified-block_to_light_client_header func toDenebLightClientHeader( - blck: # `SomeSignedBeaconBlock` doesn't work here (Nim 1.6) + # `SomeSignedBeaconBlock`: https://github.com/nim-lang/Nim/issues/18095 + blck: phase0.SignedBeaconBlock | phase0.TrustedSignedBeaconBlock | altair.SignedBeaconBlock | altair.TrustedSignedBeaconBlock | bellatrix.SignedBeaconBlock | bellatrix.TrustedSignedBeaconBlock @@ -898,7 +905,8 @@ func toDenebLightClientHeader( beacon: blck.message.toBeaconBlockHeader()) func toDenebLightClientHeader( - blck: # `SomeSignedBeaconBlock` doesn't work here (Nim 1.6) + # `SomeSignedBeaconBlock`: https://github.com/nim-lang/Nim/issues/18095 + blck: capella.SignedBeaconBlock | capella.TrustedSignedBeaconBlock ): deneb.LightClientHeader = template payload: untyped = blck.message.body.execution_payload @@ -924,7 +932,8 @@ func toDenebLightClientHeader( capella.EXECUTION_PAYLOAD_GINDEX).get) func toDenebLightClientHeader( - blck: # `SomeSignedBeaconBlock` doesn't work here (Nim 1.6) + # `SomeSignedBeaconBlock`: https://github.com/nim-lang/Nim/issues/18095 + blck: deneb.SignedBeaconBlock | deneb.TrustedSignedBeaconBlock ): deneb.LightClientHeader = template payload: untyped = blck.message.body.execution_payload @@ -952,7 +961,8 @@ func toDenebLightClientHeader( capella.EXECUTION_PAYLOAD_GINDEX).get) func toLightClientHeader*( - blck: # `SomeSignedBeaconBlock` doesn't work here (Nim 1.6) + # `SomeSignedBeaconBlock`: https://github.com/nim-lang/Nim/issues/18095 + blck: phase0.SignedBeaconBlock | phase0.TrustedSignedBeaconBlock | altair.SignedBeaconBlock | altair.TrustedSignedBeaconBlock | bellatrix.SignedBeaconBlock | bellatrix.TrustedSignedBeaconBlock | @@ -991,7 +1001,7 @@ func shortLog*[ of LightClientDataFork.Deneb: denebData: typeof(x.denebData.shortLog()) - let xKind = x.kind # Nim 1.6.12: Using `kind: x.kind` inside case is broken + let xKind = x.kind # Nim 2.0.6: Using `kind: x.kind` inside case is broken case xKind of LightClientDataFork.Deneb: ResultType(kind: xKind, denebData: x.denebData.shortLog()) From 9924aec1e394a56bb7f2ec6ecbf280aec81b1551 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 26 Jun 2024 21:02:03 +0200 Subject: [PATCH 26/68] extend light client protocol for Electra (#6375) * extend light client protocol for Electra Add missing Electra support for light client protocol: - https://github.com/ethereum/consensus-specs/pull/3811 Tested against PR consensus-spec-tests, the test runner automatically picks up the new tests once available. * workaround `version-2-0`: `Error: cannot instantiate: 'SomeUnsignedInt'` * fix initialization when Electra not scheduled * try reduce stack size in test * put correct sync committee branch version into DB * adjust fork schedule in light client data tests * further reduce stack size * split function into multiple parts * rename variable * regenerate test reports to cover new Electra tests * add Nim bug reference --- ConsensusSpecPreset-mainnet.md | 10 +- ConsensusSpecPreset-minimal.md | 10 +- beacon_chain/beacon_chain_db.nim | 12 +- beacon_chain/beacon_chain_db_light_client.nim | 96 +++-- .../block_pools_types_light_client.nim | 8 +- .../blockchain_dag_light_client.nim | 72 ++-- .../light_client_processor.nim | 89 +++-- beacon_chain/spec/datatypes/deneb.nim | 7 +- beacon_chain/spec/datatypes/electra.nim | 258 ++++++++++++- .../eth2_apis/eth2_rest_serialization.nim | 5 + beacon_chain/spec/forks.nim | 6 +- beacon_chain/spec/forks_light_client.nim | 350 ++++++++++++++++-- beacon_chain/spec/light_client_sync.nim | 63 ++-- ...est_fixture_light_client_sync_protocol.nim | 24 +- tests/test_light_client.nim | 6 +- tests/test_light_client_processor.nim | 68 ++-- 16 files changed, 877 insertions(+), 207 deletions(-) diff --git a/ConsensusSpecPreset-mainnet.md b/ConsensusSpecPreset-mainnet.md index 9f7b5a296..588512d14 100644 --- a/ConsensusSpecPreset-mainnet.md +++ b/ConsensusSpecPreset-mainnet.md @@ -3156,6 +3156,14 @@ OK: 6/6 Fail: 0/6 Skip: 0/6 + EF - Electra - Transition - transition_with_random_three_quarters_participation [Preset: m OK ``` OK: 25/25 Fail: 0/25 Skip: 0/25 +## EF - Electra - Unittests - Light client - Sync protocol [Preset: mainnet] +```diff ++ process_light_client_update_finality_updated OK ++ process_light_client_update_timeout OK ++ test_process_light_client_update_at_period_boundary OK ++ test_process_light_client_update_not_timeout OK +``` +OK: 4/4 Fail: 0/4 Skip: 0/4 ## EF - Light client - Single merkle proof [Preset: mainnet] ```diff + Light client - Single merkle proof - mainnet/altair/light_client/single_merkle_proof/Beaco OK @@ -3685,4 +3693,4 @@ OK: 69/88 Fail: 0/88 Skip: 19/88 OK: 3/3 Fail: 0/3 Skip: 0/3 ---TOTAL--- -OK: 2967/2987 Fail: 0/2987 Skip: 20/2987 +OK: 2971/2991 Fail: 0/2991 Skip: 20/2991 diff --git a/ConsensusSpecPreset-minimal.md b/ConsensusSpecPreset-minimal.md index e0cfad762..d4bb95796 100644 --- a/ConsensusSpecPreset-minimal.md +++ b/ConsensusSpecPreset-minimal.md @@ -3321,6 +3321,14 @@ OK: 6/6 Fail: 0/6 Skip: 0/6 + EF - Electra - Transition - transition_with_voluntary_exit_right_before_fork [Preset: mini OK ``` OK: 30/30 Fail: 0/30 Skip: 0/30 +## EF - Electra - Unittests - Light client - Sync protocol [Preset: minimal] +```diff ++ process_light_client_update_finality_updated OK ++ process_light_client_update_timeout OK ++ test_process_light_client_update_at_period_boundary OK ++ test_process_light_client_update_not_timeout OK +``` +OK: 4/4 Fail: 0/4 Skip: 0/4 ## EF - Light client - Single merkle proof [Preset: minimal] ```diff + Light client - Single merkle proof - minimal/altair/light_client/single_merkle_proof/Beaco OK @@ -4011,4 +4019,4 @@ OK: 185/207 Fail: 0/207 Skip: 22/207 OK: 3/3 Fail: 0/3 Skip: 0/3 ---TOTAL--- -OK: 3262/3285 Fail: 0/3285 Skip: 23/3285 +OK: 3266/3289 Fail: 0/3289 Skip: 23/3289 diff --git a/beacon_chain/beacon_chain_db.nim b/beacon_chain/beacon_chain_db.nim index 54500005d..fac0cd2f5 100644 --- a/beacon_chain/beacon_chain_db.nim +++ b/beacon_chain/beacon_chain_db.nim @@ -542,12 +542,22 @@ proc new*(T: type BeaconChainDB, "lc_deneb_headers" else: "", + electraHeaders: + if cfg.DENEB_FORK_EPOCH != FAR_FUTURE_EPOCH: + "lc_electra_headers" + else: + "", altairCurrentBranches: "lc_altair_current_branches", + electraCurrentBranches: + if cfg.ELECTRA_FORK_EPOCH != FAR_FUTURE_EPOCH: + "lc_electra_current_branches" + else: + "", altairSyncCommittees: "lc_altair_sync_committees", legacyAltairBestUpdates: "lc_altair_best_updates", bestUpdates: "lc_best_updates", sealedPeriods: "lc_sealed_periods")).expectDb() - static: doAssert LightClientDataFork.high == LightClientDataFork.Deneb + static: doAssert LightClientDataFork.high == LightClientDataFork.Electra var blobs : KvStoreRef if cfg.DENEB_FORK_EPOCH != FAR_FUTURE_EPOCH: diff --git a/beacon_chain/beacon_chain_db_light_client.nim b/beacon_chain/beacon_chain_db_light_client.nim index 8c7cdddd2..3ba23b022 100644 --- a/beacon_chain/beacon_chain_db_light_client.nim +++ b/beacon_chain/beacon_chain_db_light_client.nim @@ -28,13 +28,15 @@ logScope: topics = "lcdata" # - Altair: ~38 KB per `SyncCommitteePeriod` (~1.0 MB per month) # - Capella: ~221 KB per `SyncCommitteePeriod` (~6.0 MB per month) # - Deneb: ~225 KB per `SyncCommitteePeriod` (~6.2 MB per month) +# - Electra: ~249 KB per `SyncCommitteePeriod` (~6.8 MB per month) # -# `lc_altair_current_branches` holds Merkle proofs needed to +# `lc_xxxxx_current_branches` holds Merkle proofs needed to # construct `LightClientBootstrap` objects. # SSZ because this data does not compress well, and because this data # needs to be bundled together with other data to fulfill requests. # Mainnet data size (all columns): # - Altair ... Deneb: ~42 KB per `SyncCommitteePeriod` (~1.1 MB per month) +# - Electra: ~50 KB per `SyncCommitteePeriod` (~1.4 MB per month) # # `lc_altair_sync_committees` contains a copy of finalized sync committees. # They are initially populated from the main DAG (usually a fast state access). @@ -42,7 +44,7 @@ logScope: topics = "lcdata" # SSZ because this data does not compress well, and because this data # needs to be bundled together with other data to fulfill requests. # Mainnet data size (all columns): -# - Altair ... Deneb: ~24 KB per `SyncCommitteePeriod` (~0.7 MB per month) +# - Altair ... Electra: ~24 KB per `SyncCommitteePeriod` (~0.7 MB per month) # # `lc_best_updates` holds full `LightClientUpdate` objects in SSZ form. # These objects are frequently queried in bulk, but there is only one per @@ -59,6 +61,7 @@ logScope: topics = "lcdata" # - Altair: ~25 KB per `SyncCommitteePeriod` (~0.7 MB per month) # - Capella: ~26 KB per `SyncCommitteePeriod` (~0.7 MB per month) # - Deneb: ~26 KB per `SyncCommitteePeriod` (~0.7 MB per month) +# - Electra: ~27 KB per `SyncCommitteePeriod` (~0.7 MB per month) # # `lc_sealed_periods` contains the sync committee periods for which # full light client data was imported. Data for these periods may no longer @@ -73,12 +76,16 @@ logScope: topics = "lcdata" # 600 = 32+20+32+32+256+32+8+8+8+8+4+32+32+32+32+32 # - Deneb: 256*(112+4+616+128+40)/1024*28/1024 # 616 = 32+20+32+32+256+32+8+8+8+8+4+32+32+32+32+32+8+8 +# - Electra: 256*(112+4+712+128+40)/1024*28/1024 +# 712 = 32+20+32+32+256+32+8+8+8+8+4+32+32+32+32+32+8+8+32+32+32 # # Committee branch computations: # - Altair: 256*(5*32+8)/1024*28/1024 +# - Electra: 256*(6*32+8)/1024*28/1024 # # Finality branch computations: # - Altair: 256*(6*32+8)/1024*28/1024 +# - Electra: 256*(7*32+8)/1024*28/1024 # # Committee computations: # - Altair: (24624+8)/1024*28/1024 @@ -91,6 +98,7 @@ logScope: topics = "lcdata" # - Altair: (112+24624+5*32+112+6*32+112+8+9)/1024*28/1024 # - Capella: (4+884+24624+5*32+4+884+6*32+112+8+9)/1024*28/1024 # - Deneb: (4+900+24624+5*32+4+900+6*32+112+8+9)/1024*28/1024 +# - Electra: (4+996+24624+6*32+4+996+7*32+112+8+9)/1024*28/1024 type LightClientHeaderStore = object @@ -98,6 +106,11 @@ type putStmt: SqliteStmt[(array[32, byte], int64, seq[byte]), void] keepFromStmt: SqliteStmt[int64, void] + BranchFork {.pure.} = enum + None = 0, + Altair, + Electra + CurrentSyncCommitteeBranchStore = object containsStmt: SqliteStmt[int64, int64] getStmt: SqliteStmt[int64, seq[byte]] @@ -135,8 +148,8 @@ type ## Eth2Digest -> (Slot, LightClientHeader) ## Cached block headers to support longer retention than block storage. - currentBranches: CurrentSyncCommitteeBranchStore - ## Slot -> altair.CurrentSyncCommitteeBranch + currentBranches: array[BranchFork, CurrentSyncCommitteeBranchStore] + ## Slot -> CurrentSyncCommitteeBranch ## Cached data for creating future `LightClientBootstrap` instances. ## Key is the block slot of which the post state was used to get the data. ## Data stored for all finalized epoch boundary blocks. @@ -234,12 +247,14 @@ func putHeader*[T: ForkyLightClientHeader]( proc initCurrentBranchesStore( backend: SqStoreRef, - name: string): KvResult[CurrentSyncCommitteeBranchStore] = + name, typeName: string): KvResult[CurrentSyncCommitteeBranchStore] = + if name == "": + return ok CurrentSyncCommitteeBranchStore() if not backend.readOnly: ? backend.exec(""" CREATE TABLE IF NOT EXISTS `""" & name & """` ( `slot` INTEGER PRIMARY KEY, -- `Slot` (up through 2^63-1) - `branch` BLOB -- `altair.CurrentSyncCommitteeBranch` (SSZ) + `branch` BLOB -- `""" & typeName & """` (SSZ) ); """) if not ? backend.hasTable(name): @@ -278,40 +293,46 @@ func close(store: var CurrentSyncCommitteeBranchStore) = store.putStmt.disposeSafe() store.keepFromStmt.disposeSafe() -func hasCurrentSyncCommitteeBranch*( +template kind(x: typedesc[altair.CurrentSyncCommitteeBranch]): BranchFork = + BranchFork.Altair + +template kind(x: typedesc[electra.CurrentSyncCommitteeBranch]): BranchFork = + BranchFork.Electra + +func hasCurrentSyncCommitteeBranch*[T: ForkyCurrentSyncCommitteeBranch]( db: LightClientDataDB, slot: Slot): bool = if not slot.isSupportedBySQLite or - distinctBase(db.currentBranches.containsStmt) == nil: + distinctBase(db.currentBranches[T.kind].containsStmt) == nil: return false var exists: int64 - for res in db.currentBranches.containsStmt.exec(slot.int64, exists): + for res in db.currentBranches[T.kind].containsStmt.exec(slot.int64, exists): res.expect("SQL query OK") doAssert exists == 1 return true false -proc getCurrentSyncCommitteeBranch*( - db: LightClientDataDB, slot: Slot): Opt[altair.CurrentSyncCommitteeBranch] = +proc getCurrentSyncCommitteeBranch*[T: ForkyCurrentSyncCommitteeBranch]( + db: LightClientDataDB, slot: Slot): Opt[T] = if not slot.isSupportedBySQLite or - distinctBase(db.currentBranches.getStmt) == nil: - return Opt.none(altair.CurrentSyncCommitteeBranch) + distinctBase(db.currentBranches[T.kind].getStmt) == nil: + return Opt.none(T) var branch: seq[byte] - for res in db.currentBranches.getStmt.exec(slot.int64, branch): + for res in db.currentBranches[T.kind].getStmt.exec(slot.int64, branch): res.expect("SQL query OK") try: - return ok SSZ.decode(branch, altair.CurrentSyncCommitteeBranch) + return ok SSZ.decode(branch, T) except SerializationError as exc: - error "LC data store corrupted", store = "currentBranches", + error "LC data store corrupted", store = "currentBranches", kind = T.kind, slot, exc = exc.msg - return Opt.none(altair.CurrentSyncCommitteeBranch) + return Opt.none(T) -func putCurrentSyncCommitteeBranch*( - db: LightClientDataDB, slot: Slot, - branch: altair.CurrentSyncCommitteeBranch) = +func putCurrentSyncCommitteeBranch*[T: ForkyCurrentSyncCommitteeBranch]( + db: LightClientDataDB, slot: Slot, branch: T) = doAssert not db.backend.readOnly # All `stmt` are non-nil if not slot.isSupportedBySQLite: return - let res = db.currentBranches.putStmt.exec((slot.int64, SSZ.encode(branch))) + let res = db.currentBranches[T.kind].putStmt.exec( + (slot.int64, SSZ.encode(branch))) res.expect("SQL query OK") proc initSyncCommitteesStore( @@ -643,9 +664,11 @@ func keepPeriodsFrom*( let res = db.syncCommittees.keepFromStmt.exec(minPeriod.int64) res.expect("SQL query OK") let minSlot = min(minPeriod.start_slot, int64.high.Slot) - block: - let res = db.currentBranches.keepFromStmt.exec(minSlot.int64) - res.expect("SQL query OK") + for branchFork, store in db.currentBranches: + if branchFork > BranchFork.None and + distinctBase(store.keepFromStmt) != nil: + let res = store.keepFromStmt.exec(minSlot.int64) + res.expect("SQL query OK") for lcDataFork, store in db.headers: if lcDataFork > LightClientDataFork.None and distinctBase(store.keepFromStmt) != nil: @@ -656,7 +679,9 @@ type LightClientDataDBNames* = object altairHeaders*: string capellaHeaders*: string denebHeaders*: string + electraHeaders*: string altairCurrentBranches*: string + electraCurrentBranches*: string altairSyncCommittees*: string legacyAltairBestUpdates*: string bestUpdates*: string @@ -665,7 +690,7 @@ type LightClientDataDBNames* = object proc initLightClientDataDB*( backend: SqStoreRef, names: LightClientDataDBNames): KvResult[LightClientDataDB] = - static: doAssert LightClientDataFork.high == LightClientDataFork.Deneb + static: doAssert LightClientDataFork.high == LightClientDataFork.Electra let headers = [ # LightClientDataFork.None @@ -678,10 +703,21 @@ proc initLightClientDataDB*( names.capellaHeaders, "capella.LightClientHeader"), # LightClientDataFork.Deneb ? backend.initHeadersStore( - names.denebHeaders, "deneb.LightClientHeader") + names.denebHeaders, "deneb.LightClientHeader"), + # LightClientDataFork.Electra + ? backend.initHeadersStore( + names.electraHeaders, "electra.LightClientHeader"), + ] + currentBranches = [ + # BranchFork.None + CurrentSyncCommitteeBranchStore(), + # BranchFork.Altair + ? backend.initCurrentBranchesStore( + names.altairCurrentBranches, "altair.CurrentSyncCommitteeBranch"), + # BranchFork.Electra + ? backend.initCurrentBranchesStore( + names.electraCurrentBranches, "electra.CurrentSyncCommitteeBranch"), ] - currentBranches = - ? backend.initCurrentBranchesStore(names.altairCurrentBranches) syncCommittees = ? backend.initSyncCommitteesStore(names.altairSyncCommittees) legacyBestUpdates = @@ -706,7 +742,9 @@ proc close*(db: LightClientDataDB) = for lcDataFork in LightClientDataFork: if lcDataFork > LightClientDataFork.None: db.headers[lcDataFork].close() - db.currentBranches.close() + for branchFork in BranchFork: + if branchFork > BranchFork.None: + db.currentBranches[branchFork].close() db.syncCommittees.close() db.legacyBestUpdates.close() db.bestUpdates.close() diff --git a/beacon_chain/consensus_object_pools/block_pools_types_light_client.nim b/beacon_chain/consensus_object_pools/block_pools_types_light_client.nim index a7b9d8da9..b8ea3e638 100644 --- a/beacon_chain/consensus_object_pools/block_pools_types_light_client.nim +++ b/beacon_chain/consensus_object_pools/block_pools_types_light_client.nim @@ -33,11 +33,13 @@ type CachedLightClientData* = object ## Cached data from historical non-finalized states to improve speed when ## creating future `LightClientUpdate` and `LightClientBootstrap` instances. - current_sync_committee_branch*: altair.CurrentSyncCommitteeBranch - next_sync_committee_branch*: altair.NextSyncCommitteeBranch + current_sync_committee_branch*: + LightClientDataFork.high.CurrentSyncCommitteeBranch + next_sync_committee_branch*: + LightClientDataFork.high.NextSyncCommitteeBranch finalized_slot*: Slot - finality_branch*: altair.FinalityBranch + finality_branch*: LightClientDataFork.high.FinalityBranch current_period_best_update*: ref ForkedLightClientUpdate latest_signature_slot*: Slot diff --git a/beacon_chain/consensus_object_pools/blockchain_dag_light_client.nim b/beacon_chain/consensus_object_pools/blockchain_dag_light_client.nim index 6a5aff997..55eebd44b 100644 --- a/beacon_chain/consensus_object_pools/blockchain_dag_light_client.nim +++ b/beacon_chain/consensus_object_pools/blockchain_dag_light_client.nim @@ -22,6 +22,15 @@ template nextEpochBoundarySlot(slot: Slot): Slot = ## referring to a block at given slot. (slot + (SLOTS_PER_EPOCH - 1)).epoch.start_slot +func hasCurrentSyncCommitteeBranch(dag: ChainDAGRef, slot: Slot): bool = + let epoch = dag.cfg.consensusForkAtEpoch(slot.epoch) + withLcDataFork(lcDataForkAtConsensusFork(epoch)): + when lcDataFork > LightClientDataFork.None: + hasCurrentSyncCommitteeBranch[lcDataFork.CurrentSyncCommitteeBranch]( + dag.lcDataStore.db, slot) + else: + true + proc updateExistingState( dag: ChainDAGRef, state: var ForkedHashedBeaconState, bsi: BlockSlotId, save: bool, cache: var StateCache): bool = @@ -226,7 +235,7 @@ proc initLightClientBootstrapForPeriod( bid = bsi.bid boundarySlot = bid.slot.nextEpochBoundarySlot if boundarySlot == nextBoundarySlot and bid.slot >= lowSlot and - not dag.lcDataStore.db.hasCurrentSyncCommitteeBranch(bid.slot): + not dag.hasCurrentSyncCommitteeBranch(bid.slot): let bdata = dag.getExistingForkedBlock(bid).valueOr: dag.handleUnexpectedLightClientError(bid.slot) res.err() @@ -246,7 +255,7 @@ proc initLightClientBootstrapForPeriod( forkyBlck.toLightClientHeader(lcDataFork)) dag.lcDataStore.db.putCurrentSyncCommitteeBranch( bid.slot, forkyState.data.build_proof( - altair.CURRENT_SYNC_COMMITTEE_GINDEX).get) + lcDataFork.CURRENT_SYNC_COMMITTEE_GINDEX).get) else: raiseAssert "Unreachable" res @@ -393,13 +402,13 @@ proc initLightClientUpdateForPeriod( update = ForkedLightClientUpdate.init(lcDataFork.LightClientUpdate( attested_header: forkyBlck.toLightClientHeader(lcDataFork), next_sync_committee: forkyState.data.next_sync_committee, - next_sync_committee_branch: - forkyState.data.build_proof(altair.NEXT_SYNC_COMMITTEE_GINDEX).get, + next_sync_committee_branch: forkyState.data.build_proof( + lcDataFork.NEXT_SYNC_COMMITTEE_GINDEX).get, finality_branch: if finalizedBid.slot != FAR_FUTURE_SLOT: - forkyState.data.build_proof(altair.FINALIZED_ROOT_GINDEX).get + forkyState.data.build_proof(lcDataFork.FINALIZED_ROOT_GINDEX).get else: - default(FinalityBranch))) + default(lcDataFork.FinalityBranch))) else: raiseAssert "Unreachable" do: dag.handleUnexpectedLightClientError(attestedBid.slot) @@ -464,17 +473,21 @@ proc cacheLightClientData( ## Cache data for a given block and its post-state to speed up creating future ## `LightClientUpdate` and `LightClientBootstrap` instances that refer to this ## block and state. + const lcDataFork = lcDataForkAtConsensusFork(typeof(state).kind) let bid = blck.toBlockId() cachedData = CachedLightClientData( - current_sync_committee_branch: - state.data.build_proof(altair.CURRENT_SYNC_COMMITTEE_GINDEX).get, - next_sync_committee_branch: - state.data.build_proof(altair.NEXT_SYNC_COMMITTEE_GINDEX).get, + current_sync_committee_branch: normalize_merkle_branch( + state.data.build_proof(lcDataFork.CURRENT_SYNC_COMMITTEE_GINDEX).get, + LightClientDataFork.high.CURRENT_SYNC_COMMITTEE_GINDEX), + next_sync_committee_branch: normalize_merkle_branch( + state.data.build_proof(lcDataFork.NEXT_SYNC_COMMITTEE_GINDEX).get, + LightClientDataFork.high.NEXT_SYNC_COMMITTEE_GINDEX), finalized_slot: state.data.finalized_checkpoint.epoch.start_slot, - finality_branch: - state.data.build_proof(altair.FINALIZED_ROOT_GINDEX).get, + finality_branch: normalize_merkle_branch( + state.data.build_proof(lcDataFork.FINALIZED_ROOT_GINDEX).get, + LightClientDataFork.high.FINALIZED_ROOT_GINDEX), current_period_best_update: current_period_best_update, latest_signature_slot: @@ -538,15 +551,18 @@ proc assignLightClientData( when lcDataFork > LightClientDataFork.None: forkyObject.next_sync_committee = next_sync_committee.get - forkyObject.next_sync_committee_branch = - attested_data.next_sync_committee_branch + forkyObject.next_sync_committee_branch = normalize_merkle_branch( + attested_data.next_sync_committee_branch, + lcDataFork.NEXT_SYNC_COMMITTEE_GINDEX) else: doAssert next_sync_committee.isNone var finalized_slot = attested_data.finalized_slot withForkyObject(obj): when lcDataFork > LightClientDataFork.None: if finalized_slot == forkyObject.finalized_header.beacon.slot: - forkyObject.finality_branch = attested_data.finality_branch + forkyObject.finality_branch = normalize_merkle_branch( + attested_data.finality_branch, + lcDataFork.FINALIZED_ROOT_GINDEX) elif finalized_slot < max(dag.tail.slot, dag.backfill.slot): forkyObject.finalized_header.reset() forkyObject.finality_branch.reset() @@ -564,10 +580,14 @@ proc assignLightClientData( attested_data.finalized_slot = finalized_slot dag.lcDataStore.cache.data[attested_bid] = attested_data if finalized_slot == forkyObject.finalized_header.beacon.slot: - forkyObject.finality_branch = attested_data.finality_branch + forkyObject.finality_branch = normalize_merkle_branch( + attested_data.finality_branch, + lcDataFork.FINALIZED_ROOT_GINDEX) elif finalized_slot == GENESIS_SLOT: forkyObject.finalized_header.reset() - forkyObject.finality_branch = attested_data.finality_branch + forkyObject.finality_branch = normalize_merkle_branch( + attested_data.finality_branch, + lcDataFork.FINALIZED_ROOT_GINDEX) else: var fin_header = dag.getExistingLightClientHeader(finalized_bid) if fin_header.kind == LightClientDataFork.None: @@ -577,7 +597,9 @@ proc assignLightClientData( else: fin_header.migrateToDataFork(lcDataFork) forkyObject.finalized_header = fin_header.forky(lcDataFork) - forkyObject.finality_branch = attested_data.finality_branch + forkyObject.finality_branch = normalize_merkle_branch( + attested_data.finality_branch, + lcDataFork.FINALIZED_ROOT_GINDEX) withForkyObject(obj): when lcDataFork > LightClientDataFork.None: forkyObject.sync_aggregate = sync_aggregate @@ -701,9 +723,11 @@ proc createLightClientBootstrap( const lcDataFork = lcDataForkAtConsensusFork(consensusFork) dag.lcDataStore.db.putHeader( forkyBlck.toLightClientHeader(lcDataFork)) + dag.lcDataStore.db.putCurrentSyncCommitteeBranch( + bid.slot, normalize_merkle_branch( + dag.getLightClientData(bid).current_sync_committee_branch, + lcDataFork.CURRENT_SYNC_COMMITTEE_GINDEX)) else: raiseAssert "Unreachable" - dag.lcDataStore.db.putCurrentSyncCommitteeBranch( - bid.slot, dag.getLightClientData(bid).current_sync_committee_branch) ok() proc initLightClientDataCache*(dag: ChainDAGRef) = @@ -1014,7 +1038,7 @@ proc getLightClientBootstrap( # Ensure `current_sync_committee_branch` is known if dag.lcDataStore.importMode == LightClientDataImportMode.OnDemand and - not dag.lcDataStore.db.hasCurrentSyncCommitteeBranch(slot): + not dag.hasCurrentSyncCommitteeBranch(slot): let bsi = dag.getExistingBlockIdAtSlot(slot).valueOr: return default(ForkedLightClientBootstrap) @@ -1022,13 +1046,14 @@ proc getLightClientBootstrap( dag.withUpdatedExistingState(tmpState[], bsi) do: withState(updatedState): when consensusFork >= ConsensusFork.Altair: + const lcDataFork = lcDataForkAtConsensusFork(consensusFork) if not dag.lcDataStore.db.hasSyncCommittee(period): dag.lcDataStore.db.putSyncCommittee( period, forkyState.data.current_sync_committee) dag.lcDataStore.db.putHeader(header) dag.lcDataStore.db.putCurrentSyncCommitteeBranch( slot, forkyState.data.build_proof( - altair.CURRENT_SYNC_COMMITTEE_GINDEX).get) + lcDataFork.CURRENT_SYNC_COMMITTEE_GINDEX).get) else: raiseAssert "Unreachable" do: return default(ForkedLightClientBootstrap) @@ -1050,7 +1075,8 @@ proc getLightClientBootstrap( debug "LC bootstrap unavailable: Sync committee not cached", period return default(ForkedLightClientBootstrap)), current_sync_committee_branch: (block: - dag.lcDataStore.db.getCurrentSyncCommitteeBranch(slot).valueOr: + getCurrentSyncCommitteeBranch[lcDataFork.CurrentSyncCommitteeBranch]( + dag.lcDataStore.db, slot).valueOr: debug "LC bootstrap unavailable: Committee branch not cached", slot return default(ForkedLightClientBootstrap)))) diff --git a/beacon_chain/gossip_processing/light_client_processor.nim b/beacon_chain/gossip_processing/light_client_processor.nim index ed37acb73..f70e43703 100644 --- a/beacon_chain/gossip_processing/light_client_processor.nim +++ b/beacon_chain/gossip_processing/light_client_processor.nim @@ -209,47 +209,62 @@ proc tryForceUpdate( finalizedSlot = forkyStore.finalized_header.beacon.slot, optimisticSlot = forkyStore.optimistic_header.beacon.slot +proc doProcessObject( + self: var LightClientProcessor, + bootstrap: ForkedLightClientBootstrap, + wallTime: BeaconTime): Result[void, VerifierError] = + if bootstrap.kind == LightClientDataFork.None: + err(VerifierError.Invalid) + elif self.store[].kind > LightClientDataFork.None: + err(VerifierError.Duplicate) + else: + let trustedBlockRoot = self.getTrustedBlockRoot() + if trustedBlockRoot.isNone: + err(VerifierError.MissingParent) + else: + withForkyBootstrap(bootstrap): + when lcDataFork > LightClientDataFork.None: + let initRes = initialize_light_client_store( + trustedBlockRoot.get, forkyBootstrap, self.cfg) + if initRes.isErr: + err(initRes.error) + else: + self.store[] = ForkedLightClientStore.init(initRes.get) + ok() + else: + raiseAssert "Unreachable; bootstrap.kind was checked" + +proc doProcessObject( + self: var LightClientProcessor, + update: SomeForkedLightClientUpdate, + wallTime: BeaconTime): Result[void, VerifierError] = + if update.kind == LightClientDataFork.None: + err(VerifierError.Invalid) + elif self.store[].kind == LightClientDataFork.None: + err(VerifierError.MissingParent) + else: + withForkyObject(update): + when lcDataFork > LightClientDataFork.None: + if lcDataFork > self.store[].kind: + info "Upgrading light client", + oldFork = self.store[].kind, newFork = lcDataFork + self.store[].migrateToDataFork(lcDataFork) + withForkyStore(self.store[]): + when lcDataFork > LightClientDataFork.None: + let + wallSlot = wallTime.slotOrZero() + upgradedUpdate = update.migratingToDataFork(lcDataFork) + process_light_client_update( + forkyStore, upgradedUpdate.forky(lcDataFork), wallSlot, + self.cfg, self.genesis_validators_root) + else: + raiseAssert "Unreachable; self.store[].kind was checked" + proc processObject( self: var LightClientProcessor, obj: SomeForkedLightClientObject, wallTime: BeaconTime): Result[void, VerifierError] = - let - res = withForkyObject(obj): - when lcDataFork > LightClientDataFork.None: - when forkyObject is ForkyLightClientBootstrap: - if self.store[].kind > LightClientDataFork.None: - err(VerifierError.Duplicate) - else: - let trustedBlockRoot = self.getTrustedBlockRoot() - if trustedBlockRoot.isNone: - err(VerifierError.MissingParent) - else: - let initRes = initialize_light_client_store( - trustedBlockRoot.get, forkyObject, self.cfg) - if initRes.isErr: - err(initRes.error) - else: - self.store[] = ForkedLightClientStore.init(initRes.get) - ok() - elif forkyObject is SomeForkyLightClientUpdate: - if self.store[].kind == LightClientDataFork.None: - err(VerifierError.MissingParent) - else: - if lcDataFork > self.store[].kind: - info "Upgrading light client", - oldFork = self.store[].kind, newFork = lcDataFork - self.store[].migrateToDataFork(lcDataFork) - withForkyStore(self.store[]): - when lcDataFork > LightClientDataFork.None: - let - wallSlot = wallTime.slotOrZero() - upgradedObject = obj.migratingToDataFork(lcDataFork) - process_light_client_update( - forkyStore, upgradedObject.forky(lcDataFork), wallSlot, - self.cfg, self.genesis_validators_root) - else: raiseAssert "Unreachable" - else: - err(VerifierError.Invalid) + let res = self.doProcessObject(obj, wallTime) withForkyObject(obj): when lcDataFork > LightClientDataFork.None: diff --git a/beacon_chain/spec/datatypes/deneb.nim b/beacon_chain/spec/datatypes/deneb.nim index 1f136ed9a..722094948 100644 --- a/beacon_chain/spec/datatypes/deneb.nim +++ b/beacon_chain/spec/datatypes/deneb.nim @@ -626,14 +626,16 @@ func kzg_commitment_inclusion_proof_gindex*( BLOB_KZG_COMMITMENTS_FIRST_GINDEX + index -# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/deneb/light-client/sync-protocol.md#modified-get_lc_execution_root +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/deneb/light-client/sync-protocol.md#modified-get_lc_execution_root func get_lc_execution_root*( header: LightClientHeader, cfg: RuntimeConfig): Eth2Digest = let epoch = header.beacon.slot.epoch + # [New in Deneb] if epoch >= cfg.DENEB_FORK_EPOCH: return hash_tree_root(header.execution) + # [Modified in Deneb] if epoch >= cfg.CAPELLA_FORK_EPOCH: let execution_header = capella.ExecutionPayloadHeader( parent_hash: header.execution.parent_hash, @@ -655,11 +657,12 @@ func get_lc_execution_root*( ZERO_HASH -# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/deneb/light-client/sync-protocol.md#modified-is_valid_light_client_header +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/deneb/light-client/sync-protocol.md#modified-is_valid_light_client_header func is_valid_light_client_header*( header: LightClientHeader, cfg: RuntimeConfig): bool = let epoch = header.beacon.slot.epoch + # [New in Deneb:EIP4844] if epoch < cfg.DENEB_FORK_EPOCH: if header.execution.blob_gas_used != 0 or header.execution.excess_blob_gas != 0: diff --git a/beacon_chain/spec/datatypes/electra.nim b/beacon_chain/spec/datatypes/electra.nim index 954950069..5f5091d40 100644 --- a/beacon_chain/spec/datatypes/electra.nim +++ b/beacon_chain/spec/datatypes/electra.nim @@ -29,24 +29,25 @@ from stew/bitops2 import log2trunc from stew/byteutils import to0xHex from ./altair import EpochParticipationFlags, InactivityScores, SyncAggregate, SyncCommittee, - TrustedSyncAggregate + TrustedSyncAggregate, num_active_participants from ./bellatrix import BloomLogs, ExecutionAddress, Transaction from ./capella import - HistoricalSummary, SignedBLSToExecutionChangeList, Withdrawal + ExecutionBranch, HistoricalSummary, SignedBLSToExecutionChangeList, + Withdrawal, EXECUTION_PAYLOAD_GINDEX from ./deneb import Blobs, BlobsBundle, KzgCommitments, KzgProofs export json_serialization, base, kzg4844 const - # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/sync-protocol.md#constants + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/sync-protocol.md#constants # All of these indices are rooted in `BeaconState`. # The first member (`genesis_time`) is 64, subsequent members +1 each. # If there are ever more than 64 members in `BeaconState`, indices change! # `FINALIZED_ROOT_GINDEX` is one layer deeper, i.e., `84 * 2 + 1`. # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/ssz/merkle-proofs.md - FINALIZED_ROOT_GINDEX = 169.GeneralizedIndex # finalized_checkpoint > root - CURRENT_SYNC_COMMITTEE_GINDEX = 86.GeneralizedIndex # current_sync_committee - NEXT_SYNC_COMMITTEE_GINDEX = 87.GeneralizedIndex # next_sync_committee + FINALIZED_ROOT_GINDEX* = 169.GeneralizedIndex # finalized_checkpoint > root + CURRENT_SYNC_COMMITTEE_GINDEX* = 86.GeneralizedIndex # current_sync_committee + NEXT_SYNC_COMMITTEE_GINDEX* = 87.GeneralizedIndex # next_sync_committee type # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#depositrequest @@ -182,15 +183,6 @@ type source_pubkey*: ValidatorPubKey target_pubkey*: ValidatorPubKey - FinalityBranch = - array[log2trunc(FINALIZED_ROOT_GINDEX), Eth2Digest] - - CurrentSyncCommitteeBranch = - array[log2trunc(CURRENT_SYNC_COMMITTEE_GINDEX), Eth2Digest] - - NextSyncCommitteeBranch = - array[log2trunc(NEXT_SYNC_COMMITTEE_GINDEX), Eth2Digest] - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/validator.md#aggregateandproof AggregateAndProof* = object aggregator_index*: uint64 # `ValidatorIndex` after validation @@ -202,6 +194,15 @@ type message*: AggregateAndProof signature*: ValidatorSig + FinalityBranch* = + array[log2trunc(FINALIZED_ROOT_GINDEX), Eth2Digest] + + CurrentSyncCommitteeBranch* = + array[log2trunc(CURRENT_SYNC_COMMITTEE_GINDEX), Eth2Digest] + + NextSyncCommitteeBranch* = + array[log2trunc(NEXT_SYNC_COMMITTEE_GINDEX), Eth2Digest] + # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/light-client/sync-protocol.md#modified-lightclientheader LightClientHeader* = object beacon*: BeaconBlockHeader @@ -675,6 +676,233 @@ func shortLog*(v: ExecutionPayload): auto = excess_blob_gas: $(v.excess_blob_gas) ) +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/sync-protocol.md#modified-get_lc_execution_root +func get_lc_execution_root*( + header: LightClientHeader, cfg: RuntimeConfig): Eth2Digest = + let epoch = header.beacon.slot.epoch + + # [New in Electra] + if epoch >= cfg.ELECTRA_FORK_EPOCH: + return hash_tree_root(header.execution) + + # [Modified in Electra] + if epoch >= cfg.DENEB_FORK_EPOCH: + let execution_header = deneb.ExecutionPayloadHeader( + parent_hash: header.execution.parent_hash, + fee_recipient: header.execution.fee_recipient, + state_root: header.execution.state_root, + receipts_root: header.execution.receipts_root, + logs_bloom: header.execution.logs_bloom, + prev_randao: header.execution.prev_randao, + block_number: header.execution.block_number, + gas_limit: header.execution.gas_limit, + gas_used: header.execution.gas_used, + timestamp: header.execution.timestamp, + extra_data: header.execution.extra_data, + base_fee_per_gas: header.execution.base_fee_per_gas, + block_hash: header.execution.block_hash, + transactions_root: header.execution.transactions_root, + withdrawals_root: header.execution.withdrawals_root, + blob_gas_used: header.execution.blob_gas_used, + excess_blob_gas: header.execution.excess_blob_gas) + return hash_tree_root(execution_header) + + if epoch >= cfg.CAPELLA_FORK_EPOCH: + let execution_header = capella.ExecutionPayloadHeader( + parent_hash: header.execution.parent_hash, + fee_recipient: header.execution.fee_recipient, + state_root: header.execution.state_root, + receipts_root: header.execution.receipts_root, + logs_bloom: header.execution.logs_bloom, + prev_randao: header.execution.prev_randao, + block_number: header.execution.block_number, + gas_limit: header.execution.gas_limit, + gas_used: header.execution.gas_used, + timestamp: header.execution.timestamp, + extra_data: header.execution.extra_data, + base_fee_per_gas: header.execution.base_fee_per_gas, + block_hash: header.execution.block_hash, + transactions_root: header.execution.transactions_root, + withdrawals_root: header.execution.withdrawals_root) + return hash_tree_root(execution_header) + + ZERO_HASH + +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/sync-protocol.md#modified-is_valid_light_client_header +func is_valid_light_client_header*( + header: LightClientHeader, cfg: RuntimeConfig): bool = + let epoch = header.beacon.slot.epoch + + # [New in Electra:EIP6110:EIP7002:EIP7251] + if epoch < cfg.ELECTRA_FORK_EPOCH: + if not header.execution.deposit_requests_root.isZero or + not header.execution.withdrawal_requests_root.isZero or + not header.execution.consolidation_requests_root.isZero: + return false + + if epoch < cfg.DENEB_FORK_EPOCH: + if header.execution.blob_gas_used != 0 or + header.execution.excess_blob_gas != 0: + return false + + if epoch < cfg.CAPELLA_FORK_EPOCH: + return + header.execution == static(default(ExecutionPayloadHeader)) and + header.execution_branch == static(default(ExecutionBranch)) + + is_valid_merkle_branch( + get_lc_execution_root(header, cfg), + header.execution_branch, + log2trunc(EXECUTION_PAYLOAD_GINDEX), + get_subtree_index(EXECUTION_PAYLOAD_GINDEX), + header.beacon.body_root) + +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/fork.md#normalize_merkle_branch +func normalize_merkle_branch*[N]( + branch: array[N, Eth2Digest], + gindex: static GeneralizedIndex): auto = + const depth = log2trunc(gindex) + var res: array[depth, Eth2Digest] + when depth >= branch.len: + const num_extra = depth - branch.len + res[num_extra ..< depth] = branch + else: + const num_extra = branch.len - depth + for node in branch[0 ..< num_extra]: + doAssert node.isZero, "Truncation of Merkle branch cannot lose info" + res[0 ..< depth] = branch[num_extra ..< branch.len] + res + +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/fork.md#upgrading-light-client-data +func upgrade_lc_header_to_electra*( + pre: deneb.LightClientHeader): LightClientHeader = + LightClientHeader( + beacon: pre.beacon, + execution: ExecutionPayloadHeader( + parent_hash: pre.execution.parent_hash, + fee_recipient: pre.execution.fee_recipient, + state_root: pre.execution.state_root, + receipts_root: pre.execution.receipts_root, + logs_bloom: pre.execution.logs_bloom, + prev_randao: pre.execution.prev_randao, + block_number: pre.execution.block_number, + gas_limit: pre.execution.gas_limit, + gas_used: pre.execution.gas_used, + timestamp: pre.execution.timestamp, + extra_data: pre.execution.extra_data, + base_fee_per_gas: pre.execution.base_fee_per_gas, + block_hash: pre.execution.block_hash, + transactions_root: pre.execution.transactions_root, + withdrawals_root: pre.execution.withdrawals_root, + blob_gas_used: pre.execution.blob_gas_used, + excess_blob_gas: pre.execution.blob_gas_used, + deposit_requests_root: ZERO_HASH, # [New in Electra:EIP6110] + withdrawal_requests_root: ZERO_HASH, # [New in Electra:EIP7002:EIP7251] + consolidation_requests_root: ZERO_HASH), # [New in Electra:EIP7251] + execution_branch: pre.execution_branch) + +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/fork.md#upgrading-light-client-data +func upgrade_lc_bootstrap_to_electra*( + pre: deneb.LightClientBootstrap): LightClientBootstrap = + LightClientBootstrap( + header: upgrade_lc_header_to_electra(pre.header), + current_sync_committee: pre.current_sync_committee, + current_sync_committee_branch: normalize_merkle_branch( + pre.current_sync_committee_branch, CURRENT_SYNC_COMMITTEE_GINDEX)) + +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/fork.md#upgrading-light-client-data +func upgrade_lc_update_to_electra*( + pre: deneb.LightClientUpdate): LightClientUpdate = + LightClientUpdate( + attested_header: upgrade_lc_header_to_electra(pre.attested_header), + next_sync_committee: pre.next_sync_committee, + next_sync_committee_branch: normalize_merkle_branch( + pre.next_sync_committee_branch, NEXT_SYNC_COMMITTEE_GINDEX), + finalized_header: upgrade_lc_header_to_electra(pre.finalized_header), + finality_branch: normalize_merkle_branch( + pre.finality_branch, FINALIZED_ROOT_GINDEX), + sync_aggregate: pre.sync_aggregate, + signature_slot: pre.signature_slot) + +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/fork.md#upgrading-light-client-data +func upgrade_lc_finality_update_to_electra*( + pre: deneb.LightClientFinalityUpdate): LightClientFinalityUpdate = + LightClientFinalityUpdate( + attested_header: upgrade_lc_header_to_electra(pre.attested_header), + finalized_header: upgrade_lc_header_to_electra(pre.finalized_header), + finality_branch: normalize_merkle_branch( + pre.finality_branch, FINALIZED_ROOT_GINDEX), + sync_aggregate: pre.sync_aggregate, + signature_slot: pre.signature_slot) + +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/fork.md#upgrading-light-client-data +func upgrade_lc_optimistic_update_to_electra*( + pre: deneb.LightClientOptimisticUpdate): LightClientOptimisticUpdate = + LightClientOptimisticUpdate( + attested_header: upgrade_lc_header_to_electra(pre.attested_header), + sync_aggregate: pre.sync_aggregate, + signature_slot: pre.signature_slot) + +func shortLog*(v: LightClientHeader): auto = + ( + beacon: shortLog(v.beacon), + execution: ( + block_hash: v.execution.block_hash, + block_number: v.execution.block_number) + ) + +func shortLog*(v: LightClientBootstrap): auto = + ( + header: shortLog(v.header) + ) + +func shortLog*(v: LightClientUpdate): auto = + ( + attested: shortLog(v.attested_header), + has_next_sync_committee: + v.next_sync_committee != static(default(typeof(v.next_sync_committee))), + finalized: shortLog(v.finalized_header), + num_active_participants: v.sync_aggregate.num_active_participants, + signature_slot: v.signature_slot + ) + +func shortLog*(v: LightClientFinalityUpdate): auto = + ( + attested: shortLog(v.attested_header), + finalized: shortLog(v.finalized_header), + num_active_participants: v.sync_aggregate.num_active_participants, + signature_slot: v.signature_slot + ) + +func shortLog*(v: LightClientOptimisticUpdate): auto = + ( + attested: shortLog(v.attested_header), + num_active_participants: v.sync_aggregate.num_active_participants, + signature_slot: v.signature_slot, + ) + +chronicles.formatIt LightClientBootstrap: shortLog(it) +chronicles.formatIt LightClientUpdate: shortLog(it) +chronicles.formatIt LightClientFinalityUpdate: shortLog(it) +chronicles.formatIt LightClientOptimisticUpdate: shortLog(it) + +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/fork.md#upgrading-the-store +func upgrade_lc_store_to_electra*( + pre: deneb.LightClientStore): LightClientStore = + let best_valid_update = + if pre.best_valid_update.isNone: + Opt.none(LightClientUpdate) + else: + Opt.some upgrade_lc_update_to_electra(pre.best_valid_update.get) + LightClientStore( + finalized_header: upgrade_lc_header_to_electra(pre.finalized_header), + current_sync_committee: pre.current_sync_committee, + next_sync_committee: pre.next_sync_committee, + best_valid_update: best_valid_update, + optimistic_header: upgrade_lc_header_to_electra(pre.optimistic_header), + previous_max_active_participants: pre.previous_max_active_participants, + current_max_active_participants: pre.current_max_active_participants) + template asSigned*( x: SigVerifiedSignedBeaconBlock | MsgTrustedSignedBeaconBlock | diff --git a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim index 13762ec7d..d2a223f32 100644 --- a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim +++ b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim @@ -252,6 +252,11 @@ RestJson.useDefaultSerializationFor( electra.ExecutionPayload, electra.ExecutionPayloadHeader, electra.IndexedAttestation, + electra.LightClientBootstrap, + electra.LightClientFinalityUpdate, + electra.LightClientHeader, + electra.LightClientOptimisticUpdate, + electra.LightClientUpdate, electra.SignedBeaconBlock, electra.TrustedAttestation, electra_mev.BlindedBeaconBlock, diff --git a/beacon_chain/spec/forks.nim b/beacon_chain/spec/forks.nim index 3c86b4926..5dc50ee20 100644 --- a/beacon_chain/spec/forks.nim +++ b/beacon_chain/spec/forks.nim @@ -1325,8 +1325,10 @@ func forkVersion*(cfg: RuntimeConfig, consensusFork: ConsensusFork): Version = func lcDataForkAtConsensusFork*( consensusFork: ConsensusFork): LightClientDataFork = - static: doAssert LightClientDataFork.high == LightClientDataFork.Deneb - if consensusFork >= ConsensusFork.Deneb: + static: doAssert LightClientDataFork.high == LightClientDataFork.Electra + if consensusFork >= ConsensusFork.Electra: + LightClientDataFork.Electra + elif consensusFork >= ConsensusFork.Deneb: LightClientDataFork.Deneb elif consensusFork >= ConsensusFork.Capella: LightClientDataFork.Capella diff --git a/beacon_chain/spec/forks_light_client.nim b/beacon_chain/spec/forks_light_client.nim index 1c3de1d0e..dd596a993 100644 --- a/beacon_chain/spec/forks_light_client.nim +++ b/beacon_chain/spec/forks_light_client.nim @@ -16,32 +16,42 @@ type None = 0, # only use non-0 in DB to detect accidentally uninitialized data Altair = 1, Capella = 2, - Deneb = 3 + Deneb = 3, + Electra = 4 + + ForkyCurrentSyncCommitteeBranch* = + altair.CurrentSyncCommitteeBranch | + electra.CurrentSyncCommitteeBranch ForkyLightClientHeader* = altair.LightClientHeader | capella.LightClientHeader | - deneb.LightClientHeader + deneb.LightClientHeader | + electra.LightClientHeader ForkyLightClientBootstrap* = altair.LightClientBootstrap | capella.LightClientBootstrap | - deneb.LightClientBootstrap + deneb.LightClientBootstrap | + electra.LightClientBootstrap ForkyLightClientUpdate* = altair.LightClientUpdate | capella.LightClientUpdate | - deneb.LightClientUpdate + deneb.LightClientUpdate | + electra.LightClientUpdate ForkyLightClientFinalityUpdate* = altair.LightClientFinalityUpdate | capella.LightClientFinalityUpdate | - deneb.LightClientFinalityUpdate + deneb.LightClientFinalityUpdate | + electra.LightClientFinalityUpdate ForkyLightClientOptimisticUpdate* = altair.LightClientOptimisticUpdate | capella.LightClientOptimisticUpdate | - deneb.LightClientOptimisticUpdate + deneb.LightClientOptimisticUpdate | + electra.LightClientOptimisticUpdate SomeForkyLightClientUpdateWithSyncCommittee* = ForkyLightClientUpdate @@ -62,7 +72,8 @@ type ForkyLightClientStore* = altair.LightClientStore | capella.LightClientStore | - deneb.LightClientStore + deneb.LightClientStore | + electra.LightClientStore ForkedLightClientHeader* = object case kind*: LightClientDataFork @@ -74,6 +85,8 @@ type capellaData*: capella.LightClientHeader of LightClientDataFork.Deneb: denebData*: deneb.LightClientHeader + of LightClientDataFork.Electra: + electraData*: electra.LightClientHeader ForkedLightClientBootstrap* = object case kind*: LightClientDataFork @@ -85,6 +98,8 @@ type capellaData*: capella.LightClientBootstrap of LightClientDataFork.Deneb: denebData*: deneb.LightClientBootstrap + of LightClientDataFork.Electra: + electraData*: electra.LightClientBootstrap ForkedLightClientUpdate* = object case kind*: LightClientDataFork @@ -96,6 +111,8 @@ type capellaData*: capella.LightClientUpdate of LightClientDataFork.Deneb: denebData*: deneb.LightClientUpdate + of LightClientDataFork.Electra: + electraData*: electra.LightClientUpdate ForkedLightClientFinalityUpdate* = object case kind*: LightClientDataFork @@ -107,6 +124,8 @@ type capellaData*: capella.LightClientFinalityUpdate of LightClientDataFork.Deneb: denebData*: deneb.LightClientFinalityUpdate + of LightClientDataFork.Electra: + electraData*: electra.LightClientFinalityUpdate ForkedLightClientOptimisticUpdate* = object case kind*: LightClientDataFork @@ -118,6 +137,8 @@ type capellaData*: capella.LightClientOptimisticUpdate of LightClientDataFork.Deneb: denebData*: deneb.LightClientOptimisticUpdate + of LightClientDataFork.Electra: + electraData*: electra.LightClientOptimisticUpdate SomeForkedLightClientUpdateWithSyncCommittee* = ForkedLightClientUpdate @@ -145,11 +166,15 @@ type capellaData*: capella.LightClientStore of LightClientDataFork.Deneb: denebData*: deneb.LightClientStore + of LightClientDataFork.Electra: + electraData*: electra.LightClientStore func lcDataForkAtEpoch*( cfg: RuntimeConfig, epoch: Epoch): LightClientDataFork = - static: doAssert LightClientDataFork.high == LightClientDataFork.Deneb - if epoch >= cfg.DENEB_FORK_EPOCH: + static: doAssert LightClientDataFork.high == LightClientDataFork.Electra + if epoch >= cfg.ELECTRA_FORK_EPOCH: + LightClientDataFork.Electra + elif epoch >= cfg.DENEB_FORK_EPOCH: LightClientDataFork.Deneb elif epoch >= cfg.CAPELLA_FORK_EPOCH: LightClientDataFork.Capella @@ -191,8 +216,72 @@ template kind*( deneb.LightClientStore]): LightClientDataFork = LightClientDataFork.Deneb +template kind*( + # `SomeLightClientObject`: https://github.com/nim-lang/Nim/issues/18095 + x: typedesc[ + electra.LightClientHeader | + electra.LightClientBootstrap | + electra.LightClientUpdate | + electra.LightClientFinalityUpdate | + electra.LightClientOptimisticUpdate | + electra.LightClientStore]): LightClientDataFork = + LightClientDataFork.Electra + +template FINALIZED_ROOT_GINDEX*( + kind: static LightClientDataFork): GeneralizedIndex = + when kind >= LightClientDataFork.Electra: + electra.FINALIZED_ROOT_GINDEX + elif kind >= LightClientDataFork.Altair: + altair.FINALIZED_ROOT_GINDEX + else: + static: raiseAssert "Unreachable" + +template FinalityBranch*(kind: static LightClientDataFork): auto = + when kind >= LightClientDataFork.Electra: + typedesc[electra.FinalityBranch] + elif kind >= LightClientDataFork.Altair: + typedesc[altair.FinalityBranch] + else: + static: raiseAssert "Unreachable" + +template CURRENT_SYNC_COMMITTEE_GINDEX*( + kind: static LightClientDataFork): GeneralizedIndex = + when kind >= LightClientDataFork.Electra: + electra.CURRENT_SYNC_COMMITTEE_GINDEX + elif kind >= LightClientDataFork.Altair: + altair.CURRENT_SYNC_COMMITTEE_GINDEX + else: + static: raiseAssert "Unreachable" + +template CurrentSyncCommitteeBranch*(kind: static LightClientDataFork): auto = + when kind >= LightClientDataFork.Electra: + typedesc[electra.CurrentSyncCommitteeBranch] + elif kind >= LightClientDataFork.Altair: + typedesc[altair.CurrentSyncCommitteeBranch] + else: + static: raiseAssert "Unreachable" + +template NEXT_SYNC_COMMITTEE_GINDEX*( + kind: static LightClientDataFork): GeneralizedIndex = + when kind >= LightClientDataFork.Electra: + electra.NEXT_SYNC_COMMITTEE_GINDEX + elif kind >= LightClientDataFork.Altair: + altair.NEXT_SYNC_COMMITTEE_GINDEX + else: + static: raiseAssert "Unreachable" + +template NextSyncCommitteeBranch*(kind: static LightClientDataFork): auto = + when kind >= LightClientDataFork.Electra: + typedesc[electra.NextSyncCommitteeBranch] + elif kind >= LightClientDataFork.Altair: + typedesc[altair.NextSyncCommitteeBranch] + else: + static: raiseAssert "Unreachable" + template LightClientHeader*(kind: static LightClientDataFork): auto = - when kind == LightClientDataFork.Deneb: + when kind == LightClientDataFork.Electra: + typedesc[electra.LightClientHeader] + elif kind == LightClientDataFork.Deneb: typedesc[deneb.LightClientHeader] elif kind == LightClientDataFork.Capella: typedesc[capella.LightClientHeader] @@ -202,7 +291,9 @@ template LightClientHeader*(kind: static LightClientDataFork): auto = static: raiseAssert "Unreachable" template LightClientBootstrap*(kind: static LightClientDataFork): auto = - when kind == LightClientDataFork.Deneb: + when kind == LightClientDataFork.Electra: + typedesc[electra.LightClientBootstrap] + elif kind == LightClientDataFork.Deneb: typedesc[deneb.LightClientBootstrap] elif kind == LightClientDataFork.Capella: typedesc[capella.LightClientBootstrap] @@ -212,7 +303,9 @@ template LightClientBootstrap*(kind: static LightClientDataFork): auto = static: raiseAssert "Unreachable" template LightClientUpdate*(kind: static LightClientDataFork): auto = - when kind == LightClientDataFork.Deneb: + when kind == LightClientDataFork.Electra: + typedesc[electra.LightClientUpdate] + elif kind == LightClientDataFork.Deneb: typedesc[deneb.LightClientUpdate] elif kind == LightClientDataFork.Capella: typedesc[capella.LightClientUpdate] @@ -222,7 +315,9 @@ template LightClientUpdate*(kind: static LightClientDataFork): auto = static: raiseAssert "Unreachable" template LightClientFinalityUpdate*(kind: static LightClientDataFork): auto = - when kind == LightClientDataFork.Deneb: + when kind == LightClientDataFork.Electra: + typedesc[electra.LightClientFinalityUpdate] + elif kind == LightClientDataFork.Deneb: typedesc[deneb.LightClientFinalityUpdate] elif kind == LightClientDataFork.Capella: typedesc[capella.LightClientFinalityUpdate] @@ -232,7 +327,9 @@ template LightClientFinalityUpdate*(kind: static LightClientDataFork): auto = static: raiseAssert "Unreachable" template LightClientOptimisticUpdate*(kind: static LightClientDataFork): auto = - when kind == LightClientDataFork.Deneb: + when kind == LightClientDataFork.Electra: + typedesc[electra.LightClientOptimisticUpdate] + elif kind == LightClientDataFork.Deneb: typedesc[deneb.LightClientOptimisticUpdate] elif kind == LightClientDataFork.Capella: typedesc[capella.LightClientOptimisticUpdate] @@ -242,7 +339,9 @@ template LightClientOptimisticUpdate*(kind: static LightClientDataFork): auto = static: raiseAssert "Unreachable" template LightClientStore*(kind: static LightClientDataFork): auto = - when kind == LightClientDataFork.Deneb: + when kind == LightClientDataFork.Electra: + typedesc[electra.LightClientStore] + elif kind == LightClientDataFork.Deneb: typedesc[deneb.LightClientStore] elif kind == LightClientDataFork.Capella: typedesc[capella.LightClientStore] @@ -301,7 +400,10 @@ template Forked*(x: typedesc[ForkyLightClientStore]): auto = template withAll*( x: typedesc[LightClientDataFork], body: untyped): untyped = - static: doAssert LightClientDataFork.high == LightClientDataFork.Deneb + static: doAssert LightClientDataFork.high == LightClientDataFork.Electra + block: + const lcDataFork {.inject, used.} = LightClientDataFork.Electra + body block: const lcDataFork {.inject, used.} = LightClientDataFork.Deneb body @@ -318,6 +420,9 @@ template withAll*( template withLcDataFork*( x: LightClientDataFork, body: untyped): untyped = case x + of LightClientDataFork.Electra: + const lcDataFork {.inject, used.} = LightClientDataFork.Electra + body of LightClientDataFork.Deneb: const lcDataFork {.inject, used.} = LightClientDataFork.Deneb body @@ -334,6 +439,10 @@ template withLcDataFork*( template withForkyHeader*( x: ForkedLightClientHeader, body: untyped): untyped = case x.kind + of LightClientDataFork.Electra: + const lcDataFork {.inject, used.} = LightClientDataFork.Electra + template forkyHeader: untyped {.inject, used.} = x.electraData + body of LightClientDataFork.Deneb: const lcDataFork {.inject, used.} = LightClientDataFork.Deneb template forkyHeader: untyped {.inject, used.} = x.denebData @@ -353,6 +462,10 @@ template withForkyHeader*( template withForkyBootstrap*( x: ForkedLightClientBootstrap, body: untyped): untyped = case x.kind + of LightClientDataFork.Electra: + const lcDataFork {.inject, used.} = LightClientDataFork.Electra + template forkyBootstrap: untyped {.inject, used.} = x.electraData + body of LightClientDataFork.Deneb: const lcDataFork {.inject, used.} = LightClientDataFork.Deneb template forkyBootstrap: untyped {.inject, used.} = x.denebData @@ -372,6 +485,10 @@ template withForkyBootstrap*( template withForkyUpdate*( x: ForkedLightClientUpdate, body: untyped): untyped = case x.kind + of LightClientDataFork.Electra: + const lcDataFork {.inject, used.} = LightClientDataFork.Electra + template forkyUpdate: untyped {.inject, used.} = x.electraData + body of LightClientDataFork.Deneb: const lcDataFork {.inject, used.} = LightClientDataFork.Deneb template forkyUpdate: untyped {.inject, used.} = x.denebData @@ -391,6 +508,10 @@ template withForkyUpdate*( template withForkyFinalityUpdate*( x: ForkedLightClientFinalityUpdate, body: untyped): untyped = case x.kind + of LightClientDataFork.Electra: + const lcDataFork {.inject, used.} = LightClientDataFork.Electra + template forkyFinalityUpdate: untyped {.inject, used.} = x.electraData + body of LightClientDataFork.Deneb: const lcDataFork {.inject, used.} = LightClientDataFork.Deneb template forkyFinalityUpdate: untyped {.inject, used.} = x.denebData @@ -410,6 +531,10 @@ template withForkyFinalityUpdate*( template withForkyOptimisticUpdate*( x: ForkedLightClientOptimisticUpdate, body: untyped): untyped = case x.kind + of LightClientDataFork.Electra: + const lcDataFork {.inject, used.} = LightClientDataFork.Electra + template forkyOptimisticUpdate: untyped {.inject, used.} = x.electraData + body of LightClientDataFork.Deneb: const lcDataFork {.inject, used.} = LightClientDataFork.Deneb template forkyOptimisticUpdate: untyped {.inject, used.} = x.denebData @@ -429,6 +554,10 @@ template withForkyOptimisticUpdate*( template withForkyObject*( x: SomeForkedLightClientObject, body: untyped): untyped = case x.kind + of LightClientDataFork.Electra: + const lcDataFork {.inject, used.} = LightClientDataFork.Electra + template forkyObject: untyped {.inject, used.} = x.electraData + body of LightClientDataFork.Deneb: const lcDataFork {.inject, used.} = LightClientDataFork.Deneb template forkyObject: untyped {.inject, used.} = x.denebData @@ -448,6 +577,10 @@ template withForkyObject*( template withForkyStore*( x: ForkedLightClientStore, body: untyped): untyped = case x.kind + of LightClientDataFork.Electra: + const lcDataFork {.inject, used.} = LightClientDataFork.Electra + template forkyStore: untyped {.inject, used.} = x.electraData + body of LightClientDataFork.Deneb: const lcDataFork {.inject, used.} = LightClientDataFork.Deneb template forkyStore: untyped {.inject, used.} = x.denebData @@ -476,7 +609,9 @@ func init*( type ResultType = typeof(forkyData).Forked static: doAssert ResultType is x const kind = typeof(forkyData).kind - when kind == LightClientDataFork.Deneb: + when kind == LightClientDataFork.Electra: + ResultType(kind: kind, electraData: forkyData) + elif kind == LightClientDataFork.Deneb: ResultType(kind: kind, denebData: forkyData) elif kind == LightClientDataFork.Capella: ResultType(kind: kind, capellaData: forkyData) @@ -491,7 +626,9 @@ template forky*( SomeForkedLightClientObject | ForkedLightClientStore, kind: static LightClientDataFork): untyped = - when kind == LightClientDataFork.Deneb: + when kind == LightClientDataFork.Electra: + x.electraData + elif kind == LightClientDataFork.Deneb: x.denebData elif kind == LightClientDataFork.Capella: x.capellaData @@ -644,7 +781,15 @@ func migrateToDataFork*( denebData: upgrade_lc_header_to_deneb( x.forky(LightClientDataFork.Capella))) - static: doAssert LightClientDataFork.high == LightClientDataFork.Deneb + # Upgrade to Electra + when newKind >= LightClientDataFork.Electra: + if x.kind == LightClientDataFork.Deneb: + x = ForkedLightClientHeader( + kind: LightClientDataFork.Electra, + electraData: upgrade_lc_header_to_electra( + x.forky(LightClientDataFork.Deneb))) + + static: doAssert LightClientDataFork.high == LightClientDataFork.Electra doAssert x.kind == newKind func migrateToDataFork*( @@ -679,7 +824,15 @@ func migrateToDataFork*( denebData: upgrade_lc_bootstrap_to_deneb( x.forky(LightClientDataFork.Capella))) - static: doAssert LightClientDataFork.high == LightClientDataFork.Deneb + # Upgrade to Electra + when newKind >= LightClientDataFork.Electra: + if x.kind == LightClientDataFork.Deneb: + x = ForkedLightClientBootstrap( + kind: LightClientDataFork.Electra, + electraData: upgrade_lc_bootstrap_to_electra( + x.forky(LightClientDataFork.Deneb))) + + static: doAssert LightClientDataFork.high == LightClientDataFork.Electra doAssert x.kind == newKind func migrateToDataFork*( @@ -714,7 +867,15 @@ func migrateToDataFork*( denebData: upgrade_lc_update_to_deneb( x.forky(LightClientDataFork.Capella))) - static: doAssert LightClientDataFork.high == LightClientDataFork.Deneb + # Upgrade to Electra + when newKind >= LightClientDataFork.Electra: + if x.kind == LightClientDataFork.Deneb: + x = ForkedLightClientUpdate( + kind: LightClientDataFork.Electra, + electraData: upgrade_lc_update_to_electra( + x.forky(LightClientDataFork.Deneb))) + + static: doAssert LightClientDataFork.high == LightClientDataFork.Electra doAssert x.kind == newKind func migrateToDataFork*( @@ -749,7 +910,15 @@ func migrateToDataFork*( denebData: upgrade_lc_finality_update_to_deneb( x.forky(LightClientDataFork.Capella))) - static: doAssert LightClientDataFork.high == LightClientDataFork.Deneb + # Upgrade to Electra + when newKind >= LightClientDataFork.Electra: + if x.kind == LightClientDataFork.Deneb: + x = ForkedLightClientFinalityUpdate( + kind: LightClientDataFork.Electra, + electraData: upgrade_lc_finality_update_to_electra( + x.forky(LightClientDataFork.Deneb))) + + static: doAssert LightClientDataFork.high == LightClientDataFork.Electra doAssert x.kind == newKind func migrateToDataFork*( @@ -784,7 +953,15 @@ func migrateToDataFork*( denebData: upgrade_lc_optimistic_update_to_deneb( x.forky(LightClientDataFork.Capella))) - static: doAssert LightClientDataFork.high == LightClientDataFork.Deneb + # Upgrade to Electra + when newKind >= LightClientDataFork.Electra: + if x.kind == LightClientDataFork.Deneb: + x = ForkedLightClientOptimisticUpdate( + kind: LightClientDataFork.Electra, + electraData: upgrade_lc_optimistic_update_to_electra( + x.forky(LightClientDataFork.Deneb))) + + static: doAssert LightClientDataFork.high == LightClientDataFork.Electra doAssert x.kind == newKind func migrateToDataFork*( @@ -819,7 +996,15 @@ func migrateToDataFork*( denebData: upgrade_lc_store_to_deneb( x.forky(LightClientDataFork.Capella))) - static: doAssert LightClientDataFork.high == LightClientDataFork.Deneb + # Upgrade to Electra + when newKind >= LightClientDataFork.Electra: + if x.kind == LightClientDataFork.Deneb: + x = ForkedLightClientStore( + kind: LightClientDataFork.Electra, + electraData: upgrade_lc_store_to_electra( + x.forky(LightClientDataFork.Deneb))) + + static: doAssert LightClientDataFork.high == LightClientDataFork.Electra doAssert x.kind == newKind func migratingToDataFork*[ @@ -960,6 +1145,112 @@ func toDenebLightClientHeader( execution_branch: blck.message.body.build_proof( capella.EXECUTION_PAYLOAD_GINDEX).get) +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/full-node.md#modified-block_to_light_client_header +func toElectraLightClientHeader( + # `SomeSignedBeaconBlock`: https://github.com/nim-lang/Nim/issues/18095 + blck: + phase0.SignedBeaconBlock | phase0.TrustedSignedBeaconBlock | + altair.SignedBeaconBlock | altair.TrustedSignedBeaconBlock | + bellatrix.SignedBeaconBlock | bellatrix.TrustedSignedBeaconBlock +): electra.LightClientHeader = + # Note that during fork transitions, `finalized_header` may still + # point to earlier forks. While Bellatrix blocks also contain an + # `ExecutionPayload` (minus `withdrawals_root`), it was not included + # in the corresponding light client data. To ensure compatibility + # with legacy data going through `upgrade_lc_header_to_capella`, + # leave out execution data. + electra.LightClientHeader( + beacon: blck.message.toBeaconBlockHeader()) + +func toElectraLightClientHeader( + # `SomeSignedBeaconBlock`: https://github.com/nim-lang/Nim/issues/18095 + blck: + capella.SignedBeaconBlock | capella.TrustedSignedBeaconBlock +): electra.LightClientHeader = + template payload: untyped = blck.message.body.execution_payload + electra.LightClientHeader( + beacon: blck.message.toBeaconBlockHeader(), + execution: electra.ExecutionPayloadHeader( + parent_hash: payload.parent_hash, + fee_recipient: payload.fee_recipient, + state_root: payload.state_root, + receipts_root: payload.receipts_root, + logs_bloom: payload.logs_bloom, + prev_randao: payload.prev_randao, + block_number: payload.block_number, + gas_limit: payload.gas_limit, + gas_used: payload.gas_used, + timestamp: payload.timestamp, + extra_data: payload.extra_data, + base_fee_per_gas: payload.base_fee_per_gas, + block_hash: payload.block_hash, + transactions_root: hash_tree_root(payload.transactions), + withdrawals_root: hash_tree_root(payload.withdrawals)), + execution_branch: blck.message.body.build_proof( + capella.EXECUTION_PAYLOAD_GINDEX).get) + +func toElectraLightClientHeader( + # `SomeSignedBeaconBlock`: https://github.com/nim-lang/Nim/issues/18095 + blck: + deneb.SignedBeaconBlock | deneb.TrustedSignedBeaconBlock +): electra.LightClientHeader = + template payload: untyped = blck.message.body.execution_payload + electra.LightClientHeader( + beacon: blck.message.toBeaconBlockHeader(), + execution: electra.ExecutionPayloadHeader( + parent_hash: payload.parent_hash, + fee_recipient: payload.fee_recipient, + state_root: payload.state_root, + receipts_root: payload.receipts_root, + logs_bloom: payload.logs_bloom, + prev_randao: payload.prev_randao, + block_number: payload.block_number, + gas_limit: payload.gas_limit, + gas_used: payload.gas_used, + timestamp: payload.timestamp, + extra_data: payload.extra_data, + base_fee_per_gas: payload.base_fee_per_gas, + block_hash: payload.block_hash, + transactions_root: hash_tree_root(payload.transactions), + withdrawals_root: hash_tree_root(payload.withdrawals), + blob_gas_used: payload.blob_gas_used, + excess_blob_gas: payload.excess_blob_gas), + execution_branch: blck.message.body.build_proof( + capella.EXECUTION_PAYLOAD_GINDEX).get) + +func toElectraLightClientHeader( + # `SomeSignedBeaconBlock`: https://github.com/nim-lang/Nim/issues/18095 + blck: + electra.SignedBeaconBlock | electra.TrustedSignedBeaconBlock +): electra.LightClientHeader = + template payload: untyped = blck.message.body.execution_payload + electra.LightClientHeader( + beacon: blck.message.toBeaconBlockHeader(), + execution: electra.ExecutionPayloadHeader( + parent_hash: payload.parent_hash, + fee_recipient: payload.fee_recipient, + state_root: payload.state_root, + receipts_root: payload.receipts_root, + logs_bloom: payload.logs_bloom, + prev_randao: payload.prev_randao, + block_number: payload.block_number, + gas_limit: payload.gas_limit, + gas_used: payload.gas_used, + timestamp: payload.timestamp, + extra_data: payload.extra_data, + base_fee_per_gas: payload.base_fee_per_gas, + block_hash: payload.block_hash, + transactions_root: hash_tree_root(payload.transactions), + withdrawals_root: hash_tree_root(payload.withdrawals), + blob_gas_used: payload.blob_gas_used, + excess_blob_gas: payload.excess_blob_gas, + deposit_requests_root: hash_tree_root(payload.deposit_requests), + withdrawal_requests_root: hash_tree_root(payload.withdrawal_requests), + consolidation_requests_root: + hash_tree_root(payload.consolidation_requests)), + execution_branch: blck.message.body.build_proof( + capella.EXECUTION_PAYLOAD_GINDEX).get) + func toLightClientHeader*( # `SomeSignedBeaconBlock`: https://github.com/nim-lang/Nim/issues/18095 blck: @@ -970,9 +1261,8 @@ func toLightClientHeader*( deneb.SignedBeaconBlock | deneb.TrustedSignedBeaconBlock | electra.SignedBeaconBlock | electra.TrustedSignedBeaconBlock, kind: static LightClientDataFork): auto = - when blck is electra.SignedBeaconBlock or blck is electra.TrustedSignedBeaconBlock: - debugComment "toLightClientHeader electra missing" - default(deneb.LightClientHeader) + when kind == LightClientDataFork.Electra: + blck.toElectraLightClientHeader() elif kind == LightClientDataFork.Deneb: blck.toDenebLightClientHeader() elif kind == LightClientDataFork.Capella: @@ -1000,9 +1290,13 @@ func shortLog*[ capellaData: typeof(x.capellaData.shortLog()) of LightClientDataFork.Deneb: denebData: typeof(x.denebData.shortLog()) + of LightClientDataFork.Electra: + electraData: typeof(x.electraData.shortLog()) - let xKind = x.kind # Nim 2.0.6: Using `kind: x.kind` inside case is broken + let xKind = x.kind # https://github.com/nim-lang/Nim/issues/23762 case xKind + of LightClientDataFork.Electra: + ResultType(kind: xKind, electraData: x.electraData.shortLog()) of LightClientDataFork.Deneb: ResultType(kind: xKind, denebData: x.denebData.shortLog()) of LightClientDataFork.Capella: diff --git a/beacon_chain/spec/light_client_sync.nim b/beacon_chain/spec/light_client_sync.nim index ef58198ae..d735e4152 100644 --- a/beacon_chain/spec/light_client_sync.nim +++ b/beacon_chain/spec/light_client_sync.nim @@ -15,6 +15,21 @@ import from ../consensus_object_pools/block_pools_types import VerifierError export block_pools_types.VerifierError +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/sync-protocol.md#is_valid_normalized_merkle_branch +func is_valid_normalized_merkle_branch[N]( + leaf: Eth2Digest, + branch: array[N, Eth2Digest], + gindex: static GeneralizedIndex, + root: Eth2Digest): bool = + const + depth = log2trunc(gindex) + index = get_subtree_index(gindex) + num_extra = branch.len - depth + for i in 0 ..< num_extra: + if not branch[i].isZero: + return false + is_valid_merkle_branch(leaf, branch[num_extra .. ^1], depth, index, root) + # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/sync-protocol.md#initialize_light_client_store func initialize_light_client_store*( trusted_block_root: Eth2Digest, @@ -29,13 +44,15 @@ func initialize_light_client_store*( if hash_tree_root(bootstrap.header.beacon) != trusted_block_root: return ResultType.err(VerifierError.Invalid) - if not is_valid_merkle_branch( - hash_tree_root(bootstrap.current_sync_committee), - bootstrap.current_sync_committee_branch, - log2trunc(altair.CURRENT_SYNC_COMMITTEE_GINDEX), - get_subtree_index(altair.CURRENT_SYNC_COMMITTEE_GINDEX), - bootstrap.header.beacon.state_root): - return ResultType.err(VerifierError.Invalid) + withLcDataFork(lcDataForkAtConsensusFork( + cfg.consensusForkAtEpoch(bootstrap.header.beacon.slot.epoch))): + when lcDataFork > LightClientDataFork.None: + if not is_valid_normalized_merkle_branch( + hash_tree_root(bootstrap.current_sync_committee), + bootstrap.current_sync_committee_branch, + lcDataFork.CURRENT_SYNC_COMMITTEE_GINDEX, + bootstrap.header.beacon.state_root): + return ResultType.err(VerifierError.Invalid) return ResultType.ok(typeof(bootstrap).kind.LightClientStore( finalized_header: bootstrap.header, @@ -109,13 +126,15 @@ proc validate_light_client_update*( finalized_root.reset() else: return err(VerifierError.Invalid) - if not is_valid_merkle_branch( - finalized_root, - update.finality_branch, - log2trunc(altair.FINALIZED_ROOT_GINDEX), - get_subtree_index(altair.FINALIZED_ROOT_GINDEX), - update.attested_header.beacon.state_root): - return err(VerifierError.Invalid) + withLcDataFork(lcDataForkAtConsensusFork( + cfg.consensusForkAtEpoch(update.attested_header.beacon.slot.epoch))): + when lcDataFork > LightClientDataFork.None: + if not is_valid_normalized_merkle_branch( + finalized_root, + update.finality_branch, + lcDataFork.FINALIZED_ROOT_GINDEX, + update.attested_header.beacon.state_root): + return err(VerifierError.Invalid) # Verify that the `next_sync_committee`, if present, actually is the # next sync committee saved in the state of the `attested_header` @@ -128,13 +147,15 @@ proc validate_light_client_update*( if attested_period == store_period and is_next_sync_committee_known: if update.next_sync_committee != store.next_sync_committee: return err(VerifierError.UnviableFork) - if not is_valid_merkle_branch( - hash_tree_root(update.next_sync_committee), - update.next_sync_committee_branch, - log2trunc(altair.NEXT_SYNC_COMMITTEE_GINDEX), - get_subtree_index(altair.NEXT_SYNC_COMMITTEE_GINDEX), - update.attested_header.beacon.state_root): - return err(VerifierError.Invalid) + withLcDataFork(lcDataForkAtConsensusFork( + cfg.consensusForkAtEpoch(update.attested_header.beacon.slot.epoch))): + when lcDataFork > LightClientDataFork.None: + if not is_valid_normalized_merkle_branch( + hash_tree_root(update.next_sync_committee), + update.next_sync_committee_branch, + lcDataFork.NEXT_SYNC_COMMITTEE_GINDEX, + update.attested_header.beacon.state_root): + return err(VerifierError.Invalid) # Verify sync committee aggregate signature let sync_committee = diff --git a/tests/consensus_spec/altair/test_fixture_light_client_sync_protocol.nim b/tests/consensus_spec/altair/test_fixture_light_client_sync_protocol.nim index 7e8def2a4..59974c0c5 100644 --- a/tests/consensus_spec/altair/test_fixture_light_client_sync_protocol.nim +++ b/tests/consensus_spec/altair/test_fixture_light_client_sync_protocol.nim @@ -172,14 +172,15 @@ proc runTest(storeDataFork: static LightClientDataFork) = # Sync committee signing the attested_header (sync_aggregate, signature_slot) = get_sync_aggregate(cfg, forked[]) next_sync_committee = SyncCommittee() - next_sync_committee_branch = default(altair.NextSyncCommitteeBranch) + next_sync_committee_branch = + default(storeDataFork.NextSyncCommitteeBranch) # Ensure that finality checkpoint is genesis check state.finalized_checkpoint.epoch == 0 # Finality is unchanged let finality_header = default(storeDataFork.LightClientHeader) - finality_branch = default(altair.FinalityBranch) + finality_branch = default(storeDataFork.FinalityBranch) update = storeDataFork.LightClientUpdate( attested_header: attested_header, @@ -228,11 +229,12 @@ proc runTest(storeDataFork: static LightClientDataFork) = # Sync committee signing the attested_header (sync_aggregate, signature_slot) = get_sync_aggregate(cfg, forked[]) next_sync_committee = SyncCommittee() - next_sync_committee_branch = default(altair.NextSyncCommitteeBranch) + next_sync_committee_branch = + default(storeDataFork.NextSyncCommitteeBranch) # Finality is unchanged finality_header = default(storeDataFork.LightClientHeader) - finality_branch = default(altair.FinalityBranch) + finality_branch = default(storeDataFork.FinalityBranch) update = storeDataFork.LightClientUpdate( attested_header: attested_header, @@ -283,12 +285,13 @@ proc runTest(storeDataFork: static LightClientDataFork) = # Sync committee is updated template next_sync_committee(): auto = state.next_sync_committee let - next_sync_committee_branch = - state.build_proof(altair.NEXT_SYNC_COMMITTEE_GINDEX).get + next_sync_committee_branch = normalize_merkle_branch( + state.build_proof(altair.NEXT_SYNC_COMMITTEE_GINDEX).get, + storeDataFork.NEXT_SYNC_COMMITTEE_GINDEX) # Finality is unchanged finality_header = default(storeDataFork.LightClientHeader) - finality_branch = default(altair.FinalityBranch) + finality_branch = default(storeDataFork.FinalityBranch) update = storeDataFork.LightClientUpdate( attested_header: attested_header, @@ -345,7 +348,8 @@ proc runTest(storeDataFork: static LightClientDataFork) = # Updated sync_committee and finality next_sync_committee = SyncCommittee() - next_sync_committee_branch = default(altair.NextSyncCommitteeBranch) + next_sync_committee_branch = + default(storeDataFork.NextSyncCommitteeBranch) finalized_block = blocks[SLOTS_PER_EPOCH - 1].altairData finalized_header = finalized_block.toLightClientHeader(storeDataFork) check: @@ -354,7 +358,9 @@ proc runTest(storeDataFork: static LightClientDataFork) = finalized_header.beacon.hash_tree_root() == state.finalized_checkpoint.root let - finality_branch = state.build_proof(altair.FINALIZED_ROOT_GINDEX).get + finality_branch = normalize_merkle_branch( + state.build_proof(altair.FINALIZED_ROOT_GINDEX).get, + storeDataFork.FINALIZED_ROOT_GINDEX) update = storeDataFork.LightClientUpdate( attested_header: attested_header, diff --git a/tests/test_light_client.nim b/tests/test_light_client.nim index 9b549fa79..9219bef35 100644 --- a/tests/test_light_client.nim +++ b/tests/test_light_client.nim @@ -22,7 +22,7 @@ from ./testbcutil import addHeadBlock suite "Light client" & preset(): const # Test config, should be long enough to cover interesting transitions - headPeriod = 3.SyncCommitteePeriod + headPeriod = 4.SyncCommitteePeriod let cfg = block: # Fork schedule so that each `LightClientDataFork` is covered static: doAssert ConsensusFork.high == ConsensusFork.Electra @@ -31,7 +31,7 @@ suite "Light client" & preset(): res.BELLATRIX_FORK_EPOCH = 2.Epoch res.CAPELLA_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 1).Epoch res.DENEB_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 2).Epoch - res.ELECTRA_FORK_EPOCH = FAR_FUTURE_EPOCH + res.ELECTRA_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 3).Epoch res altairStartSlot = cfg.ALTAIR_FORK_EPOCH.start_slot @@ -246,4 +246,4 @@ suite "Light client" & preset(): let headSlot = (finalizedSlot.epoch + i).start_slot cpDag.advanceToSlot(headSlot, verifier, quarantine[]) - check true \ No newline at end of file + check true diff --git a/tests/test_light_client_processor.nim b/tests/test_light_client_processor.nim index 6d70c7bf7..a1fcecb85 100644 --- a/tests/test_light_client_processor.nim +++ b/tests/test_light_client_processor.nim @@ -24,8 +24,8 @@ from ./testbcutil import addHeadBlock suite "Light client processor" & preset(): const # Test config, should be long enough to cover interesting transitions lowPeriod = 0.SyncCommitteePeriod - lastPeriodWithSupermajority = 3.SyncCommitteePeriod - highPeriod = 5.SyncCommitteePeriod + lastPeriodWithSupermajority = 4.SyncCommitteePeriod + highPeriod = 6.SyncCommitteePeriod let cfg = block: # Fork schedule so that each `LightClientDataFork` is covered static: doAssert ConsensusFork.high == ConsensusFork.Electra @@ -34,7 +34,7 @@ suite "Light client processor" & preset(): res.BELLATRIX_FORK_EPOCH = 2.Epoch res.CAPELLA_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 1).Epoch res.DENEB_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 2).Epoch - res.ELECTRA_FORK_EPOCH = FAR_FUTURE_EPOCH + res.ELECTRA_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 3).Epoch res const numValidators = SLOTS_PER_EPOCH @@ -146,22 +146,35 @@ suite "Light client processor" & preset(): proc applyPeriodWithoutSupermajority( period: SyncCommitteePeriod, update: ref ForkedLightClientUpdate) = for i in 0 ..< 2: - res = processor[].storeObject( - MsgSource.gossip, getBeaconTime(), update[]) - check update[].kind <= store[].kind - if finalizationMode == LightClientFinalizationMode.Optimistic or - period == lastPeriodWithSupermajority + 1: + # Reduce stack size by making this a `proc` + proc applyInitial(update: ref ForkedLightClientUpdate) = + res = processor[].storeObject( + MsgSource.gossip, getBeaconTime(), update[]) + check update[].kind <= store[].kind if finalizationMode == LightClientFinalizationMode.Optimistic or - i == 0: - withForkyStore(store[]): - when lcDataFork > LightClientDataFork.None: - let upgraded = newClone( - update[].migratingToDataFork(lcDataFork)) - template forkyUpdate: untyped = upgraded[].forky(lcDataFork) - check: - res.isOk - forkyStore.best_valid_update.isSome - forkyStore.best_valid_update.get.matches(forkyUpdate) + period == lastPeriodWithSupermajority + 1: + if finalizationMode == LightClientFinalizationMode.Optimistic or + i == 0: + withForkyStore(store[]): + when lcDataFork > LightClientDataFork.None: + let upgraded = newClone( + update[].migratingToDataFork(lcDataFork)) + template forkyUpdate: untyped = upgraded[].forky(lcDataFork) + check: + res.isOk + forkyStore.best_valid_update.isSome + forkyStore.best_valid_update.get.matches(forkyUpdate) + else: + withForkyStore(store[]): + when lcDataFork > LightClientDataFork.None: + let upgraded = newClone( + update[].migratingToDataFork(lcDataFork)) + template forkyUpdate: untyped = upgraded[].forky(lcDataFork) + check: + res.isErr + res.error == VerifierError.Duplicate + forkyStore.best_valid_update.isSome + forkyStore.best_valid_update.get.matches(forkyUpdate) else: withForkyStore(store[]): when lcDataFork > LightClientDataFork.None: @@ -170,20 +183,11 @@ suite "Light client processor" & preset(): template forkyUpdate: untyped = upgraded[].forky(lcDataFork) check: res.isErr - res.error == VerifierError.Duplicate + res.error == VerifierError.MissingParent forkyStore.best_valid_update.isSome - forkyStore.best_valid_update.get.matches(forkyUpdate) - else: - withForkyStore(store[]): - when lcDataFork > LightClientDataFork.None: - let upgraded = newClone( - update[].migratingToDataFork(lcDataFork)) - template forkyUpdate: untyped = upgraded[].forky(lcDataFork) - check: - res.isErr - res.error == VerifierError.MissingParent - forkyStore.best_valid_update.isSome - not forkyStore.best_valid_update.get.matches(forkyUpdate) + not forkyStore.best_valid_update.get.matches(forkyUpdate) + + applyInitial(update) # Reduce stack size by making this a `proc` proc applyDuplicate(update: ref ForkedLightClientUpdate) = @@ -387,4 +391,4 @@ suite "Light client processor" & preset(): check: res.isErr res.error == VerifierError.MissingParent - numOnStoreInitializedCalls == 0 \ No newline at end of file + numOnStoreInitializedCalls == 0 From bab7d8428fe940e59424eec0651d73136c7520e6 Mon Sep 17 00:00:00 2001 From: Eugene Kabanov Date: Thu, 27 Jun 2024 04:54:04 +0300 Subject: [PATCH 27/68] Bump nim-bearssl. (#6390) --- vendor/nim-bearssl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/nim-bearssl b/vendor/nim-bearssl index a806cbfab..646fa2152 160000 --- a/vendor/nim-bearssl +++ b/vendor/nim-bearssl @@ -1 +1 @@ -Subproject commit a806cbfab5fe8de49c76139f8705fff79daf99ee +Subproject commit 646fa2152b11980c24bf34b3e214b479c9d25f21 From 190dbfd48181cf8ff87d6715165e4812e62a318b Mon Sep 17 00:00:00 2001 From: Eugene Kabanov Date: Fri, 28 Jun 2024 06:54:51 +0300 Subject: [PATCH 28/68] Fix empty status string handling, address #6175. (#6391) --- beacon_chain/rpc/rest_beacon_api.nim | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/beacon_chain/rpc/rest_beacon_api.nim b/beacon_chain/rpc/rest_beacon_api.nim index 58aa5a881..29e77dc07 100644 --- a/beacon_chain/rpc/rest_beacon_api.nim +++ b/beacon_chain/rpc/rest_beacon_api.nim @@ -425,7 +425,11 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) = Http400, InvalidRequestBodyError, $error) let ids = request.ids.valueOr: @[] - filter = request.status.valueOr: AllValidatorFilterKinds + filter = + if request.status.isNone() or len(request.status.get) == 0: + AllValidatorFilterKinds + else: + request.status.get (ids, filter) sid = state_id.valueOr: return RestApiResponse.jsonError(Http400, InvalidStateIdValueError, From 08863465a0be232473c407ae0000b2078e1dd36d Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Fri, 28 Jun 2024 16:04:04 +0200 Subject: [PATCH 29/68] deps: update ci.yml and be more explicit in .nimble (#6392) Bump nim-blscurve, nim-faststreams, nim-http-utils, nim-metrics, nim-presto, nim-serialization, nim-snappy for explicit refc and use `results` instead of `stew/results`. --- vendor/nim-blscurve | 2 +- vendor/nim-faststreams | 2 +- vendor/nim-http-utils | 2 +- vendor/nim-metrics | 2 +- vendor/nim-presto | 2 +- vendor/nim-serialization | 2 +- vendor/nim-snappy | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/vendor/nim-blscurve b/vendor/nim-blscurve index f29698d2e..1d0d886cd 160000 --- a/vendor/nim-blscurve +++ b/vendor/nim-blscurve @@ -1 +1 @@ -Subproject commit f29698d2e9a59453d99db7315a5af58add3c8715 +Subproject commit 1d0d886cdcb17b25108c7b904f84819629c0e4fb diff --git a/vendor/nim-faststreams b/vendor/nim-faststreams index 11b9d952a..dbc4a95df 160000 --- a/vendor/nim-faststreams +++ b/vendor/nim-faststreams @@ -1 +1 @@ -Subproject commit 11b9d952a80ec87e2443405a6a5382f9daac51f8 +Subproject commit dbc4a95df60238157dcf286f6125188cb72f37c1 diff --git a/vendor/nim-http-utils b/vendor/nim-http-utils index be57dbc90..98496aa24 160000 --- a/vendor/nim-http-utils +++ b/vendor/nim-http-utils @@ -1 +1 @@ -Subproject commit be57dbc902d36f37540897e98c69aa80f868cb45 +Subproject commit 98496aa24d9364d1652e531f5f346de9b7cb3e15 diff --git a/vendor/nim-metrics b/vendor/nim-metrics index 2e29df095..5f5e0f843 160000 --- a/vendor/nim-metrics +++ b/vendor/nim-metrics @@ -1 +1 @@ -Subproject commit 2e29df095059a7a787b234f040612b742567b2bc +Subproject commit 5f5e0f84349775069d048a6aa6194c1df383abb5 diff --git a/vendor/nim-presto b/vendor/nim-presto index a9687dda1..2190421e0 160000 --- a/vendor/nim-presto +++ b/vendor/nim-presto @@ -1 +1 @@ -Subproject commit a9687dda1c3e20d5b066d42b33c2a63f018af93f +Subproject commit 2190421e09938696cd95d54b1f4753446c84c7a2 diff --git a/vendor/nim-serialization b/vendor/nim-serialization index 005ee90cb..298a9554a 160000 --- a/vendor/nim-serialization +++ b/vendor/nim-serialization @@ -1 +1 @@ -Subproject commit 005ee90cb6aa563cdd690910455ea05f916ead3f +Subproject commit 298a9554a885b2df59737bb3461aac8d0d339724 diff --git a/vendor/nim-snappy b/vendor/nim-snappy index 913c426d5..2de3844c6 160000 --- a/vendor/nim-snappy +++ b/vendor/nim-snappy @@ -1 +1 @@ -Subproject commit 913c426d571cf82601452642e01cd11ea26f7ac6 +Subproject commit 2de3844c6e3d51ef54a698c52b3d66197c982505 From 68eabc098b6ff5a3dd9033c6c5f24743a5731096 Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Sun, 30 Jun 2024 08:56:52 +0200 Subject: [PATCH 30/68] ssz: bump (fixes #6393) --- vendor/nim-ssz-serialization | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/nim-ssz-serialization b/vendor/nim-ssz-serialization index b71ebc41c..3475c2b28 160000 --- a/vendor/nim-ssz-serialization +++ b/vendor/nim-ssz-serialization @@ -1 +1 @@ -Subproject commit b71ebc41c8e5027580be77a9707df1a64e6d9c8b +Subproject commit 3475c2b2825b83995ea636c1ab57354f1fdcbfbb From 13e766d4df42d2d67eeb315fd3ed1412f4570f3f Mon Sep 17 00:00:00 2001 From: tersec Date: Mon, 1 Jul 2024 04:18:41 +0000 Subject: [PATCH 31/68] add database electra block tests (#6394) --- AllTests-mainnet.md | 5 +- beacon_chain/beacon_chain_db.nim | 3 +- .../gossip_processing/gossip_validation.nim | 1 - config.nims | 3 - ncli/ncli_db.nim | 2 + tests/test_beacon_chain_db.nim | 68 ++++++++++++++++++- tests/testblockutil.nim | 2 - 7 files changed, 74 insertions(+), 10 deletions(-) diff --git a/AllTests-mainnet.md b/AllTests-mainnet.md index a27029e2e..a7b215453 100644 --- a/AllTests-mainnet.md +++ b/AllTests-mainnet.md @@ -54,6 +54,7 @@ OK: 4/4 Fail: 0/4 Skip: 0/4 + sanity check Deneb blocks [Preset: mainnet] OK + sanity check Deneb states [Preset: mainnet] OK + sanity check Deneb states, reusing buffers [Preset: mainnet] OK ++ sanity check Electra blocks [Preset: mainnet] OK + sanity check blobs [Preset: mainnet] OK + sanity check genesis roundtrip [Preset: mainnet] OK + sanity check phase 0 blocks [Preset: mainnet] OK @@ -62,7 +63,7 @@ OK: 4/4 Fail: 0/4 Skip: 0/4 + sanity check phase 0 states, reusing buffers [Preset: mainnet] OK + sanity check state diff roundtrip [Preset: mainnet] OK ``` -OK: 25/25 Fail: 0/25 Skip: 0/25 +OK: 26/26 Fail: 0/26 Skip: 0/26 ## Beacon state [Preset: mainnet] ```diff + Smoke test initialize_beacon_state_from_eth1 [Preset: mainnet] OK @@ -1032,4 +1033,4 @@ OK: 2/2 Fail: 0/2 Skip: 0/2 OK: 9/9 Fail: 0/9 Skip: 0/9 ---TOTAL--- -OK: 689/694 Fail: 0/694 Skip: 5/694 +OK: 690/695 Fail: 0/695 Skip: 5/695 diff --git a/beacon_chain/beacon_chain_db.nim b/beacon_chain/beacon_chain_db.nim index fac0cd2f5..5bca68264 100644 --- a/beacon_chain/beacon_chain_db.nim +++ b/beacon_chain/beacon_chain_db.nim @@ -1366,7 +1366,8 @@ proc containsBlock*( proc containsBlock*[ X: altair.TrustedSignedBeaconBlock | bellatrix.TrustedSignedBeaconBlock | - capella.TrustedSignedBeaconBlock | deneb.TrustedSignedBeaconBlock]( + capella.TrustedSignedBeaconBlock | deneb.TrustedSignedBeaconBlock | + electra.TrustedSignedBeaconBlock]( db: BeaconChainDB, key: Eth2Digest, T: type X): bool = db.blocks[X.kind].contains(key.data).expectDb() diff --git a/beacon_chain/gossip_processing/gossip_validation.nim b/beacon_chain/gossip_processing/gossip_validation.nim index c7b755670..9f8659488 100644 --- a/beacon_chain/gossip_processing/gossip_validation.nim +++ b/beacon_chain/gossip_processing/gossip_validation.nim @@ -1132,7 +1132,6 @@ proc validateAggregate*( Future[Result[ tuple[attestingIndices: seq[ValidatorIndex], sig: CookedSig], ValidationError]] {.async: (raises: [CancelledError]).} = - debugComment "is not" template aggregate_and_proof: untyped = signedAggregateAndProof.message template aggregate: untyped = aggregate_and_proof.aggregate diff --git a/config.nims b/config.nims index 42d47c447..ec1ce2b79 100644 --- a/config.nims +++ b/config.nims @@ -187,9 +187,6 @@ switch("warning", "CaseTransition:off") # do its (N)RVO pass: https://github.com/nim-lang/RFCs/issues/230 switch("warning", "ObservableStores:off") -# Too many false positives for "Warning: method has lock level , but another method has 0 [LockLevel]" -switch("warning", "LockLevel:off") - # Too many right now to read compiler output. Warnings are legitimate, but # should be fixed out-of-band of `unstable` branch. switch("warning", "BareExcept:off") diff --git a/ncli/ncli_db.nim b/ncli/ncli_db.nim index ccc2559ce..3129e31e1 100644 --- a/ncli/ncli_db.nim +++ b/ncli/ncli_db.nim @@ -383,6 +383,7 @@ proc cmdDumpState(conf: DbConf) = bellatrixState = (ref bellatrix.HashedBeaconState)() capellaState = (ref capella.HashedBeaconState)() denebState = (ref deneb.HashedBeaconState)() + electraState = (ref electra.HashedBeaconState)() for stateRoot in conf.stateRoot: if shouldShutDown: quit QuitSuccess @@ -401,6 +402,7 @@ proc cmdDumpState(conf: DbConf) = doit(bellatrixState[]) doit(capellaState[]) doit(denebState[]) + doit(electraState[]) echo "Couldn't load ", stateRoot diff --git a/tests/test_beacon_chain_db.nim b/tests/test_beacon_chain_db.nim index c81bb95c9..08b47696c 100644 --- a/tests/test_beacon_chain_db.nim +++ b/tests/test_beacon_chain_db.nim @@ -100,6 +100,13 @@ func withDigest(blck: deneb.TrustedBeaconBlock): root: hash_tree_root(blck) ) +func withDigest(blck: electra.TrustedBeaconBlock): + electra.TrustedSignedBeaconBlock = + electra.TrustedSignedBeaconBlock( + message: blck, + root: hash_tree_root(blck) + ) + proc getTestStates(consensusFork: ConsensusFork): auto = let db = makeTestDB(SLOTS_PER_EPOCH) @@ -113,7 +120,7 @@ proc getTestStates(consensusFork: ConsensusFork): auto = testStates -debugComment "add some electra states, and test electra state/block loading/etc" +debugComment "add some electra states, and test electra state loading/etc" # Each set of states gets used twice, so scope them to module let @@ -153,6 +160,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, bellatrix.TrustedSignedBeaconBlock) not db.containsBlock(root, capella.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) + not db.containsBlock(root, electra.TrustedSignedBeaconBlock) db.getBlock(root, phase0.TrustedSignedBeaconBlock).get() == signedBlock db.getBlockSSZ(root, tmp, phase0.TrustedSignedBeaconBlock) db.getBlockSZ(root, tmp2, phase0.TrustedSignedBeaconBlock) @@ -168,6 +176,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, bellatrix.TrustedSignedBeaconBlock) not db.containsBlock(root, capella.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) + not db.containsBlock(root, electra.TrustedSignedBeaconBlock) db.getBlock(root, phase0.TrustedSignedBeaconBlock).isErr() not db.getBlockSSZ(root, tmp, phase0.TrustedSignedBeaconBlock) not db.getBlockSZ(root, tmp2, phase0.TrustedSignedBeaconBlock) @@ -200,6 +209,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, bellatrix.TrustedSignedBeaconBlock) not db.containsBlock(root, capella.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) + not db.containsBlock(root, electra.TrustedSignedBeaconBlock) db.getBlock(root, altair.TrustedSignedBeaconBlock).get() == signedBlock db.getBlockSSZ(root, tmp, altair.TrustedSignedBeaconBlock) db.getBlockSZ(root, tmp2, altair.TrustedSignedBeaconBlock) @@ -215,6 +225,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, bellatrix.TrustedSignedBeaconBlock) not db.containsBlock(root, capella.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) + not db.containsBlock(root, electra.TrustedSignedBeaconBlock) db.getBlock(root, altair.TrustedSignedBeaconBlock).isErr() not db.getBlockSSZ(root, tmp, altair.TrustedSignedBeaconBlock) not db.getBlockSZ(root, tmp2, altair.TrustedSignedBeaconBlock) @@ -247,6 +258,7 @@ suite "Beacon chain DB" & preset(): db.containsBlock(root, bellatrix.TrustedSignedBeaconBlock) not db.containsBlock(root, capella.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) + not db.containsBlock(root, electra.TrustedSignedBeaconBlock) db.getBlock(root, bellatrix.TrustedSignedBeaconBlock).get() == signedBlock db.getBlockSSZ(root, tmp, bellatrix.TrustedSignedBeaconBlock) db.getBlockSZ(root, tmp2, bellatrix.TrustedSignedBeaconBlock) @@ -262,6 +274,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, bellatrix.TrustedSignedBeaconBlock) not db.containsBlock(root, capella.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) + not db.containsBlock(root, electra.TrustedSignedBeaconBlock) db.getBlock(root, bellatrix.TrustedSignedBeaconBlock).isErr() not db.getBlockSSZ(root, tmp, bellatrix.TrustedSignedBeaconBlock) not db.getBlockSZ(root, tmp2, bellatrix.TrustedSignedBeaconBlock) @@ -293,6 +306,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, altair.TrustedSignedBeaconBlock) not db.containsBlock(root, bellatrix.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) + not db.containsBlock(root, electra.TrustedSignedBeaconBlock) db.containsBlock(root, capella.TrustedSignedBeaconBlock) db.getBlock(root, capella.TrustedSignedBeaconBlock).get() == signedBlock db.getBlockSSZ(root, tmp, capella.TrustedSignedBeaconBlock) @@ -309,6 +323,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, bellatrix.TrustedSignedBeaconBlock) not db.containsBlock(root, capella.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) + not db.containsBlock(root, electra.TrustedSignedBeaconBlock) db.getBlock(root, capella.TrustedSignedBeaconBlock).isErr() not db.getBlockSSZ(root, tmp, capella.TrustedSignedBeaconBlock) not db.getBlockSZ(root, tmp2, capella.TrustedSignedBeaconBlock) @@ -341,6 +356,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, bellatrix.TrustedSignedBeaconBlock) not db.containsBlock(root, capella.TrustedSignedBeaconBlock) db.containsBlock(root, deneb.TrustedSignedBeaconBlock) + not db.containsBlock(root, electra.TrustedSignedBeaconBlock) db.getBlock(root, deneb.TrustedSignedBeaconBlock).get() == signedBlock db.getBlockSSZ(root, tmp, deneb.TrustedSignedBeaconBlock) db.getBlockSZ(root, tmp2, deneb.TrustedSignedBeaconBlock) @@ -356,6 +372,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, bellatrix.TrustedSignedBeaconBlock) not db.containsBlock(root, capella.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) + not db.containsBlock(root, electra.TrustedSignedBeaconBlock) db.getBlock(root, deneb.TrustedSignedBeaconBlock).isErr() not db.getBlockSSZ(root, tmp, deneb.TrustedSignedBeaconBlock) not db.getBlockSZ(root, tmp2, deneb.TrustedSignedBeaconBlock) @@ -371,6 +388,55 @@ suite "Beacon chain DB" & preset(): db.close() + test "sanity check Electra blocks" & preset(): + let db = BeaconChainDB.new("", inMemory = true) + + let + signedBlock = withDigest((electra.TrustedBeaconBlock)()) + root = hash_tree_root(signedBlock.message) + + db.putBlock(signedBlock) + + var tmp, tmp2: seq[byte] + check: + db.containsBlock(root) + not db.containsBlock(root, phase0.TrustedSignedBeaconBlock) + not db.containsBlock(root, altair.TrustedSignedBeaconBlock) + not db.containsBlock(root, bellatrix.TrustedSignedBeaconBlock) + not db.containsBlock(root, capella.TrustedSignedBeaconBlock) + not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) + db.containsBlock(root, electra.TrustedSignedBeaconBlock) + db.getBlock(root, electra.TrustedSignedBeaconBlock).get() == signedBlock + db.getBlockSSZ(root, tmp, electra.TrustedSignedBeaconBlock) + db.getBlockSZ(root, tmp2, electra.TrustedSignedBeaconBlock) + tmp == SSZ.encode(signedBlock) + tmp2 == encodeFramed(tmp) + uncompressedLenFramed(tmp2).isSome + + check: + db.delBlock(ConsensusFork.Electra, root) + not db.containsBlock(root) + not db.containsBlock(root, phase0.TrustedSignedBeaconBlock) + not db.containsBlock(root, altair.TrustedSignedBeaconBlock) + not db.containsBlock(root, bellatrix.TrustedSignedBeaconBlock) + not db.containsBlock(root, capella.TrustedSignedBeaconBlock) + not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) + not db.containsBlock(root, electra.TrustedSignedBeaconBlock) + db.getBlock(root, electra.TrustedSignedBeaconBlock).isErr() + not db.getBlockSSZ(root, tmp, electra.TrustedSignedBeaconBlock) + not db.getBlockSZ(root, tmp2, electra.TrustedSignedBeaconBlock) + + db.putStateRoot(root, signedBlock.message.slot, root) + var root2 = root + root2.data[0] = root.data[0] + 1 + db.putStateRoot(root, signedBlock.message.slot + 1, root2) + + check: + db.getStateRoot(root, signedBlock.message.slot).get() == root + db.getStateRoot(root, signedBlock.message.slot + 1).get() == root2 + + db.close() + test "sanity check phase 0 states" & preset(): let db = makeTestDB(SLOTS_PER_EPOCH) diff --git a/tests/testblockutil.nim b/tests/testblockutil.nim index 1e8e05a8b..3b5fc267a 100644 --- a/tests/testblockutil.nim +++ b/tests/testblockutil.nim @@ -172,8 +172,6 @@ proc addTestBlock*( cfg, state, getStateField(state, slot) + 1, cache, info, flags).expect( "can advance 1") - debugComment "add consolidations support to addTestBlock" - let proposer_index = get_beacon_proposer_index( state, cache, getStateField(state, slot)).expect("valid proposer index") From 8c67a265d0b63156285fd1f45e9897f88f16accd Mon Sep 17 00:00:00 2001 From: tersec Date: Mon, 1 Jul 2024 14:07:30 +0000 Subject: [PATCH 32/68] bump nim-web3 to align WithdrawalRequestV1 with EIP-7002 and consensus spec (#6395) --- beacon_chain/el/el_manager.nim | 5 ++--- vendor/nim-web3 | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/beacon_chain/el/el_manager.nim b/beacon_chain/el/el_manager.nim index 85eab9dc5..e7bc1377f 100644 --- a/beacon_chain/el/el_manager.nim +++ b/beacon_chain/el/el_manager.nim @@ -513,8 +513,7 @@ func asConsensusType*(rpcExecutionPayload: ExecutionPayloadV4): template getWithdrawalRequest(wr: WithdrawalRequestV1): WithdrawalRequest = WithdrawalRequest( source_address: ExecutionAddress(data: wr.sourceAddress.distinctBase), - validator_pubkey: ValidatorPubKey( - blob: wr.validatorPublicKey.distinctBase), + validator_pubkey: ValidatorPubKey(blob: wr.validatorPubkey.distinctBase), amount: wr.amount.Gwei) template getConsolidationRequest(cr: ConsolidationRequestV1): @@ -667,7 +666,7 @@ func asEngineExecutionPayload*(executionPayload: electra.ExecutionPayload): template getWithdrawalRequest(wr: WithdrawalRequest): WithdrawalRequestV1 = WithdrawalRequestV1( sourceAddress: Address(wr.source_address.data), - validatorPublicKey: FixedBytes[RawPubKeySize](wr.validator_pubkey.blob), + validatorPubkey: FixedBytes[RawPubKeySize](wr.validator_pubkey.blob), amount: wr.amount.Quantity) template getConsolidationRequest(cr: ConsolidationRequest): diff --git a/vendor/nim-web3 b/vendor/nim-web3 index fc226d451..3ba859d8f 160000 --- a/vendor/nim-web3 +++ b/vendor/nim-web3 @@ -1 +1 @@ -Subproject commit fc226d4511199aa57a3fcd5cc44695c6b365a6bf +Subproject commit 3ba859d8f11bf71e96161741f99b55206425968f From 12a7ed8c29b035b4c98ed1556a2a2db1d0a56bc8 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 3 Jul 2024 03:40:17 +0200 Subject: [PATCH 33/68] bump geth to `v1.14.6` (#6400) - https://github.com/ethereum/go-ethereum/releases/tag/v1.14.6 --- scripts/geth_binaries.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/geth_binaries.sh b/scripts/geth_binaries.sh index abd112538..c8d406f14 100644 --- a/scripts/geth_binaries.sh +++ b/scripts/geth_binaries.sh @@ -21,7 +21,7 @@ source "${SCRIPTS_DIR}/bash_utils.sh" download_geth_stable() { if [[ ! -e "${STABLE_GETH_BINARY}" ]]; then - GETH_VERSION="1.14.5-0dd173a7" # https://geth.ethereum.org/downloads + GETH_VERSION="1.14.6-aadddf3a" # https://geth.ethereum.org/downloads GETH_URL="https://gethstore.blob.core.windows.net/builds/" case "${OS}-${ARCH}" in From 1fd246b23e66cee56fc0a5e0aa259143afa83c8e Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 3 Jul 2024 03:40:47 +0200 Subject: [PATCH 34/68] explicitly refer to attestation fork in SSZ consensus object tests (#6399) Use fully qualified types when referring to attestation related types in tests. We should also consider to merge these to a single runner. --- .../altair/test_fixture_operations.nim | 2 +- .../test_fixture_ssz_consensus_objects.nim | 11 +++++----- .../bellatrix/test_fixture_operations.nim | 6 ++--- .../test_fixture_ssz_consensus_objects.nim | 13 ++++++----- .../capella/test_fixture_operations.nim | 12 +++++----- .../test_fixture_ssz_consensus_objects.nim | 16 ++++++++------ .../deneb/test_fixture_operations.nim | 12 +++++----- .../test_fixture_ssz_consensus_objects.nim | 22 +++++++++++-------- .../electra/test_fixture_operations.nim | 2 +- .../test_fixture_ssz_consensus_objects.nim | 13 ++++++----- .../phase0/test_fixture_operations.nim | 2 +- .../test_fixture_ssz_consensus_objects.nim | 11 +++++----- 12 files changed, 67 insertions(+), 55 deletions(-) diff --git a/tests/consensus_spec/altair/test_fixture_operations.nim b/tests/consensus_spec/altair/test_fixture_operations.nim index 251bb3f29..8ca1b4f6c 100644 --- a/tests/consensus_spec/altair/test_fixture_operations.nim +++ b/tests/consensus_spec/altair/test_fixture_operations.nim @@ -173,4 +173,4 @@ suite baseDescription & "Voluntary Exit " & preset(): for path in walkTests(OpVoluntaryExitDir): runTest[SignedVoluntaryExit, typeof applyVoluntaryExit]( OpVoluntaryExitDir, suiteName, "Voluntary Exit", "voluntary_exit", - applyVoluntaryExit, path) \ No newline at end of file + applyVoluntaryExit, path) diff --git a/tests/consensus_spec/altair/test_fixture_ssz_consensus_objects.nim b/tests/consensus_spec/altair/test_fixture_ssz_consensus_objects.nim index 53a5643ce..86af9c1aa 100644 --- a/tests/consensus_spec/altair/test_fixture_ssz_consensus_objects.nim +++ b/tests/consensus_spec/altair/test_fixture_ssz_consensus_objects.nim @@ -108,10 +108,10 @@ suite "EF - Altair - SSZ consensus objects " & preset(): let hash = loadExpectedHashTreeRoot(path) case sszType: - of "AggregateAndProof": checkSSZ(AggregateAndProof, path, hash) - of "Attestation": checkSSZ(Attestation, path, hash) + of "AggregateAndProof": checkSSZ(phase0.AggregateAndProof, path, hash) + of "Attestation": checkSSZ(phase0.Attestation, path, hash) of "AttestationData": checkSSZ(AttestationData, path, hash) - of "AttesterSlashing": checkSSZ(AttesterSlashing, path, hash) + of "AttesterSlashing": checkSSZ(phase0.AttesterSlashing, path, hash) of "BeaconBlock": checkSSZ(altair.BeaconBlock, path, hash) of "BeaconBlockBody": checkSSZ(altair.BeaconBlockBody, path, hash) of "BeaconBlockHeader": checkSSZ(BeaconBlockHeader, path, hash) @@ -126,7 +126,8 @@ suite "EF - Altair - SSZ consensus objects " & preset(): 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 "IndexedAttestation": + checkSSZ(phase0.IndexedAttestation, path, hash) of "LightClientBootstrap": checkSSZ(altair.LightClientBootstrap, path, hash) of "LightClientHeader": @@ -140,7 +141,7 @@ suite "EF - Altair - SSZ consensus objects " & preset(): of "PendingAttestation": checkSSZ(PendingAttestation, path, hash) of "ProposerSlashing": checkSSZ(ProposerSlashing, path, hash) of "SignedAggregateAndProof": - checkSSZ(SignedAggregateAndProof, path, hash) + checkSSZ(phase0.SignedAggregateAndProof, path, hash) of "SignedBeaconBlock": checkSSZ(altair.SignedBeaconBlock, path, hash) of "SignedBeaconBlockHeader": checkSSZ(SignedBeaconBlockHeader, path, hash) diff --git a/tests/consensus_spec/bellatrix/test_fixture_operations.nim b/tests/consensus_spec/bellatrix/test_fixture_operations.nim index b24576037..7ec841519 100644 --- a/tests/consensus_spec/bellatrix/test_fixture_operations.nim +++ b/tests/consensus_spec/bellatrix/test_fixture_operations.nim @@ -75,7 +75,7 @@ proc runTest[T, U]( suite baseDescription & "Attestation " & preset(): proc applyAttestation( - preState: var bellatrix.BeaconState, attestation: Attestation): + preState: var bellatrix.BeaconState, attestation: phase0.Attestation): Result[void, cstring] = var cache: StateCache let @@ -90,7 +90,7 @@ suite baseDescription & "Attestation " & preset(): ok() for path in walkTests(OpAttestationsDir): - runTest[Attestation, typeof applyAttestation]( + runTest[phase0.Attestation, typeof applyAttestation]( OpAttestationsDir, suiteName, "Attestation", "attestation", applyAttestation, path) @@ -198,4 +198,4 @@ suite baseDescription & "Voluntary Exit " & preset(): for path in walkTests(OpVoluntaryExitDir): runTest[SignedVoluntaryExit, typeof applyVoluntaryExit]( OpVoluntaryExitDir, suiteName, "Voluntary Exit", "voluntary_exit", - applyVoluntaryExit, path) \ No newline at end of file + applyVoluntaryExit, path) diff --git a/tests/consensus_spec/bellatrix/test_fixture_ssz_consensus_objects.nim b/tests/consensus_spec/bellatrix/test_fixture_ssz_consensus_objects.nim index db028599a..27337b5fe 100644 --- a/tests/consensus_spec/bellatrix/test_fixture_ssz_consensus_objects.nim +++ b/tests/consensus_spec/bellatrix/test_fixture_ssz_consensus_objects.nim @@ -108,8 +108,8 @@ suite "EF - Bellatrix - SSZ consensus objects " & preset(): let hash = loadExpectedHashTreeRoot(path) case sszType: - of "AggregateAndProof": checkSSZ(AggregateAndProof, path, hash) - of "Attestation": checkSSZ(Attestation, path, hash) + of "AggregateAndProof": checkSSZ(phase0.AggregateAndProof, path, hash) + of "Attestation": checkSSZ(phase0.Attestation, path, hash) of "AttestationData": checkSSZ(AttestationData, path, hash) of "AttesterSlashing": checkSSZ(phase0.AttesterSlashing, path, hash) of "BeaconBlock": checkSSZ(bellatrix.BeaconBlock, path, hash) @@ -123,9 +123,10 @@ suite "EF - Bellatrix - SSZ consensus objects " & preset(): 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 "ExecutionPayload": + checkSSZ(bellatrix.ExecutionPayload, path, hash) of "ExecutionPayloadHeader": - checkSSZ(ExecutionPayloadHeader, path, hash) + checkSSZ(bellatrix.ExecutionPayloadHeader, path, hash) of "Fork": checkSSZ(Fork, path, hash) of "ForkData": checkSSZ(ForkData, path, hash) of "HistoricalBatch": checkSSZ(HistoricalBatch, path, hash) @@ -145,7 +146,7 @@ suite "EF - Bellatrix - SSZ consensus objects " & preset(): of "PowBlock": checkSSZ(PowBlock, path, hash) of "ProposerSlashing": checkSSZ(ProposerSlashing, path, hash) of "SignedAggregateAndProof": - checkSSZ(SignedAggregateAndProof, path, hash) + checkSSZ(phase0.SignedAggregateAndProof, path, hash) of "SignedBeaconBlock": checkSSZ(bellatrix.SignedBeaconBlock, path, hash) of "SignedBeaconBlockHeader": @@ -164,4 +165,4 @@ suite "EF - Bellatrix - SSZ consensus objects " & preset(): of "Validator": checkSSZ(Validator, path, hash) of "VoluntaryExit": checkSSZ(VoluntaryExit, path, hash) else: - raise newException(ValueError, "Unsupported test: " & sszType) \ No newline at end of file + raise newException(ValueError, "Unsupported test: " & sszType) diff --git a/tests/consensus_spec/capella/test_fixture_operations.nim b/tests/consensus_spec/capella/test_fixture_operations.nim index d1a67c6b3..22198cb46 100644 --- a/tests/consensus_spec/capella/test_fixture_operations.nim +++ b/tests/consensus_spec/capella/test_fixture_operations.nim @@ -79,7 +79,7 @@ proc runTest[T, U]( suite baseDescription & "Attestation " & preset(): proc applyAttestation( - preState: var capella.BeaconState, attestation: Attestation): + preState: var capella.BeaconState, attestation: phase0.Attestation): Result[void, cstring] = var cache: StateCache let @@ -94,14 +94,14 @@ suite baseDescription & "Attestation " & preset(): ok() for path in walkTests(OpAttestationsDir): - runTest[Attestation, typeof applyAttestation]( + runTest[phase0.Attestation, typeof applyAttestation]( OpAttestationsDir, suiteName, "Attestation", "attestation", applyAttestation, path) suite baseDescription & "Attester Slashing " & preset(): proc applyAttesterSlashing( - preState: var capella.BeaconState, attesterSlashing: AttesterSlashing): - Result[void, cstring] = + preState: var capella.BeaconState, + attesterSlashing: phase0.AttesterSlashing): Result[void, cstring] = var cache: StateCache doAssert (? process_attester_slashing( defaultRuntimeConfig, preState, attesterSlashing, {strictVerification}, @@ -109,7 +109,7 @@ suite baseDescription & "Attester Slashing " & preset(): ok() for path in walkTests(OpAttSlashingDir): - runTest[AttesterSlashing, typeof applyAttesterSlashing]( + runTest[phase0.AttesterSlashing, typeof applyAttesterSlashing]( OpAttSlashingDir, suiteName, "Attester Slashing", "attester_slashing", applyAttesterSlashing, path) @@ -226,4 +226,4 @@ suite baseDescription & "Withdrawals " & preset(): for path in walkTests(OpWithdrawalsDir): runTest[capella.ExecutionPayload, typeof applyWithdrawals]( OpWithdrawalsDir, suiteName, "Withdrawals", "execution_payload", - applyWithdrawals, path) \ No newline at end of file + applyWithdrawals, path) diff --git a/tests/consensus_spec/capella/test_fixture_ssz_consensus_objects.nim b/tests/consensus_spec/capella/test_fixture_ssz_consensus_objects.nim index 271fca416..b10951b59 100644 --- a/tests/consensus_spec/capella/test_fixture_ssz_consensus_objects.nim +++ b/tests/consensus_spec/capella/test_fixture_ssz_consensus_objects.nim @@ -110,10 +110,10 @@ suite "EF - Capella - SSZ consensus objects " & preset(): let hash = loadExpectedHashTreeRoot(path) case sszType: - of "AggregateAndProof": checkSSZ(AggregateAndProof, path, hash) - of "Attestation": checkSSZ(Attestation, path, hash) + of "AggregateAndProof": checkSSZ(phase0.AggregateAndProof, path, hash) + of "Attestation": checkSSZ(phase0.Attestation, path, hash) of "AttestationData": checkSSZ(AttestationData, path, hash) - of "AttesterSlashing": checkSSZ(AttesterSlashing, path, hash) + of "AttesterSlashing": checkSSZ(phase0.AttesterSlashing, path, hash) of "BeaconBlock": checkSSZ(capella.BeaconBlock, path, hash) of "BeaconBlockBody": checkSSZ(capella.BeaconBlockBody, path, hash) of "BeaconBlockHeader": checkSSZ(BeaconBlockHeader, path, hash) @@ -126,14 +126,16 @@ suite "EF - Capella - SSZ consensus objects " & preset(): 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 "ExecutionPayload": + checkSSZ(capella.ExecutionPayload, path, hash) of "ExecutionPayloadHeader": - checkSSZ(ExecutionPayloadHeader, path, hash) + checkSSZ(capella.ExecutionPayloadHeader, path, hash) of "Fork": checkSSZ(Fork, path, hash) of "ForkData": checkSSZ(ForkData, path, hash) of "HistoricalBatch": checkSSZ(HistoricalBatch, path, hash) of "HistoricalSummary": checkSSZ(HistoricalSummary, path, hash) - of "IndexedAttestation": checkSSZ(IndexedAttestation, path, hash) + of "IndexedAttestation": + checkSSZ(phase0.IndexedAttestation, path, hash) of "LightClientBootstrap": checkSSZ(capella.LightClientBootstrap, path, hash) of "LightClientHeader": @@ -148,7 +150,7 @@ suite "EF - Capella - SSZ consensus objects " & preset(): of "PowBlock": checkSSZ(PowBlock, path, hash) of "ProposerSlashing": checkSSZ(ProposerSlashing, path, hash) of "SignedAggregateAndProof": - checkSSZ(SignedAggregateAndProof, path, hash) + checkSSZ(phase0.SignedAggregateAndProof, path, hash) of "SignedBeaconBlock": checkSSZ(capella.SignedBeaconBlock, path, hash) of "SignedBeaconBlockHeader": diff --git a/tests/consensus_spec/deneb/test_fixture_operations.nim b/tests/consensus_spec/deneb/test_fixture_operations.nim index 86e1e8de1..78dad933b 100644 --- a/tests/consensus_spec/deneb/test_fixture_operations.nim +++ b/tests/consensus_spec/deneb/test_fixture_operations.nim @@ -79,7 +79,7 @@ proc runTest[T, U]( suite baseDescription & "Attestation " & preset(): proc applyAttestation( - preState: var deneb.BeaconState, attestation: Attestation): + preState: var deneb.BeaconState, attestation: phase0.Attestation): Result[void, cstring] = var cache: StateCache let @@ -94,14 +94,14 @@ suite baseDescription & "Attestation " & preset(): ok() for path in walkTests(OpAttestationsDir): - runTest[Attestation, typeof applyAttestation]( + runTest[phase0.Attestation, typeof applyAttestation]( OpAttestationsDir, suiteName, "Attestation", "attestation", applyAttestation, path) suite baseDescription & "Attester Slashing " & preset(): proc applyAttesterSlashing( - preState: var deneb.BeaconState, attesterSlashing: AttesterSlashing): - Result[void, cstring] = + preState: var deneb.BeaconState, + attesterSlashing: phase0.AttesterSlashing): Result[void, cstring] = var cache: StateCache doAssert (? process_attester_slashing( defaultRuntimeConfig, preState, attesterSlashing, {strictVerification}, @@ -109,7 +109,7 @@ suite baseDescription & "Attester Slashing " & preset(): ok() for path in walkTests(OpAttSlashingDir): - runTest[AttesterSlashing, typeof applyAttesterSlashing]( + runTest[phase0.AttesterSlashing, typeof applyAttesterSlashing]( OpAttSlashingDir, suiteName, "Attester Slashing", "attester_slashing", applyAttesterSlashing, path) @@ -228,4 +228,4 @@ suite baseDescription & "Withdrawals " & preset(): for path in walkTests(OpWithdrawalsDir): runTest[deneb.ExecutionPayload, typeof applyWithdrawals]( OpWithdrawalsDir, suiteName, "Withdrawals", "execution_payload", - applyWithdrawals, path) \ No newline at end of file + applyWithdrawals, path) diff --git a/tests/consensus_spec/deneb/test_fixture_ssz_consensus_objects.nim b/tests/consensus_spec/deneb/test_fixture_ssz_consensus_objects.nim index db561d215..f4637ba17 100644 --- a/tests/consensus_spec/deneb/test_fixture_ssz_consensus_objects.nim +++ b/tests/consensus_spec/deneb/test_fixture_ssz_consensus_objects.nim @@ -113,10 +113,10 @@ suite "EF - Deneb - SSZ consensus objects " & preset(): let hash = loadExpectedHashTreeRoot(path) case sszType: - of "AggregateAndProof": checkSSZ(AggregateAndProof, path, hash) - of "Attestation": checkSSZ(Attestation, path, hash) + of "AggregateAndProof": checkSSZ(phase0.AggregateAndProof, path, hash) + of "Attestation": checkSSZ(phase0.Attestation, path, hash) of "AttestationData": checkSSZ(AttestationData, path, hash) - of "AttesterSlashing": checkSSZ(AttesterSlashing, path, hash) + of "AttesterSlashing": checkSSZ(phase0.AttesterSlashing, path, hash) of "BeaconBlock": checkSSZ(deneb.BeaconBlock, path, hash) of "BeaconBlockBody": checkSSZ(deneb.BeaconBlockBody, path, hash) of "BeaconBlockHeader": checkSSZ(BeaconBlockHeader, path, hash) @@ -131,18 +131,22 @@ suite "EF - Deneb - SSZ consensus objects " & preset(): 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 "ExecutionPayload": + checkSSZ(deneb.ExecutionPayload, path, hash) of "ExecutionPayloadHeader": - checkSSZ(ExecutionPayloadHeader, path, hash) + checkSSZ(deneb.ExecutionPayloadHeader, path, hash) of "Fork": checkSSZ(Fork, path, hash) of "ForkData": checkSSZ(ForkData, path, hash) of "HistoricalBatch": checkSSZ(HistoricalBatch, path, hash) of "HistoricalSummary": checkSSZ(HistoricalSummary, path, hash) - of "IndexedAttestation": checkSSZ(IndexedAttestation, path, hash) + of "IndexedAttestation": + checkSSZ(phase0.IndexedAttestation, path, hash) of "LightClientBootstrap": checkSSZ(deneb.LightClientBootstrap, path, hash) - of "LightClientHeader": checkSSZ(deneb.LightClientHeader, path, hash) - of "LightClientUpdate": checkSSZ(deneb.LightClientUpdate, path, hash) + of "LightClientHeader": + checkSSZ(deneb.LightClientHeader, path, hash) + of "LightClientUpdate": + checkSSZ(deneb.LightClientUpdate, path, hash) of "LightClientFinalityUpdate": checkSSZ(deneb.LightClientFinalityUpdate, path, hash) of "LightClientOptimisticUpdate": @@ -151,7 +155,7 @@ suite "EF - Deneb - SSZ consensus objects " & preset(): of "PowBlock": checkSSZ(PowBlock, path, hash) of "ProposerSlashing": checkSSZ(ProposerSlashing, path, hash) of "SignedAggregateAndProof": - checkSSZ(SignedAggregateAndProof, path, hash) + checkSSZ(phase0.SignedAggregateAndProof, path, hash) of "SignedBeaconBlock": checkSSZ(deneb.SignedBeaconBlock, path, hash) of "SignedBeaconBlockHeader": diff --git a/tests/consensus_spec/electra/test_fixture_operations.nim b/tests/consensus_spec/electra/test_fixture_operations.nim index 0bf68ff77..d3974d56b 100644 --- a/tests/consensus_spec/electra/test_fixture_operations.nim +++ b/tests/consensus_spec/electra/test_fixture_operations.nim @@ -276,4 +276,4 @@ suite baseDescription & "Withdrawals " & preset(): for path in walkTests(OpWithdrawalsDir): runTest[electra.ExecutionPayload, typeof applyWithdrawals]( OpWithdrawalsDir, suiteName, "Withdrawals", "execution_payload", - applyWithdrawals, path) \ No newline at end of file + applyWithdrawals, path) diff --git a/tests/consensus_spec/electra/test_fixture_ssz_consensus_objects.nim b/tests/consensus_spec/electra/test_fixture_ssz_consensus_objects.nim index 816736052..dd5f32c4e 100644 --- a/tests/consensus_spec/electra/test_fixture_ssz_consensus_objects.nim +++ b/tests/consensus_spec/electra/test_fixture_ssz_consensus_objects.nim @@ -136,9 +136,10 @@ suite "EF - Electra - SSZ consensus objects " & preset(): of "DepositRequest": checkSSZ(DepositRequest, path, hash) of "Eth1Block": checkSSZ(Eth1Block, path, hash) of "Eth1Data": checkSSZ(Eth1Data, path, hash) - of "ExecutionPayload": checkSSZ(ExecutionPayload, path, hash) + of "ExecutionPayload": + checkSSZ(electra.ExecutionPayload, path, hash) of "ExecutionPayloadHeader": - checkSSZ(ExecutionPayloadHeader, path, hash) + checkSSZ(electra.ExecutionPayloadHeader, path, hash) of "Fork": checkSSZ(Fork, path, hash) of "ForkData": checkSSZ(ForkData, path, hash) of "HistoricalBatch": checkSSZ(HistoricalBatch, path, hash) @@ -146,8 +147,10 @@ suite "EF - Electra - SSZ consensus objects " & preset(): of "IndexedAttestation": checkSSZ(electra.IndexedAttestation, path, hash) of "LightClientBootstrap": checkSSZ(electra.LightClientBootstrap, path, hash) - of "LightClientHeader": checkSSZ(electra.LightClientHeader, path, hash) - of "LightClientUpdate": checkSSZ(electra.LightClientUpdate, path, hash) + of "LightClientHeader": + checkSSZ(electra.LightClientHeader, path, hash) + of "LightClientUpdate": + checkSSZ(electra.LightClientUpdate, path, hash) of "LightClientFinalityUpdate": checkSSZ(electra.LightClientFinalityUpdate, path, hash) of "LightClientOptimisticUpdate": @@ -184,4 +187,4 @@ suite "EF - Electra - SSZ consensus objects " & preset(): of "VoluntaryExit": checkSSZ(VoluntaryExit, path, hash) of "WithdrawalRequest": checkSSZ(WithdrawalRequest, path, hash) else: - raise newException(ValueError, "Unsupported test: " & sszType) \ No newline at end of file + raise newException(ValueError, "Unsupported test: " & sszType) diff --git a/tests/consensus_spec/phase0/test_fixture_operations.nim b/tests/consensus_spec/phase0/test_fixture_operations.nim index 532897711..42195af5a 100644 --- a/tests/consensus_spec/phase0/test_fixture_operations.nim +++ b/tests/consensus_spec/phase0/test_fixture_operations.nim @@ -150,4 +150,4 @@ suite baseDescription & "Voluntary Exit " & preset(): for path in walkTests(OpVoluntaryExitDir): runTest[SignedVoluntaryExit, typeof applyVoluntaryExit]( OpVoluntaryExitDir, suiteName, "Voluntary Exit", "voluntary_exit", - applyVoluntaryExit, path) \ No newline at end of file + applyVoluntaryExit, path) diff --git a/tests/consensus_spec/phase0/test_fixture_ssz_consensus_objects.nim b/tests/consensus_spec/phase0/test_fixture_ssz_consensus_objects.nim index b2282e0ea..8d395fac1 100644 --- a/tests/consensus_spec/phase0/test_fixture_ssz_consensus_objects.nim +++ b/tests/consensus_spec/phase0/test_fixture_ssz_consensus_objects.nim @@ -108,10 +108,10 @@ suite "EF - Phase 0 - SSZ consensus objects " & preset(): let hash = loadExpectedHashTreeRoot(path) case sszType: - of "AggregateAndProof": checkSSZ(AggregateAndProof, path, hash) - of "Attestation": checkSSZ(Attestation, path, hash) + of "AggregateAndProof": checkSSZ(phase0.AggregateAndProof, path, hash) + of "Attestation": checkSSZ(phase0.Attestation, path, hash) of "AttestationData": checkSSZ(AttestationData, path, hash) - of "AttesterSlashing": checkSSZ(AttesterSlashing, path, hash) + of "AttesterSlashing": checkSSZ(phase0.AttesterSlashing, path, hash) of "BeaconBlock": checkSSZ(phase0.BeaconBlock, path, hash) of "BeaconBlockBody": checkSSZ(phase0.BeaconBlockBody, path, hash) of "BeaconBlockHeader": checkSSZ(BeaconBlockHeader, path, hash) @@ -125,11 +125,12 @@ suite "EF - Phase 0 - SSZ consensus objects " & preset(): 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 "IndexedAttestation": + checkSSZ(phase0.IndexedAttestation, path, hash) of "PendingAttestation": checkSSZ(PendingAttestation, path, hash) of "ProposerSlashing": checkSSZ(ProposerSlashing, path, hash) of "SignedAggregateAndProof": - checkSSZ(SignedAggregateAndProof, path, hash) + checkSSZ(phase0.SignedAggregateAndProof, path, hash) of "SignedBeaconBlock": checkSSZ(phase0.SignedBeaconBlock, path, hash) of "SignedBeaconBlockHeader": checkSSZ(SignedBeaconBlockHeader, path, hash) From fba8cc3ee5a4c92457a57c4477b6b26fe13464bc Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 3 Jul 2024 03:41:01 +0200 Subject: [PATCH 35/68] fix EIP reference in Electra type definition (#6398) The field `withdrawal_requests` is from EIP-7002 instead of EIP-6110. --- beacon_chain/spec/datatypes/electra.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon_chain/spec/datatypes/electra.nim b/beacon_chain/spec/datatypes/electra.nim index 5f5091d40..9691916a4 100644 --- a/beacon_chain/spec/datatypes/electra.nim +++ b/beacon_chain/spec/datatypes/electra.nim @@ -115,7 +115,7 @@ type ## [New in Electra:EIP6110] withdrawal_requests*: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD] - ## [New in Electra:EIP6110] + ## [New in Electra:EIP7002:EIP7251] consolidation_requests*: List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD] ## [New in Electra:EIP7251] From 515bd486e62dcc0855b5f785fa96e8a0657da21c Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 3 Jul 2024 03:43:16 +0200 Subject: [PATCH 36/68] ensure passing unsigned integer to `rlp.encode` (#6397) RLP encoding is not defined for signed integers. Make sure to use unsigned integers when encoding RLP for EL block hash computation. --- beacon_chain/libnimbus_lc/libnimbus_lc.nim | 6 +++--- beacon_chain/spec/helpers.nim | 9 +++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/beacon_chain/libnimbus_lc/libnimbus_lc.nim b/beacon_chain/libnimbus_lc/libnimbus_lc.nim index 062f4b016..1e4fbc5fa 100644 --- a/beacon_chain/libnimbus_lc/libnimbus_lc.nim +++ b/beacon_chain/libnimbus_lc/libnimbus_lc.nim @@ -1322,7 +1322,7 @@ proc ETHExecutionBlockHeaderCreateFromJson( var tr = initHexaryTrie(newMemoryDB()) for i, wd in wds: try: - tr.put(rlp.encode(i), wd.bytes) + tr.put(rlp.encode(i.uint), wd.bytes) except RlpError: raiseAssert "Unreachable" if tr.rootHash() != data.withdrawalsRoot.get.asEth2Digest: @@ -1632,7 +1632,7 @@ proc ETHTransactionsCreateFromJson( var tr = initHexaryTrie(newMemoryDB()) for i, transaction in txs: try: - tr.put(rlp.encode(i), distinctBase(transaction.bytes)) + tr.put(rlp.encode(i.uint), distinctBase(transaction.bytes)) except RlpError: raiseAssert "Unreachable" if tr.rootHash() != transactionsRoot[]: @@ -2208,7 +2208,7 @@ proc ETHReceiptsCreateFromJson( var tr = initHexaryTrie(newMemoryDB()) for i, rec in recs: try: - tr.put(rlp.encode(i), rec.bytes) + tr.put(rlp.encode(i.uint), rec.bytes) except RlpError: raiseAssert "Unreachable" if tr.rootHash() != receiptsRoot[]: diff --git a/beacon_chain/spec/helpers.nim b/beacon_chain/spec/helpers.nim index 5c244eb72..a168a8ec7 100644 --- a/beacon_chain/spec/helpers.nim +++ b/beacon_chain/spec/helpers.nim @@ -445,9 +445,10 @@ proc computeTransactionsTrieRoot*( var tr = initHexaryTrie(newMemoryDB()) for i, transaction in payload.transactions: try: - tr.put(rlp.encode(i), distinctBase(transaction)) # Already RLP encoded + # Transactions are already RLP encoded + tr.put(rlp.encode(i.uint), distinctBase(transaction)) except RlpError as exc: - doAssert false, "HexaryTrie.put failed: " & $exc.msg + raiseAssert "HexaryTrie.put failed: " & $exc.msg tr.rootHash() func toExecutionWithdrawal*( @@ -468,9 +469,9 @@ proc computeWithdrawalsTrieRoot*( var tr = initHexaryTrie(newMemoryDB()) for i, withdrawal in payload.withdrawals: try: - tr.put(rlp.encode(i), rlp.encode(toExecutionWithdrawal(withdrawal))) + tr.put(rlp.encode(i.uint), rlp.encode(toExecutionWithdrawal(withdrawal))) except RlpError as exc: - doAssert false, "HexaryTrie.put failed: " & $exc.msg + raiseAssert "HexaryTrie.put failed: " & $exc.msg tr.rootHash() proc blockToBlockHeader*(blck: ForkyBeaconBlock): ExecutionBlockHeader = From e54b3e8fda892a538ec97b179a21166d77ce3a51 Mon Sep 17 00:00:00 2001 From: tersec Date: Wed, 3 Jul 2024 04:29:43 +0000 Subject: [PATCH 37/68] bump nimbus-build-system for Nim v2.0.8 (#6401) --- vendor/nimbus-build-system | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/nimbus-build-system b/vendor/nimbus-build-system index 09a356878..741274439 160000 --- a/vendor/nimbus-build-system +++ b/vendor/nimbus-build-system @@ -1 +1 @@ -Subproject commit 09a35687897041c152986f13473466fa55f987ca +Subproject commit 741274439ce72162ab3c740e7c0ef624d32725f9 From 84a35c85c5cb2aa2e0f6d186e88a23be17a7e0a9 Mon Sep 17 00:00:00 2001 From: Eugene Kabanov Date: Wed, 3 Jul 2024 13:01:33 +0300 Subject: [PATCH 38/68] Fix for gcc-14 issues in kzg-4844. (#6403) * Bump nim-kzg4844. * Fix code to use proper KZG types. * Add missing coma. * Fix compilation issue. * Bump nim-kzg4844. * Add debugging output. * Remove debugging output. * Restore groupBlobs function. --- beacon_chain/el/el_manager.nim | 12 ++++--- .../gossip_processing/block_processor.nim | 4 +-- .../gossip_processing/gossip_validation.nim | 2 +- beacon_chain/spec/datatypes/deneb.nim | 2 +- .../eth2_apis/eth2_rest_serialization.nim | 4 +-- beacon_chain/spec/state_transition_block.nim | 2 +- beacon_chain/validators/message_router.nim | 6 ++-- .../validators/message_router_mev.nim | 2 +- .../test_fixture_fork_choice.nim | 5 +-- tests/consensus_spec/test_fixture_kzg.nim | 32 ++++++++++++------- tests/test_rest_json_serialization.nim | 4 +-- vendor/nim-kzg4844 | 2 +- 12 files changed, 47 insertions(+), 30 deletions(-) diff --git a/beacon_chain/el/el_manager.nim b/beacon_chain/el/el_manager.nim index e7bc1377f..d9bff2662 100644 --- a/beacon_chain/el/el_manager.nim +++ b/beacon_chain/el/el_manager.nim @@ -491,9 +491,11 @@ func asConsensusType*(payload: engine_api.GetPayloadV3Response): # Both are defined as `array[N, byte]` under the hood. blobsBundle: deneb.BlobsBundle( commitments: KzgCommitments.init( - payload.blobsBundle.commitments.mapIt(it.bytes)), + payload.blobsBundle.commitments.mapIt( + kzg_abi.KzgCommitment(bytes: it.bytes))), proofs: KzgProofs.init( - payload.blobsBundle.proofs.mapIt(it.bytes)), + payload.blobsBundle.proofs.mapIt( + kzg_abi.KzgProof(bytes: it.bytes))), blobs: Blobs.init( payload.blobsBundle.blobs.mapIt(it.bytes)))) @@ -568,9 +570,11 @@ func asConsensusType*(payload: engine_api.GetPayloadV4Response): # Both are defined as `array[N, byte]` under the hood. blobsBundle: deneb.BlobsBundle( commitments: KzgCommitments.init( - payload.blobsBundle.commitments.mapIt(it.bytes)), + payload.blobsBundle.commitments.mapIt( + kzg_abi.KzgCommitment(bytes: it.bytes))), proofs: KzgProofs.init( - payload.blobsBundle.proofs.mapIt(it.bytes)), + payload.blobsBundle.proofs.mapIt( + kzg_abi.KzgProof(bytes: it.bytes))), blobs: Blobs.init( payload.blobsBundle.blobs.mapIt(it.bytes)))) diff --git a/beacon_chain/gossip_processing/block_processor.nim b/beacon_chain/gossip_processing/block_processor.nim index 37e1174be..a89023812 100644 --- a/beacon_chain/gossip_processing/block_processor.nim +++ b/beacon_chain/gossip_processing/block_processor.nim @@ -186,7 +186,7 @@ proc storeBackfillBlock( let blobs = blobsOpt.get() let kzgCommits = signedBlock.message.body.blob_kzg_commitments.asSeq if blobs.len > 0 or kzgCommits.len > 0: - let r = validate_blobs(kzgCommits, blobs.mapIt(it.blob), + let r = validate_blobs(kzgCommits, blobs.mapIt(KzgBlob(bytes: it.blob)), blobs.mapIt(it.kzg_proof)) if r.isErr(): debug "backfill blob validation failed", @@ -578,7 +578,7 @@ proc storeBlock( let blobs = blobsOpt.get() let kzgCommits = signedBlock.message.body.blob_kzg_commitments.asSeq if blobs.len > 0 or kzgCommits.len > 0: - let r = validate_blobs(kzgCommits, blobs.mapIt(it.blob), + let r = validate_blobs(kzgCommits, blobs.mapIt(KzgBlob(bytes: it.blob)), blobs.mapIt(it.kzg_proof)) if r.isErr(): debug "blob validation failed", diff --git a/beacon_chain/gossip_processing/gossip_validation.nim b/beacon_chain/gossip_processing/gossip_validation.nim index 9f8659488..8b417836f 100644 --- a/beacon_chain/gossip_processing/gossip_validation.nim +++ b/beacon_chain/gossip_processing/gossip_validation.nim @@ -458,7 +458,7 @@ proc validateBlobSidecar*( # blob_sidecar.blob, blob_sidecar.kzg_commitment, blob_sidecar.kzg_proof)`. block: let ok = verifyProof( - blob_sidecar.blob, + KzgBlob(bytes: blob_sidecar.blob), blob_sidecar.kzg_commitment, blob_sidecar.kzg_proof).valueOr: return dag.checkedReject("BlobSidecar: blob verify failed") diff --git a/beacon_chain/spec/datatypes/deneb.nim b/beacon_chain/spec/datatypes/deneb.nim index 722094948..d2b9ae24c 100644 --- a/beacon_chain/spec/datatypes/deneb.nim +++ b/beacon_chain/spec/datatypes/deneb.nim @@ -528,7 +528,7 @@ func initHashedBeaconState*(s: BeaconState): HashedBeaconState = HashedBeaconState(data: s) func shortLog*(v: KzgCommitment | KzgProof): auto = - to0xHex(v) + to0xHex(v.bytes) func shortLog*(v: Blob): auto = to0xHex(v.toOpenArray(0, 31)) diff --git a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim index d2a223f32..45b5e372b 100644 --- a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim +++ b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim @@ -1362,7 +1362,7 @@ proc readValue*(reader: var JsonReader[RestJson], value: var (KzgCommitment|KzgProof)) {. raises: [IOError, SerializationError].} = try: - hexToByteArray(reader.readValue(string), distinctBase(value)) + hexToByteArray(reader.readValue(string), distinctBase(value.bytes)) except ValueError: raiseUnexpectedValue(reader, "KzgCommitment value should be a valid hex string") @@ -1370,7 +1370,7 @@ proc readValue*(reader: var JsonReader[RestJson], proc writeValue*( writer: var JsonWriter[RestJson], value: KzgCommitment | KzgProof ) {.raises: [IOError].} = - writeValue(writer, hexOriginal(distinctBase(value))) + writeValue(writer, hexOriginal(distinctBase(value.bytes))) ## GraffitiBytes proc writeValue*( diff --git a/beacon_chain/spec/state_transition_block.nim b/beacon_chain/spec/state_transition_block.nim index e9ad6237e..eb8bd16b0 100644 --- a/beacon_chain/spec/state_transition_block.nim +++ b/beacon_chain/spec/state_transition_block.nim @@ -1085,7 +1085,7 @@ func kzg_commitment_to_versioned_hash*( var res: VersionedHash res[0] = VERSIONED_HASH_VERSION_KZG - res[1 .. 31] = eth2digest(kzg_commitment).data.toOpenArray(1, 31) + res[1 .. 31] = eth2digest(kzg_commitment.bytes).data.toOpenArray(1, 31) res proc validate_blobs*( diff --git a/beacon_chain/validators/message_router.nim b/beacon_chain/validators/message_router.nim index c70adb743..2ebd2e65a 100644 --- a/beacon_chain/validators/message_router.nim +++ b/beacon_chain/validators/message_router.nim @@ -117,8 +117,10 @@ proc routeSignedBeaconBlock*( let blobs = blobsOpt.get() let kzgCommits = blck.message.body.blob_kzg_commitments.asSeq if blobs.len > 0 or kzgCommits.len > 0: - let res = validate_blobs(kzgCommits, blobs.mapIt(it.blob), - blobs.mapIt(it.kzg_proof)) + let res = validate_blobs( + kzgCommits, + blobs.mapIt(KzgBlob(bytes: it.blob)), + blobs.mapIt(it.kzg_proof)) if res.isErr(): warn "blobs failed validation", blockRoot = shortLog(blck.root), diff --git a/beacon_chain/validators/message_router_mev.nim b/beacon_chain/validators/message_router_mev.nim index 7dad0b76d..049b956b4 100644 --- a/beacon_chain/validators/message_router_mev.nim +++ b/beacon_chain/validators/message_router_mev.nim @@ -129,7 +129,7 @@ proc unblindAndRouteBlockMEV*( bundle.data.blobs_bundle.commitments: return err("unblinded blobs bundle has unexpected commitments") let ok = verifyProofs( - asSeq blobs_bundle.blobs, + blobs_bundle.blobs.mapIt(KzgBlob(bytes: it)), asSeq blobs_bundle.commitments, asSeq blobs_bundle.proofs).valueOr: return err("unblinded blobs bundle fails verification") diff --git a/tests/consensus_spec/test_fixture_fork_choice.nim b/tests/consensus_spec/test_fixture_fork_choice.nim index 8334ef825..163996b8f 100644 --- a/tests/consensus_spec/test_fixture_fork_choice.nim +++ b/tests/consensus_spec/test_fixture_fork_choice.nim @@ -136,7 +136,8 @@ proc loadOps( blobs: distinctBase(parseTest( path/(step["blobs"].getStr()) & ".ssz_snappy", SSZ, List[KzgBlob, Limit MAX_BLOBS_PER_BLOCK])), - proofs: step["proofs"].mapIt(KzgProof.fromHex(it.getStr()))) + proofs: step["proofs"].mapIt( + KzgProof(bytes: fromHex(array[48, byte], it.getStr())))) else: Opt.none(BlobData) else: @@ -407,4 +408,4 @@ from ../../beacon_chain/conf import loadKzgTrustedSetup discard loadKzgTrustedSetup() # Required for Deneb tests fcSuite("ForkChoice", "fork_choice") -fcSuite("Sync", "sync") \ No newline at end of file +fcSuite("Sync", "sync") diff --git a/tests/consensus_spec/test_fixture_kzg.nim b/tests/consensus_spec/test_fixture_kzg.nim index 94a0610d9..8ce41b25c 100644 --- a/tests/consensus_spec/test_fixture_kzg.nim +++ b/tests/consensus_spec/test_fixture_kzg.nim @@ -50,12 +50,12 @@ proc runBlobToKzgCommitmentTest(suiteName, suitePath, path: string) = if blob.isNone: check output.kind == JNull else: - let commitment = blobToKzgCommitment(blob.get) + let commitment = blobToKzgCommitment(KzgBlob(bytes: blob.get)) check: if commitment.isErr: output.kind == JNull else: - commitment.get == fromHex[48](output.getStr).get + commitment.get().bytes == fromHex[48](output.getStr).get proc runVerifyKzgProofTest(suiteName, suitePath, path: string) = let relativePathComponent = path.relativeTestPathComponent(suitePath) @@ -75,7 +75,10 @@ proc runVerifyKzgProofTest(suiteName, suitePath, path: string) = if commitment.isNone or z.isNone or y.isNone or proof.isNone: check output.kind == JNull else: - let v = verifyProof(commitment.get, z.get, y.get, proof.get) + let v = verifyProof( + KzgCommitment(bytes: commitment.get), + KzgBytes32(bytes: z.get), KzgBytes32(bytes: y.get), + KzgBytes48(bytes: proof.get)) check: if v.isErr: output.kind == JNull @@ -100,7 +103,10 @@ proc runVerifyBlobKzgProofTest(suiteName, suitePath, path: string) = if blob.isNone or commitment.isNone or proof.isNone: check output.kind == JNull else: - let v = verifyBlobKzgProof(blob.get, commitment.get, proof.get) + let v = verifyBlobKzgProof( + KzgBlob(bytes: blob.get), + KzgBytes48(bytes: commitment.get), + KzgBytes48(bytes: proof.get)) check: if v.isErr: output.kind == JNull @@ -127,7 +133,9 @@ proc runVerifyBlobKzgProofBatchTest(suiteName, suitePath, path: string) = check output.kind == JNull else: let v = verifyBlobKzgProofBatch( - blobs.mapIt(it.get), commitments.mapIt(it.get), proofs.mapIt(it.get)) + blobs.mapIt(KzgBlob(bytes: it.get)), + commitments.mapIt(KzgCommitment(bytes: it.get)), + proofs.mapIt(KzgProof(bytes: it.get))) check: if v.isErr: output.kind == JNull @@ -150,7 +158,8 @@ proc runComputeKzgProofTest(suiteName, suitePath, path: string) = if blob.isNone or z.isNone: check output.kind == JNull else: - let p = computeKzgProof(blob.get, z.get) + let p = computeKzgProof( + KzgBlob(bytes: blob.get), KzgBytes32(bytes: z.get)) if p.isErr: check output.kind == JNull else: @@ -158,8 +167,8 @@ proc runComputeKzgProofTest(suiteName, suitePath, path: string) = proof = fromHex[48](output[0].getStr) y = fromHex[32](output[1].getStr) check: - p.get.proof == proof.get - p.get.y == y.get + p.get.proof.bytes == proof.get + p.get.y.bytes == y.get proc runComputeBlobKzgProofTest(suiteName, suitePath, path: string) = let relativePathComponent = path.relativeTestPathComponent(suitePath) @@ -177,11 +186,12 @@ proc runComputeBlobKzgProofTest(suiteName, suitePath, path: string) = if blob.isNone or commitment.isNone: check output.kind == JNull else: - let p = computeBlobKzgProof(blob.get, commitment.get) + let p = computeBlobKzgProof( + KzgBlob(bytes: blob.get), KzgBytes48(bytes: commitment.get)) if p.isErr: check output.kind == JNull else: - check p.get == fromHex[48](output.getStr).get + check p.get.bytes == fromHex[48](output.getStr).get from std/algorithm import sorted @@ -227,4 +237,4 @@ suite suiteName: for kind, path in walkDir(testsDir, relative = true, checkDir = true): runComputeBlobKzgProofTest(suiteName, testsDir, testsDir / path) -doAssert Kzg.freeTrustedSetup().isOk \ No newline at end of file +doAssert Kzg.freeTrustedSetup().isOk diff --git a/tests/test_rest_json_serialization.nim b/tests/test_rest_json_serialization.nim index ba0404f96..e3d2a7fe9 100644 --- a/tests/test_rest_json_serialization.nim +++ b/tests/test_rest_json_serialization.nim @@ -213,7 +213,7 @@ from stew/byteutils import hexToByteArray func fromHex(T: typedesc[KzgCommitment], s: string): T {. raises: [ValueError].} = var res: T - hexToByteArray(s, res) + hexToByteArray(s, res.bytes) res suite "REST JSON encoding and decoding": @@ -353,4 +353,4 @@ suite "REST JSON encoding and decoding": check: validator.pubkey == ValidatorPubKey.fromHex( "0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f7329267a8811c397529dac52ae1342ba58c95")[] - validator.exit_epoch == FAR_FUTURE_EPOCH \ No newline at end of file + validator.exit_epoch == FAR_FUTURE_EPOCH diff --git a/vendor/nim-kzg4844 b/vendor/nim-kzg4844 index f12616d06..2f5cee7be 160000 --- a/vendor/nim-kzg4844 +++ b/vendor/nim-kzg4844 @@ -1 +1 @@ -Subproject commit f12616d0675d9f6346141ca95f0840ab227eb213 +Subproject commit 2f5cee7bea0d62e2b502ff668f752bda7f3eb0c4 From cac63a3a8266c0deea46a99891bf577e9f524be4 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 3 Jul 2024 13:00:39 +0200 Subject: [PATCH 39/68] use `pull_request_target` to run PR block action (#6376) To avoid requiring authorization to run the PR block action for new contributors, use `pull_request_target`. Running the workflow file from the destination branch does not require approval. - https://stackoverflow.com/questions/74957218/what-is-the-difference-between-pull-request-and-pull-request-target-event-in-git --- .github/workflows/pr_block.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_block.yml b/.github/workflows/pr_block.yml index 0c71f51c8..c2abf9382 100644 --- a/.github/workflows/pr_block.yml +++ b/.github/workflows/pr_block.yml @@ -7,7 +7,7 @@ name: PR block on: - pull_request: + pull_request_target: branches: - stable From 14edccc962363de3786251677c13de3cbec57694 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 3 Jul 2024 23:48:47 +0200 Subject: [PATCH 40/68] bump nim-json-serialization to `89f7be1783b2f828a95dea1496fdac3510532997` (#6409) - update ci.yml and be more explicit in .nimble - extend automatic serialization support for `distinct` in Nim 2 --- vendor/nim-json-serialization | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/nim-json-serialization b/vendor/nim-json-serialization index 4d0b0662e..89f7be178 160000 --- a/vendor/nim-json-serialization +++ b/vendor/nim-json-serialization @@ -1 +1 @@ -Subproject commit 4d0b0662ed960ab2c5a1ddbd08f77048bac13ae7 +Subproject commit 89f7be1783b2f828a95dea1496fdac3510532997 From a725da20b86793fa08c3113a82579ab21ccbc081 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 3 Jul 2024 23:48:55 +0200 Subject: [PATCH 41/68] bump nim-confutils to `cb640db2cd66d7f4a1810a7df51b55f6f59cf3c5` (#6410) - update ci.yml and be more explicit in .nimble --- vendor/nim-confutils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/nim-confutils b/vendor/nim-confutils index 0adf3b7db..cb640db2c 160000 --- a/vendor/nim-confutils +++ b/vendor/nim-confutils @@ -1 +1 @@ -Subproject commit 0adf3b7db70736061bf12fa23c2fc51f395b289e +Subproject commit cb640db2cd66d7f4a1810a7df51b55f6f59cf3c5 From 858c66b4ba8081b24af9fa9bd0b89833b6372497 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 3 Jul 2024 23:49:03 +0200 Subject: [PATCH 42/68] bump nim-json-rpc to `8e1cdb18230f7e7172b4b4aa503b0d66fe530942` (#6411) - Add redefine pragma to inner template - update ci.yml and be more explicit in .nimble --- vendor/nim-json-rpc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/nim-json-rpc b/vendor/nim-json-rpc index ad8721e0f..8e1cdb182 160000 --- a/vendor/nim-json-rpc +++ b/vendor/nim-json-rpc @@ -1 +1 @@ -Subproject commit ad8721e0f3c6925597b5a93b6c53e040f26b5fb3 +Subproject commit 8e1cdb18230f7e7172b4b4aa503b0d66fe530942 From 814dcf595cf129bff87660acbe717d3d0a7df3de Mon Sep 17 00:00:00 2001 From: kevaundray Date: Wed, 3 Jul 2024 22:49:23 +0100 Subject: [PATCH 43/68] update copyright year (#6404) --- run-holesky-beacon-node.sh | 2 +- run-mainnet-beacon-node.sh | 2 +- run-sepolia-beacon-node.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/run-holesky-beacon-node.sh b/run-holesky-beacon-node.sh index 41c15cede..3d0686b1c 100755 --- a/run-holesky-beacon-node.sh +++ b/run-holesky-beacon-node.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2020-2023 Status Research & Development GmbH. Licensed under +# Copyright (c) 2020-2024 Status Research & Development GmbH. Licensed under # either of: # - Apache License, version 2.0 # - MIT license diff --git a/run-mainnet-beacon-node.sh b/run-mainnet-beacon-node.sh index cff7de916..3f4ca5a7f 100755 --- a/run-mainnet-beacon-node.sh +++ b/run-mainnet-beacon-node.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2020-2021 Status Research & Development GmbH. Licensed under +# Copyright (c) 2020-2024 Status Research & Development GmbH. Licensed under # either of: # - Apache License, version 2.0 # - MIT license diff --git a/run-sepolia-beacon-node.sh b/run-sepolia-beacon-node.sh index edd3d56f3..494809aa5 100755 --- a/run-sepolia-beacon-node.sh +++ b/run-sepolia-beacon-node.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2022 Status Research & Development GmbH. Licensed under +# Copyright (c) 2024 Status Research & Development GmbH. Licensed under # either of: # - Apache License, version 2.0 # - MIT license From 0dc2447a586e4e079bf7b0e15feeb4dddfcdcc00 Mon Sep 17 00:00:00 2001 From: tersec Date: Wed, 3 Jul 2024 22:06:10 +0000 Subject: [PATCH 44/68] omit frame pointer for secp256k1 (#6402) --- config.nims | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config.nims b/config.nims index ec1ce2b79..67f66927a 100644 --- a/config.nims +++ b/config.nims @@ -215,7 +215,8 @@ put("server.always", "-fno-lto") put("assembly.always", "-fno-lto") # Secp256k1 -put("secp256k1.always", "-fno-lto") +# -fomit-frame-pointer for https://github.com/status-im/nimbus-eth2/issues/6324 +put("secp256k1.always", "-fno-lto -fomit-frame-pointer") # BearSSL - only RNGs put("aesctr_drbg.always", "-fno-lto") From 85c28509714664b2b16c0d0d8594a9dafc4907d4 Mon Sep 17 00:00:00 2001 From: Eugene Kabanov Date: Thu, 4 Jul 2024 04:08:07 +0300 Subject: [PATCH 45/68] Fix publishBlockV1() and publishBlockV2() SSZ decoding process. (#6408) --- .../eth2_apis/eth2_rest_serialization.nim | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim index 45b5e372b..96da33953 100644 --- a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim +++ b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim @@ -3536,7 +3536,9 @@ proc decodeBody*( of ConsensusFork.Phase0: let blck = try: - SSZ.decode(body.data, phase0.SignedBeaconBlock) + var res = SSZ.decode(body.data, phase0.SignedBeaconBlock) + res.root = hash_tree_root(res.message) + res except SerializationError as exc: return err(RestErrorMessage.init(Http400, UnableDecodeError, [version, exc.formatMsg("")])) @@ -3548,7 +3550,9 @@ proc decodeBody*( of ConsensusFork.Altair: let blck = try: - SSZ.decode(body.data, altair.SignedBeaconBlock) + var res = SSZ.decode(body.data, altair.SignedBeaconBlock) + res.root = hash_tree_root(res.message) + res except SerializationError as exc: return err(RestErrorMessage.init(Http400, UnableDecodeError, [version, exc.formatMsg("")])) @@ -3560,7 +3564,9 @@ proc decodeBody*( of ConsensusFork.Bellatrix: let blck = try: - SSZ.decode(body.data, bellatrix.SignedBeaconBlock) + var res = SSZ.decode(body.data, bellatrix.SignedBeaconBlock) + res.root = hash_tree_root(res.message) + res except SerializationError as exc: return err(RestErrorMessage.init(Http400, UnableDecodeError, [version, exc.formatMsg("")])) @@ -3572,7 +3578,9 @@ proc decodeBody*( of ConsensusFork.Capella: let blck = try: - SSZ.decode(body.data, capella.SignedBeaconBlock) + var res = SSZ.decode(body.data, capella.SignedBeaconBlock) + res.root = hash_tree_root(res.message) + res except SerializationError as exc: return err(RestErrorMessage.init(Http400, UnableDecodeError, [version, exc.formatMsg("")])) @@ -3584,7 +3592,9 @@ proc decodeBody*( of ConsensusFork.Deneb: let blckContents = try: - SSZ.decode(body.data, DenebSignedBlockContents) + var res = SSZ.decode(body.data, DenebSignedBlockContents) + res.signed_block.root = hash_tree_root(res.signed_block.message) + res except SerializationError as exc: return err(RestErrorMessage.init(Http400, UnableDecodeError, [version, exc.formatMsg("")])) @@ -3596,7 +3606,9 @@ proc decodeBody*( of ConsensusFork.Electra: let blckContents = try: - SSZ.decode(body.data, ElectraSignedBlockContents) + var res = SSZ.decode(body.data, ElectraSignedBlockContents) + res.signed_block.root = hash_tree_root(res.signed_block.message) + res except SerializationError as exc: return err(RestErrorMessage.init(Http400, UnableDecodeError, [version, exc.formatMsg("")])) From 9f654690b88253ac6b9d81ec3e9dc71cd912279b Mon Sep 17 00:00:00 2001 From: tersec Date: Thu, 4 Jul 2024 12:08:07 +0000 Subject: [PATCH 46/68] update builder API registrations after keymanager API fee recipient change (#6412) --- beacon_chain/validators/beacon_validators.nim | 6 ++++-- beacon_chain/validators/keystore_management.nim | 14 +++++++++++--- beacon_chain/validators/validator_pool.nim | 9 +++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/beacon_chain/validators/beacon_validators.nim b/beacon_chain/validators/beacon_validators.nim index 7c99c28b7..8397b3ba7 100644 --- a/beacon_chain/validators/beacon_validators.nim +++ b/beacon_chain/validators/beacon_validators.nim @@ -1749,8 +1749,10 @@ proc registerValidatorsPerBuilder( validatorRegistrations.add @[validatorRegistration] # First, check for VC-added keys; cheaper because provided pre-signed - # See issue #5599: currently VC have no way to provide BN with per-validator builders per the specs, so we have to - # resort to use the BN fallback default (--payload-builder-url value, obtained by calling getPayloadBuilderAddress) + # See issue #5599: currently VC have no way to provide BN with per-validator + # builders per the specs, so we have to resort to use the BN fallback + # default (--payload-builder-url value, obtained by calling + # getPayloadBuilderAddress) var nonExitedVcPubkeys: HashSet[ValidatorPubKey] if node.externalBuilderRegistrations.len > 0 and payloadBuilderAddress == node.config.getPayloadBuilderAddress.value: diff --git a/beacon_chain/validators/keystore_management.nim b/beacon_chain/validators/keystore_management.nim index 243fed9d3..86ca1253d 100644 --- a/beacon_chain/validators/keystore_management.nim +++ b/beacon_chain/validators/keystore_management.nim @@ -1481,6 +1481,7 @@ proc removeFeeRecipientFile*(host: KeymanagerHost, if fileExists(path): io2.removeFile(path).isOkOr: return err($uint(error) & " " & ioErrorMsg(error)) + host.validatorPool[].invalidateValidatorRegistration(pubkey) ok() proc removeGasLimitFile*(host: KeymanagerHost, @@ -1499,15 +1500,22 @@ proc removeGraffitiFile*(host: KeymanagerHost, return err($uint(error) & " " & ioErrorMsg(error)) ok() -proc setFeeRecipient*(host: KeymanagerHost, pubkey: ValidatorPubKey, feeRecipient: Eth1Address): Result[void, string] = +proc setFeeRecipient*( + host: KeymanagerHost, pubkey: ValidatorPubKey, feeRecipient: Eth1Address): + Result[void, string] = let validatorKeystoreDir = host.validatorKeystoreDir(pubkey) - ? secureCreatePath(validatorKeystoreDir).mapErr(proc(e: auto): string = "Could not create wallet directory [" & validatorKeystoreDir & "]: " & $e) - io2.writeFile(validatorKeystoreDir / FeeRecipientFilename, $feeRecipient) + let res = io2.writeFile( + validatorKeystoreDir / FeeRecipientFilename, $feeRecipient) .mapErr(proc(e: auto): string = "Failed to write fee recipient file: " & $e) + if res.isOk: + host.validatorPool[].invalidateValidatorRegistration(pubkey) + + res + proc setGasLimit*(host: KeymanagerHost, pubkey: ValidatorPubKey, gasLimit: uint64): Result[void, string] = diff --git a/beacon_chain/validators/validator_pool.nim b/beacon_chain/validators/validator_pool.nim index 6d9ccab93..4e035efac 100644 --- a/beacon_chain/validators/validator_pool.nim +++ b/beacon_chain/validators/validator_pool.nim @@ -288,6 +288,15 @@ proc updateValidator*(pool: var ValidatorPool, validator.activationEpoch = activationEpoch +func invalidateValidatorRegistration*( + pool: var ValidatorPool, pubkey: ValidatorPubKey) = + # When the per-validator fee recipient changes via keymanager, the builder + # API validator registration needs to be recomputed. This will happen when + # next the registrations are sent, but ensure here that will happen rather + # than relying on a now-outdated, cached, validator registration. + pool.getValidator(pubkey).isErrOr: + value.externalBuilderRegistration.reset() + proc close*(pool: var ValidatorPool) = ## Unlock and close all validator keystore's files managed by ``pool``. for validator in pool.validators.values(): From abf818a9f30c823164dd852e7d4b9c0cc05b807b Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Thu, 4 Jul 2024 20:40:11 +0200 Subject: [PATCH 47/68] bump nim-eth to `d8fda55c79dd48ba564f3cb540b968f4a1c1aae6` (#6405) * bump nim-eth to `d8fda55c79dd48ba564f3cb540b968f4a1c1aae6` - Overhaul of ENR implementation - part I - Rework of ENR decoding code - Update discv5 to use non deprecated ENR calls and simplify code - simplify .nimble file - avoid warnings when processing `GasInt` for RLP - define Electra types and RLP encoding * explicitly indicate consensus types over nim-eth types in EL manager --- beacon_chain/el/el_manager.nim | 26 +++++++++++++++----------- vendor/nim-eth | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/beacon_chain/el/el_manager.nim b/beacon_chain/el/el_manager.nim index d9bff2662..6bac6f038 100644 --- a/beacon_chain/el/el_manager.nim +++ b/beacon_chain/el/el_manager.nim @@ -504,23 +504,25 @@ func asConsensusType*(rpcExecutionPayload: ExecutionPayloadV4): template getTransaction(tt: TypedTransaction): bellatrix.Transaction = bellatrix.Transaction.init(tt.distinctBase) - template getDepositRequest(dr: DepositRequestV1): DepositRequest = - DepositRequest( + template getDepositRequest( + dr: DepositRequestV1): electra.DepositRequest = + electra.DepositRequest( pubkey: ValidatorPubKey(blob: dr.pubkey.distinctBase), withdrawal_credentials: dr.withdrawalCredentials.asEth2Digest, amount: dr.amount.Gwei, signature: ValidatorSig(blob: dr.signature.distinctBase), index: dr.index.uint64) - template getWithdrawalRequest(wr: WithdrawalRequestV1): WithdrawalRequest = - WithdrawalRequest( + template getWithdrawalRequest( + wr: WithdrawalRequestV1): electra.WithdrawalRequest = + electra.WithdrawalRequest( source_address: ExecutionAddress(data: wr.sourceAddress.distinctBase), validator_pubkey: ValidatorPubKey(blob: wr.validatorPubkey.distinctBase), amount: wr.amount.Gwei) - template getConsolidationRequest(cr: ConsolidationRequestV1): - ConsolidationRequest = - ConsolidationRequest( + template getConsolidationRequest( + cr: ConsolidationRequestV1): electra.ConsolidationRequest = + electra.ConsolidationRequest( source_address: ExecutionAddress(data: cr.sourceAddress.distinctBase), source_pubkey: ValidatorPubKey(blob: cr.sourcePubkey.distinctBase), target_pubkey: ValidatorPubKey(blob: cr.targetPubkey.distinctBase)) @@ -659,7 +661,8 @@ func asEngineExecutionPayload*(executionPayload: electra.ExecutionPayload): template getTypedTransaction(tt: bellatrix.Transaction): TypedTransaction = TypedTransaction(tt.distinctBase) - template getDepositRequest(dr: DepositRequest): DepositRequestV1 = + template getDepositRequest( + dr: electra.DepositRequest): DepositRequestV1 = DepositRequestV1( pubkey: FixedBytes[RawPubKeySize](dr.pubkey.blob), withdrawalCredentials: FixedBytes[32](dr.withdrawal_credentials.data), @@ -667,14 +670,15 @@ func asEngineExecutionPayload*(executionPayload: electra.ExecutionPayload): signature: FixedBytes[RawSigSize](dr.signature.blob), index: dr.index.Quantity) - template getWithdrawalRequest(wr: WithdrawalRequest): WithdrawalRequestV1 = + template getWithdrawalRequest( + wr: electra.WithdrawalRequest): WithdrawalRequestV1 = WithdrawalRequestV1( sourceAddress: Address(wr.source_address.data), validatorPubkey: FixedBytes[RawPubKeySize](wr.validator_pubkey.blob), amount: wr.amount.Quantity) - template getConsolidationRequest(cr: ConsolidationRequest): - ConsolidationRequestV1 = + template getConsolidationRequest( + cr: electra.ConsolidationRequest): ConsolidationRequestV1 = ConsolidationRequestV1( sourceAddress: Address(cr.source_address.data), sourcePubkey: FixedBytes[RawPubKeySize](cr.source_pubkey.blob), diff --git a/vendor/nim-eth b/vendor/nim-eth index 26212c881..d8fda55c7 160000 --- a/vendor/nim-eth +++ b/vendor/nim-eth @@ -1 +1 @@ -Subproject commit 26212c881b464ed64cac20442fb45144d3ecd3b3 +Subproject commit d8fda55c79dd48ba564f3cb540b968f4a1c1aae6 From c59bb719166cbfb50500d045b3cef7de82dbac55 Mon Sep 17 00:00:00 2001 From: Eugene Kabanov Date: Thu, 4 Jul 2024 22:48:12 +0300 Subject: [PATCH 48/68] Add implementation of publishBlindedBlockV2() REST API endpoint. (#6413) --- beacon_chain/rpc/rest_beacon_api.nim | 83 ++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/beacon_chain/rpc/rest_beacon_api.nim b/beacon_chain/rpc/rest_beacon_api.nim index 29e77dc07..2808bf914 100644 --- a/beacon_chain/rpc/rest_beacon_api.nim +++ b/beacon_chain/rpc/rest_beacon_api.nim @@ -1106,6 +1106,89 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) = RestApiResponse.jsonMsgResponse(BlockValidationSuccess) + # https://ethereum.github.io/beacon-APIs/#/Beacon/publishBlindedBlockV2 + router.api(MethodPost, "/eth/v2/beacon/blinded_blocks") do ( + broadcast_validation: Option[BroadcastValidationType], + contentBody: Option[ContentBody]) -> RestApiResponse: + if contentBody.isNone(): + return RestApiResponse.jsonError(Http400, EmptyRequestBodyError) + + let + currentEpochFork = + node.dag.cfg.consensusForkAtEpoch(node.currentSlot().epoch()) + version = request.headers.getString("eth-consensus-version") + validation = + if broadcast_validation.isNone(): + BroadcastValidationType.Gossip + else: + let res = broadcast_validation.get().valueOr: + return RestApiResponse.jsonError(Http400, + InvalidBroadcastValidationType) + # TODO (cheatfate): support 'consensus' and + # 'consensus_and_equivocation' broadcast_validation types. + if res != BroadcastValidationType.Gossip: + return RestApiResponse.jsonError(Http500, + "Only `gossip` broadcast_validation option supported") + res + body = contentBody.get() + + if (body.contentType == OctetStreamMediaType) and + (currentEpochFork.toString != version): + return RestApiResponse.jsonError(Http400, BlockIncorrectFork) + + withConsensusFork(currentEpochFork): + # TODO (cheatfate): handle broadcast_validation flag + when consensusFork >= ConsensusFork.Deneb: + let + restBlock = decodeBodyJsonOrSsz( + consensusFork.SignedBlindedBeaconBlock, body).valueOr: + return RestApiResponse.jsonError(error) + payloadBuilderClient = node.getPayloadBuilderClient( + restBlock.message.proposer_index).valueOr: + return RestApiResponse.jsonError( + Http400, "Unable to initialize payload builder client: " & $error) + res = await node.unblindAndRouteBlockMEV( + payloadBuilderClient, restBlock) + + if res.isErr(): + return RestApiResponse.jsonError( + Http500, InternalServerError, $res.error) + if res.get().isNone(): + return RestApiResponse.jsonError(Http202, BlockValidationError) + + return RestApiResponse.jsonMsgResponse(BlockValidationSuccess) + elif consensusFork >= ConsensusFork.Bellatrix: + return RestApiResponse.jsonError( + Http400, $consensusFork & " builder API unsupported") + else: + # Pre-Bellatrix, this endpoint will accept a `SignedBeaconBlock`. + # + # This is mostly the same as /eth/v1/beacon/blocks for phase 0 and + # altair. + var + restBlock = decodeBody( + RestPublishedSignedBeaconBlock, body, version).valueOr: + return RestApiResponse.jsonError(error) + forked = ForkedSignedBeaconBlock(restBlock) + + if forked.kind != node.dag.cfg.consensusForkAtEpoch( + getForkedBlockField(forked, slot).epoch): + return RestApiResponse.jsonError(Http400, InvalidBlockObjectError) + + let res = withBlck(forked): + forkyBlck.root = hash_tree_root(forkyBlck.message) + await node.router.routeSignedBeaconBlock( + forkyBlck, Opt.none(seq[BlobSidecar]), + checkValidator = true) + + if res.isErr(): + return RestApiResponse.jsonError( + Http503, BeaconNodeInSyncError, $res.error) + elif res.get().isNone(): + return RestApiResponse.jsonError(Http202, BlockValidationError) + + RestApiResponse.jsonMsgResponse(BlockValidationSuccess) + # https://ethereum.github.io/beacon-APIs/#/Beacon/getBlock router.api2(MethodGet, "/eth/v1/beacon/blocks/{block_id}") do ( block_id: BlockIdent) -> RestApiResponse: From 7f59e80aaa5c751c92ea8424e23c70abbd4f2324 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Fri, 5 Jul 2024 10:18:50 +0200 Subject: [PATCH 49/68] validate EL block hash in Electra when no EL is connected (#6407) When no EL is connected, it is still required to validate the block hash of `ExecutionPayload` to prevent attacks that trick us into attesting to a circular chain with invalid in-between block hashes. This is already done through Deneb but was still missing in Electra to be rectified now. --- .../gossip_processing/block_processor.nim | 3 +- beacon_chain/spec/helpers.nim | 79 ++++++++++++++++++- 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/beacon_chain/gossip_processing/block_processor.nim b/beacon_chain/gossip_processing/block_processor.nim index a89023812..15c0ffeaf 100644 --- a/beacon_chain/gossip_processing/block_processor.nim +++ b/beacon_chain/gossip_processing/block_processor.nim @@ -555,8 +555,7 @@ proc storeBlock( # This should simulate an unsynced EL, which still must perform these # checks. This means it must be able to do so without context, beyond # whatever data the block itself contains. - when typeof(signedBlock).kind >= ConsensusFork.Bellatrix and typeof(signedBlock).kind <= ConsensusFork.Deneb: - debugComment "electra can do this in principle" + when typeof(signedBlock).kind >= ConsensusFork.Bellatrix: template payload(): auto = signedBlock.message.body.execution_payload if signedBlock.message.is_execution_block and payload.block_hash != diff --git a/beacon_chain/spec/helpers.nim b/beacon_chain/spec/helpers.nim index a168a8ec7..db86ab3f2 100644 --- a/beacon_chain/spec/helpers.nim +++ b/beacon_chain/spec/helpers.nim @@ -39,6 +39,9 @@ type ExecutionTransaction* = eth_types.Transaction ExecutionReceipt* = eth_types.Receipt ExecutionWithdrawal* = eth_types.Withdrawal + ExecutionDepositRequest* = eth_types.DepositRequest + ExecutionWithdrawalRequest* = eth_types.WithdrawalRequest + ExecutionConsolidationRequest* = eth_types.ConsolidationRequest ExecutionBlockHeader* = eth_types.BlockHeader FinalityCheckpoints* = object @@ -474,6 +477,74 @@ proc computeWithdrawalsTrieRoot*( raiseAssert "HexaryTrie.put failed: " & $exc.msg tr.rootHash() +func toExecutionDepositRequest*( + request: electra.DepositRequest): ExecutionDepositRequest = + ExecutionDepositRequest( + pubkey: request.pubkey.blob, + withdrawalCredentials: request.withdrawal_credentials.data, + amount: distinctBase(request.amount), + signature: request.signature.blob, + index: request.index) + +func toExecutionWithdrawalRequest*( + request: electra.WithdrawalRequest): ExecutionWithdrawalRequest = + ExecutionWithdrawalRequest( + sourceAddress: request.source_address.data, + validatorPubkey: request.validator_pubkey.blob, + amount: distinctBase(request.amount)) + +func toExecutionConsolidationRequest*( + request: electra.ConsolidationRequest): ExecutionConsolidationRequest = + ExecutionConsolidationRequest( + sourceAddress: request.source_address.data, + sourcePubkey: request.source_pubkey.blob, + targetPubkey: request.target_pubkey.blob) + +# https://eips.ethereum.org/EIPS/eip-7685 +proc computeRequestsTrieRoot*( + payload: electra.ExecutionPayload): ExecutionHash256 = + if payload.deposit_requests.len == 0 and + payload.withdrawal_requests.len == 0 and + payload.consolidation_requests.len == 0: + return EMPTY_ROOT_HASH + + var + tr = initHexaryTrie(newMemoryDB()) + i = 0'u64 + + static: + doAssert DEPOSIT_REQUEST_TYPE < WITHDRAWAL_REQUEST_TYPE + doAssert WITHDRAWAL_REQUEST_TYPE < CONSOLIDATION_REQUEST_TYPE + + # EIP-6110 + for request in payload.deposit_requests: + try: + tr.put(rlp.encode(i.uint), rlp.encode( + toExecutionDepositRequest(request))) + except RlpError as exc: + raiseAssert "HexaryTree.put failed: " & $exc.msg + inc i + + # EIP-7002 + for request in payload.withdrawal_requests: + try: + tr.put(rlp.encode(i.uint), rlp.encode( + toExecutionWithdrawalRequest(request))) + except RlpError as exc: + raiseAssert "HexaryTree.put failed: " & $exc.msg + inc i + + # EIP-7251 + for request in payload.consolidation_requests: + try: + tr.put(rlp.encode(i.uint), rlp.encode( + toExecutionConsolidationRequest(request))) + except RlpError as exc: + raiseAssert "HexaryTree.put failed: " & $exc.msg + inc i + + tr.rootHash() + proc blockToBlockHeader*(blck: ForkyBeaconBlock): ExecutionBlockHeader = template payload: auto = blck.body.execution_payload @@ -503,6 +574,11 @@ proc blockToBlockHeader*(blck: ForkyBeaconBlock): ExecutionBlockHeader = Opt.some ExecutionHash256(data: blck.parent_root.data) else: Opt.none(ExecutionHash256) + requestsRoot = + when typeof(payload).kind >= ConsensusFork.Electra: + Opt.some payload.computeRequestsTrieRoot() + else: + Opt.none(ExecutionHash256) ExecutionBlockHeader( parentHash : payload.parent_hash, @@ -524,7 +600,8 @@ proc blockToBlockHeader*(blck: ForkyBeaconBlock): ExecutionBlockHeader = withdrawalsRoot : withdrawalsRoot, blobGasUsed : blobGasUsed, # EIP-4844 excessBlobGas : excessBlobGas, # EIP-4844 - parentBeaconBlockRoot : parentBeaconBlockRoot) # EIP-4788 + parentBeaconBlockRoot : parentBeaconBlockRoot, # EIP-4788 + requestsRoot : requestsRoot) # EIP-7685 proc compute_execution_block_hash*(blck: ForkyBeaconBlock): Eth2Digest = rlpHash blockToBlockHeader(blck) From 0b276315d27c63a10c1fe4bd9723d1b19a3d508b Mon Sep 17 00:00:00 2001 From: andri lim Date: Sun, 7 Jul 2024 03:25:31 +0700 Subject: [PATCH 50/68] Bump nim-eth: Convert GasInt to uint64 (#6415) * Bump nim-eth: Convert GasInt to uint64 * Fixes * Fix libnimbus_lc --- beacon_chain/libnimbus_lc/libnimbus_lc.nim | 29 ++++++---------------- beacon_chain/spec/helpers.nim | 6 ++--- tests/testblockutil.nim | 6 ++--- vendor/nim-eth | 2 +- 4 files changed, 14 insertions(+), 29 deletions(-) diff --git a/beacon_chain/libnimbus_lc/libnimbus_lc.nim b/beacon_chain/libnimbus_lc/libnimbus_lc.nim index 1e4fbc5fa..71d266d04 100644 --- a/beacon_chain/libnimbus_lc/libnimbus_lc.nim +++ b/beacon_chain/libnimbus_lc/libnimbus_lc.nim @@ -9,7 +9,6 @@ import std/[json, sequtils, times], - stew/saturation_arith, eth/common/[eth_types_rlp, transaction], eth/keys, eth/p2p/discoveryv5/random2, @@ -1242,10 +1241,8 @@ proc ETHExecutionBlockHeaderCreateFromJson( # Construct block header static: # `GasInt` is signed. We only use it for hashing. - doAssert sizeof(int64) == sizeof(data.gasLimit) - doAssert sizeof(int64) == sizeof(data.gasUsed) - if distinctBase(data.timestamp) > int64.high.uint64: - return nil + doAssert sizeof(uint64) == sizeof(data.gasLimit) + doAssert sizeof(uint64) == sizeof(data.gasUsed) if data.nonce.isNone: return nil let blockHeader = ExecutionBlockHeader( @@ -1258,8 +1255,8 @@ proc ETHExecutionBlockHeaderCreateFromJson( logsBloom: distinctBase(data.logsBloom), difficulty: data.difficulty, number: distinctBase(data.number), - gasLimit: GasInt.saturate distinctBase(data.gasLimit), - gasUsed: GasInt.saturate distinctBase(data.gasUsed), + gasLimit: distinctBase(data.gasLimit), + gasUsed: distinctBase(data.gasUsed), timestamp: EthTime(distinctBase(data.timestamp)), extraData: distinctBase(data.extraData), mixHash: data.mixHash.asEth2Digest, @@ -1497,25 +1494,15 @@ proc ETHTransactionsCreateFromJson( # Construct transaction static: doAssert sizeof(uint64) == sizeof(ChainId) - doAssert sizeof(int64) == sizeof(data.gasPrice) - doAssert sizeof(int64) == sizeof(data.maxPriorityFeePerGas.get) + doAssert sizeof(uint64) == sizeof(data.gas) + doAssert sizeof(uint64) == sizeof(data.gasPrice) + doAssert sizeof(uint64) == sizeof(data.maxPriorityFeePerGas.get) doAssert sizeof(UInt256) == sizeof(data.maxFeePerBlobGas.get) if distinctBase(data.chainId.get(0.Quantity)) > distinctBase(ChainId.high): return nil - if distinctBase(data.gasPrice) > int64.high.uint64: - return nil - if distinctBase(data.maxFeePerGas.get(0.Quantity)) > int64.high.uint64: - return nil - if distinctBase(data.maxPriorityFeePerGas.get(0.Quantity)) > - int64.high.uint64: - return nil if data.maxFeePerBlobGas.get(0.u256) > uint64.high.u256: return nil - if distinctBase(data.gas) > int64.high.uint64: - return nil - if distinctBase(data.v) > int64.high.uint64: - return nil if data.yParity.isSome: # This is not always included, but if it is, make sure it's correct let yParity = data.yParity.get @@ -1555,7 +1542,7 @@ proc ETHTransactionsCreateFromJson( ExecutionHash256(data: distinctBase(it))) else: @[], - V: data.v.uint64, + V: distinctBase(data.v), R: data.r, S: data.s) rlpBytes = diff --git a/beacon_chain/spec/helpers.nim b/beacon_chain/spec/helpers.nim index db86ab3f2..63d54a9d6 100644 --- a/beacon_chain/spec/helpers.nim +++ b/beacon_chain/spec/helpers.nim @@ -11,7 +11,7 @@ import # Status libraries - stew/[byteutils, endians2, objects, saturation_arith], + stew/[byteutils, endians2, objects], chronicles, eth/common/[eth_types, eth_types_rlp], eth/rlp, eth/trie/[db, hexary], @@ -590,8 +590,8 @@ proc blockToBlockHeader*(blck: ForkyBeaconBlock): ExecutionBlockHeader = logsBloom : payload.logs_bloom.data, difficulty : default(DifficultyInt), number : payload.block_number, - gasLimit : GasInt.saturate(payload.gas_limit), - gasUsed : GasInt.saturate(payload.gas_used), + gasLimit : payload.gas_limit, + gasUsed : payload.gas_used, timestamp : EthTime(payload.timestamp), extraData : payload.extra_data.asSeq, mixHash : payload.prev_randao, # EIP-4399 `mixHash` -> `prevRandao` diff --git a/tests/testblockutil.nim b/tests/testblockutil.nim index 3b5fc267a..c541a3396 100644 --- a/tests/testblockutil.nim +++ b/tests/testblockutil.nim @@ -118,8 +118,6 @@ proc build_empty_merge_execution_payload(state: bellatrix.BeaconState): bellatrix.ExecutionPayloadForSigning(executionPayload: payload, blockValue: Wei.zero) -from stew/saturating_arith import saturate - proc build_empty_execution_payload( state: bellatrix.BeaconState, feeRecipient: Eth1Address): bellatrix.ExecutionPayloadForSigning = @@ -129,8 +127,8 @@ proc build_empty_execution_payload( latest = state.latest_execution_payload_header timestamp = compute_timestamp_at_slot(state, state.slot) randao_mix = get_randao_mix(state, get_current_epoch(state)) - base_fee = calcEip1599BaseFee(GasInt.saturate latest.gas_limit, - GasInt.saturate latest.gas_used, + base_fee = calcEip1599BaseFee(latest.gas_limit, + latest.gas_used, latest.base_fee_per_gas) var payload = bellatrix.ExecutionPayloadForSigning( diff --git a/vendor/nim-eth b/vendor/nim-eth index d8fda55c7..ebfe63b9b 160000 --- a/vendor/nim-eth +++ b/vendor/nim-eth @@ -1 +1 @@ -Subproject commit d8fda55c79dd48ba564f3cb540b968f4a1c1aae6 +Subproject commit ebfe63b9b6523a1823e4505f0972d81047a77cf5 From 3f051e9ab02a4e1d24ceacabb464ddeb68ac0fe5 Mon Sep 17 00:00:00 2001 From: Jhett Black <10942655+jhett12321@users.noreply.github.com> Date: Sat, 6 Jul 2024 23:07:56 +0200 Subject: [PATCH 51/68] Add beacon node count metrics. (#6371) --- beacon_chain/nimbus_validator_client.nim | 33 +++++++++++++++--------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/beacon_chain/nimbus_validator_client.nim b/beacon_chain/nimbus_validator_client.nim index a81cd054e..35a5c9f7b 100644 --- a/beacon_chain/nimbus_validator_client.nim +++ b/beacon_chain/nimbus_validator_client.nim @@ -17,6 +17,10 @@ import const PREGENESIS_EPOCHS_COUNT = 1 +declareGauge validator_client_node_counts, + "Number of connected beacon nodes and their status", + labels = ["status"] + proc initGenesis(vc: ValidatorClientRef): Future[RestGenesis] {.async.} = info "Initializing genesis", nodes_count = len(vc.beaconNodes) var nodes = vc.beaconNodes @@ -214,19 +218,24 @@ proc runVCSlotLoop(vc: ValidatorClientRef) {.async.} = vc.processingDelay = Opt.some(nanoseconds(delay.nanoseconds)) + let + counts = vc.getNodeCounts() + # Good nodes are nodes which can be used for ALL the requests. + goodNodes = counts.data[int(RestBeaconNodeStatus.Synced)] + # Viable nodes are nodes which can be used only SOME of the requests. + viableNodes = counts.data[int(RestBeaconNodeStatus.OptSynced)] + + counts.data[int(RestBeaconNodeStatus.NotSynced)] + + counts.data[int(RestBeaconNodeStatus.Compatible)] + # Bad nodes are nodes which can't be used at all. + badNodes = counts.data[int(RestBeaconNodeStatus.Offline)] + + counts.data[int(RestBeaconNodeStatus.Online)] + + counts.data[int(RestBeaconNodeStatus.Incompatible)] + + validator_client_node_counts.set(int64(goodNodes), ["good"]) + validator_client_node_counts.set(int64(viableNodes), ["viable"]) + validator_client_node_counts.set(int64(badNodes), ["bad"]) + if len(vc.beaconNodes) > 1: - let - counts = vc.getNodeCounts() - # Good nodes are nodes which can be used for ALL the requests. - goodNodes = counts.data[int(RestBeaconNodeStatus.Synced)] - # Viable nodes are nodes which can be used only SOME of the requests. - viableNodes = counts.data[int(RestBeaconNodeStatus.OptSynced)] + - counts.data[int(RestBeaconNodeStatus.NotSynced)] + - counts.data[int(RestBeaconNodeStatus.Compatible)] - # Bad nodes are nodes which can't be used at all. - badNodes = counts.data[int(RestBeaconNodeStatus.Offline)] + - counts.data[int(RestBeaconNodeStatus.Online)] + - counts.data[int(RestBeaconNodeStatus.Incompatible)] info "Slot start", slot = shortLog(wallSlot), epoch = shortLog(wallSlot.epoch()), From 3db571d182d7d096fa82ffeae98b659a159a9a2d Mon Sep 17 00:00:00 2001 From: tersec Date: Sat, 6 Jul 2024 22:32:50 +0000 Subject: [PATCH 52/68] allow individual calculation of validator balances across epoch boundaries (#6416) --- beacon_chain/networking/network_metadata.nim | 2 +- beacon_chain/spec/state_transition_epoch.nim | 175 +++++++++++++++++- .../test_fixture_state_transition_epoch.nim | 6 +- .../test_fixture_state_transition_epoch.nim | 6 +- .../test_fixture_sanity_blocks.nim | 6 +- tests/teststateutil.nim | 20 +- 6 files changed, 202 insertions(+), 13 deletions(-) diff --git a/beacon_chain/networking/network_metadata.nim b/beacon_chain/networking/network_metadata.nim index c7c0c27d7..d49535a17 100644 --- a/beacon_chain/networking/network_metadata.nim +++ b/beacon_chain/networking/network_metadata.nim @@ -343,7 +343,7 @@ proc getMetadataForNetwork*(networkName: string): Eth2NetworkMetadata = quit 1 if networkName in ["goerli", "prater"]: - warn "Goerli is deprecated and will stop being supported; https://blog.ethereum.org/2023/11/30/goerli-lts-update suggests migrating to Holesky or Sepolia" + warn "Goerli is deprecated and unsupported; https://blog.ethereum.org/2023/11/30/goerli-lts-update suggests migrating to Holesky or Sepolia" let metadata = when const_preset == "gnosis": diff --git a/beacon_chain/spec/state_transition_epoch.nim b/beacon_chain/spec/state_transition_epoch.nim index ddcd62653..9efc7b09e 100644 --- a/beacon_chain/spec/state_transition_epoch.nim +++ b/beacon_chain/spec/state_transition_epoch.nim @@ -707,13 +707,11 @@ template get_flag_and_inactivity_delta( state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState | electra.BeaconState, base_reward_per_increment: Gwei, finality_delay: uint64, - previous_epoch: Epoch, - active_increments: uint64, + previous_epoch: Epoch, active_increments: uint64, penalty_denominator: uint64, epoch_participation: ptr EpochParticipationFlags, - participating_increments: array[3, uint64], - info: var altair.EpochInfo, - vidx: ValidatorIndex + participating_increments: array[3, uint64], info: var altair.EpochInfo, + vidx: ValidatorIndex, inactivity_score: uint64 ): (ValidatorIndex, Gwei, Gwei, Gwei, Gwei, Gwei, Gwei) = let base_reward = get_base_reward_increment(state, vidx, base_reward_per_increment) @@ -751,7 +749,7 @@ template get_flag_and_inactivity_delta( 0.Gwei else: let penalty_numerator = - state.validators[vidx].effective_balance * state.inactivity_scores[vidx] + state.validators[vidx].effective_balance * inactivity_score penalty_numerator div penalty_denominator (vidx, reward(TIMELY_SOURCE_FLAG_INDEX), @@ -804,7 +802,46 @@ iterator get_flag_and_inactivity_deltas*( yield get_flag_and_inactivity_delta( state, base_reward_per_increment, finality_delay, previous_epoch, active_increments, penalty_denominator, epoch_participation, - participating_increments, info, vidx) + participating_increments, info, vidx, state.inactivity_scores[vidx]) + +func get_flag_and_inactivity_delta_for_validator( + cfg: RuntimeConfig, + state: deneb.BeaconState | electra.BeaconState, + base_reward_per_increment: Gwei, info: var altair.EpochInfo, + finality_delay: uint64, vidx: ValidatorIndex, inactivity_score: Gwei): + Opt[(ValidatorIndex, Gwei, Gwei, Gwei, Gwei, Gwei, Gwei)] = + ## Return the deltas for a given ``flag_index`` by scanning through the + ## participation flags. + const INACTIVITY_PENALTY_QUOTIENT = + when state is altair.BeaconState: + INACTIVITY_PENALTY_QUOTIENT_ALTAIR + else: + INACTIVITY_PENALTY_QUOTIENT_BELLATRIX + + static: doAssert ord(high(TimelyFlag)) == 2 + + let + previous_epoch = get_previous_epoch(state) + active_increments = get_active_increments(info) + penalty_denominator = + cfg.INACTIVITY_SCORE_BIAS * INACTIVITY_PENALTY_QUOTIENT + epoch_participation = + if previous_epoch == get_current_epoch(state): + unsafeAddr state.current_epoch_participation + else: + unsafeAddr state.previous_epoch_participation + participating_increments = [ + get_unslashed_participating_increment(info, TIMELY_SOURCE_FLAG_INDEX), + get_unslashed_participating_increment(info, TIMELY_TARGET_FLAG_INDEX), + get_unslashed_participating_increment(info, TIMELY_HEAD_FLAG_INDEX)] + + if not is_eligible_validator(info.validators[vidx]): + return Opt.none((ValidatorIndex, Gwei, Gwei, Gwei, Gwei, Gwei, Gwei)) + + Opt.some get_flag_and_inactivity_delta( + state, base_reward_per_increment, finality_delay, previous_epoch, + active_increments, penalty_denominator, epoch_participation, + participating_increments, info, vidx, inactivity_score.uint64) # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#rewards-and-penalties-1 func process_rewards_and_penalties*( @@ -1000,6 +1037,22 @@ func get_slashing_penalty*(validator: Validator, # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#slashings +func get_slashing( + state: ForkyBeaconState, total_balance: Gwei, vidx: ValidatorIndex): Gwei = + # For efficiency reasons, it doesn't make sense to have process_slashings use + # this per-validator index version, but keep them parallel otherwise. + let + epoch = get_current_epoch(state) + adjusted_total_slashing_balance = get_adjusted_total_slashing_balance( + state, total_balance) + + let validator = unsafeAddr state.validators.item(vidx) + if slashing_penalty_applies(validator[], epoch): + get_slashing_penalty( + validator[], adjusted_total_slashing_balance, total_balance) + else: + 0.Gwei + func process_slashings*(state: var ForkyBeaconState, total_balance: Gwei) = let epoch = get_current_epoch(state) @@ -1164,7 +1217,7 @@ template compute_inactivity_update( # TODO activeness already checked; remove redundant checks between # is_active_validator and is_unslashed_participating_index if is_unslashed_participating_index( - state, TIMELY_TARGET_FLAG_INDEX, previous_epoch, index.ValidatorIndex): + state, TIMELY_TARGET_FLAG_INDEX, previous_epoch, index): inactivity_score -= min(1'u64, inactivity_score) else: inactivity_score += cfg.INACTIVITY_SCORE_BIAS @@ -1195,6 +1248,7 @@ func process_inactivity_updates*( let pre_inactivity_score = state.inactivity_scores.asSeq()[index] + index = index.ValidatorIndex # intentional shadowing inactivity_score = compute_inactivity_update(cfg, state, info, pre_inactivity_score) @@ -1507,3 +1561,108 @@ proc process_epoch*( process_sync_committee_updates(state) ok() + +proc get_validator_balance_after_epoch*( + cfg: RuntimeConfig, + state: deneb.BeaconState | electra.BeaconState, + flags: UpdateFlags, cache: var StateCache, info: var altair.EpochInfo, + index: ValidatorIndex): Gwei = + # Run a subset of process_epoch() which affects an individual validator, + # without modifying state itself + info.init(state) # TODO avoid quadratic aspects here + + # Can't use process_justification_and_finalization(), but use its helper + # function. Used to calculate inactivity_score. + let jf_info = + # process_justification_and_finalization() skips first two epochs + if get_current_epoch(state) <= GENESIS_EPOCH + 1: + JustificationAndFinalizationInfo( + previous_justified_checkpoint: state.previous_justified_checkpoint, + current_justified_checkpoint: state.current_justified_checkpoint, + finalized_checkpoint: state.finalized_checkpoint, + justification_bits: state.justification_bits) + else: + weigh_justification_and_finalization( + state, info.balances.current_epoch, + info.balances.previous_epoch[TIMELY_TARGET_FLAG_INDEX], + info.balances.current_epoch_TIMELY_TARGET, flags) + + # Used as part of process_rewards_and_penalties + let inactivity_score = + # process_inactivity_updates skips GENESIS_EPOCH and ineligible validators + if get_current_epoch(state) == GENESIS_EPOCH or + not is_eligible_validator(info.validators[index]): + 0.Gwei + else: + let + finality_delay = + get_previous_epoch(state) - jf_info.finalized_checkpoint.epoch + not_in_inactivity_leak = not is_in_inactivity_leak(finality_delay) + pre_inactivity_score = state.inactivity_scores.asSeq()[index] + + # This is a template which uses not_in_inactivity_leak and index + compute_inactivity_update(cfg, state, info, pre_inactivity_score).Gwei + + # process_rewards_and_penalties for a single validator + let reward_and_penalties_balance = block: + # process_rewards_and_penalties doesn't run at GENESIS_EPOCH + if get_current_epoch(state) == GENESIS_EPOCH: + state.balances.item(index) + else: + let + total_active_balance = info.balances.current_epoch + base_reward_per_increment = get_base_reward_per_increment( + total_active_balance) + finality_delay = get_finality_delay(state) + + var balance = state.balances.item(index) + let maybeDelta = get_flag_and_inactivity_delta_for_validator( + cfg, state, base_reward_per_increment, info, finality_delay, index, + inactivity_score) + if maybeDelta.isOk: + # Can't use isErrOr in generics + let (validator_index, reward0, reward1, reward2, penalty0, penalty1, penalty2) = + maybeDelta.get + info.validators[validator_index].delta.rewards += reward0 + reward1 + reward2 + info.validators[validator_index].delta.penalties += penalty0 + penalty1 + penalty2 + increase_balance(balance, info.validators[index].delta.rewards) + decrease_balance(balance, info.validators[index].delta.penalties) + balance + + # The two directly balance-changing operations, from Altair through Deneb, + # are these. The rest is necessary to look past a single epoch transition, + # but that's not the use case here. + var post_epoch_balance = reward_and_penalties_balance + decrease_balance( + post_epoch_balance, + get_slashing(state, info.balances.current_epoch, index)) + + # Electra adds process_pending_balance_deposit to the list of potential + # balance-changing epoch operations. This should probably be cached, so + # the 16+ invocations of this function each time, e.g., withdrawals are + # calculated don't repeat it, if it's empirically too expensive. Limits + # exist on how large this structure can get though. + when type(state).kind >= ConsensusFork.Electra: + let available_for_processing = state.deposit_balance_to_consume + + get_activation_exit_churn_limit(cfg, state, cache) + var processed_amount = 0.Gwei + + for deposit in state.pending_balance_deposits: + let + validator = state.validators.item(deposit.index) + deposit_validator_index = ValidatorIndex.init(deposit.index).valueOr: + break + + # Validator is exiting, postpone the deposit until after withdrawable epoch + if validator.exit_epoch < FAR_FUTURE_EPOCH: + if not(get_current_epoch(state) <= validator.withdrawable_epoch) and + deposit_validator_index == index: + increase_balance(post_epoch_balance, deposit.amount) + # Validator is not exiting, attempt to process deposit + else: + if not(processed_amount + deposit.amount > available_for_processing): + if deposit_validator_index == index: + increase_balance(post_epoch_balance, deposit.amount) + processed_amount += deposit.amount + + post_epoch_balance diff --git a/tests/consensus_spec/deneb/test_fixture_state_transition_epoch.nim b/tests/consensus_spec/deneb/test_fixture_state_transition_epoch.nim index 608880777..74fafafb0 100644 --- a/tests/consensus_spec/deneb/test_fixture_state_transition_epoch.nim +++ b/tests/consensus_spec/deneb/test_fixture_state_transition_epoch.nim @@ -13,7 +13,7 @@ import chronicles, # Beacon chain internals ../../../beacon_chain/spec/[presets, state_transition_epoch], - ../../../beacon_chain/spec/datatypes/[altair, deneb], + ../../../beacon_chain/spec/datatypes/altair, # Test utilities ../../testutil, ../fixtures_utils, ../os_ops, @@ -22,6 +22,8 @@ import from std/sequtils import mapIt, toSeq from std/strutils import rsplit +from ../../../beacon_chain/spec/datatypes/deneb import BeaconState +from ../../teststateutil import checkPerValidatorBalanceCalc const RootDir = SszTestsDir/const_preset/"deneb"/"epoch_processing" @@ -73,6 +75,7 @@ template runSuite( # --------------------------------------------------------------- runSuite(JustificationFinalizationDir, "Justification & Finalization"): let info = altair.EpochInfo.init(state) + check checkPerValidatorBalanceCalc(state) process_justification_and_finalization(state, info.balances) Result[void, cstring].ok() @@ -80,6 +83,7 @@ runSuite(JustificationFinalizationDir, "Justification & Finalization"): # --------------------------------------------------------------- runSuite(InactivityDir, "Inactivity"): let info = altair.EpochInfo.init(state) + check checkPerValidatorBalanceCalc(state) process_inactivity_updates(cfg, state, info) Result[void, cstring].ok() diff --git a/tests/consensus_spec/electra/test_fixture_state_transition_epoch.nim b/tests/consensus_spec/electra/test_fixture_state_transition_epoch.nim index 2c0c2c397..0ec474961 100644 --- a/tests/consensus_spec/electra/test_fixture_state_transition_epoch.nim +++ b/tests/consensus_spec/electra/test_fixture_state_transition_epoch.nim @@ -13,7 +13,7 @@ import chronicles, # Beacon chain internals ../../../beacon_chain/spec/[presets, state_transition_epoch], - ../../../beacon_chain/spec/datatypes/[altair, electra], + ../../../beacon_chain/spec/datatypes/altair, # Test utilities ../../testutil, ../fixtures_utils, ../os_ops, @@ -22,6 +22,8 @@ import from std/sequtils import mapIt, toSeq from std/strutils import rsplit +from ../../../beacon_chain/spec/datatypes/electra import BeaconState +from ../../teststateutil import checkPerValidatorBalanceCalc const RootDir = SszTestsDir/const_preset/"electra"/"epoch_processing" @@ -76,6 +78,7 @@ template runSuite( # --------------------------------------------------------------- runSuite(JustificationFinalizationDir, "Justification & Finalization"): let info = altair.EpochInfo.init(state) + check checkPerValidatorBalanceCalc(state) process_justification_and_finalization(state, info.balances) Result[void, cstring].ok() @@ -83,6 +86,7 @@ runSuite(JustificationFinalizationDir, "Justification & Finalization"): # --------------------------------------------------------------- runSuite(InactivityDir, "Inactivity"): let info = altair.EpochInfo.init(state) + check checkPerValidatorBalanceCalc(state) process_inactivity_updates(cfg, state, info) Result[void, cstring].ok() diff --git a/tests/consensus_spec/test_fixture_sanity_blocks.nim b/tests/consensus_spec/test_fixture_sanity_blocks.nim index 22b2eb35d..8d31ad2d0 100644 --- a/tests/consensus_spec/test_fixture_sanity_blocks.nim +++ b/tests/consensus_spec/test_fixture_sanity_blocks.nim @@ -11,7 +11,7 @@ import chronicles, ../../beacon_chain/spec/forks, - ../../beacon_chain/spec/state_transition, + ../../beacon_chain/spec/[state_transition, state_transition_epoch], ./os_ops, ../testutil @@ -21,6 +21,7 @@ from ../../beacon_chain/spec/presets import const_preset, defaultRuntimeConfig from ./fixtures_utils import SSZ, SszTestsDir, hash_tree_root, parseTest, readSszBytes, toSszType +from ../teststateutil import checkPerValidatorBalanceCalc proc runTest( consensusFork: static ConsensusFork, @@ -52,6 +53,9 @@ proc runTest( discard state_transition( defaultRuntimeConfig, fhPreState[], blck, cache, info, flags = {}, noRollback).expect("should apply block") + withState(fhPreState[]): + when consensusFork >= ConsensusFork.Deneb: + check checkPerValidatorBalanceCalc(forkyState.data) else: let res = state_transition( defaultRuntimeConfig, fhPreState[], blck, cache, info, flags = {}, diff --git a/tests/teststateutil.nim b/tests/teststateutil.nim index 8c231a4e1..2eb8a12d1 100644 --- a/tests/teststateutil.nim +++ b/tests/teststateutil.nim @@ -14,6 +14,9 @@ import forks, state_transition, state_transition_block] from ".."/beacon_chain/bloomfilter import constructBloomFilter +from ".."/beacon_chain/spec/state_transition_epoch import + get_validator_balance_after_epoch, process_epoch + func round_multiple_down(x: Gwei, n: Gwei): Gwei = ## Round the input to the previous multiple of "n" @@ -97,4 +100,19 @@ proc getTestStates*( doAssert getStateField(tmpState[], slot) == slot if tmpState[].kind == consensusFork: - result.add assignClone(tmpState[]) \ No newline at end of file + result.add assignClone(tmpState[]) + +proc checkPerValidatorBalanceCalc*( + state: deneb.BeaconState | electra.BeaconState): bool = + var + info: altair.EpochInfo + cache: StateCache + let tmpState = newClone(state) # slow, but tolerable for tests + discard process_epoch(defaultRuntimeConfig, tmpState[], {}, cache, info) + for i in 0 ..< tmpState.balances.len: + if tmpState.balances.item(i) != get_validator_balance_after_epoch( + defaultRuntimeConfig, state, default(UpdateFlags), cache, info, + i.ValidatorIndex): + return false + + true From dc007e397726d53badb551f42435296488bc4130 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Tue, 9 Jul 2024 12:38:16 +0200 Subject: [PATCH 53/68] nullability annotations for `libnimbus_lc.h` (#6417) Annotate functions that may return `NULL` with `_Nullable` to properly bridge into Swift. --- beacon_chain/libnimbus_lc/libnimbus_lc.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/beacon_chain/libnimbus_lc/libnimbus_lc.h b/beacon_chain/libnimbus_lc/libnimbus_lc.h index 397b62ef2..268ead32e 100644 --- a/beacon_chain/libnimbus_lc/libnimbus_lc.h +++ b/beacon_chain/libnimbus_lc/libnimbus_lc.h @@ -63,7 +63,7 @@ typedef struct ETHRandomNumber ETHRandomNumber; * @return `NULL` - If an error occurred. */ ETH_RESULT_USE_CHECK -ETHRandomNumber *ETHRandomNumberCreate(void); +ETHRandomNumber *_Nullable ETHRandomNumberCreate(void); /** * Destroys a cryptographically secure random number generator. @@ -97,7 +97,7 @@ typedef struct ETHConsensusConfig ETHConsensusConfig; * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/configs/README.md */ ETH_RESULT_USE_CHECK -ETHConsensusConfig *ETHConsensusConfigCreateFromYaml(const char *configFileContent); +ETHConsensusConfig *_Nullable ETHConsensusConfigCreateFromYaml(const char *configFileContent); /** * Destroys an Ethereum Consensus Layer network configuration. @@ -156,7 +156,7 @@ typedef struct ETHBeaconState ETHBeaconState; * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/configs/README.md */ ETH_RESULT_USE_CHECK -ETHBeaconState *ETHBeaconStateCreateFromSsz( +ETHBeaconState *_Nullable ETHBeaconStateCreateFromSsz( const ETHConsensusConfig *cfg, const char *consensusVersion, const void *sszBytes, @@ -251,7 +251,7 @@ typedef struct ETHBeaconClock ETHBeaconClock; * NULL if the state contained an invalid time. */ ETH_RESULT_USE_CHECK -ETHBeaconClock *ETHBeaconClockCreateFromState( +ETHBeaconClock *_Nullable ETHBeaconClockCreateFromState( const ETHConsensusConfig *cfg, const ETHBeaconState *state); /** @@ -329,7 +329,7 @@ typedef struct ETHLightClientStore ETHLightClientStore; * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/phase0/weak-subjectivity.md#weak-subjectivity-period */ ETH_RESULT_USE_CHECK -ETHLightClientStore *ETHLightClientStoreCreateFromBootstrap( +ETHLightClientStore *_Nullable ETHLightClientStoreCreateFromBootstrap( const ETHConsensusConfig *cfg, const ETHRoot *trustedBlockRoot, const char *mediaType, @@ -1040,7 +1040,7 @@ typedef struct ETHExecutionBlockHeader ETHExecutionBlockHeader; * @see https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbyhash */ ETH_RESULT_USE_CHECK -ETHExecutionBlockHeader *ETHExecutionBlockHeaderCreateFromJson( +ETHExecutionBlockHeader *_Nullable ETHExecutionBlockHeaderCreateFromJson( const ETHRoot *executionHash, const char *blockHeaderJson); @@ -1129,7 +1129,7 @@ typedef struct ETHTransactions ETHTransactions; * @see https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbyhash */ ETH_RESULT_USE_CHECK -ETHTransactions *ETHTransactionsCreateFromJson( +ETHTransactions *_Nullable ETHTransactionsCreateFromJson( const ETHRoot *transactionsRoot, const char *transactionsJson); @@ -1539,7 +1539,7 @@ typedef struct ETHReceipts ETHReceipts; * @see https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionreceipt */ ETH_RESULT_USE_CHECK -ETHReceipts *ETHReceiptsCreateFromJson( +ETHReceipts *_Nullable ETHReceiptsCreateFromJson( const ETHRoot *receiptsRoot, const char *receiptsJson, const ETHTransactions *transactions); From befcf3f56a97df1e420ffe69c3276d2bd418adec Mon Sep 17 00:00:00 2001 From: tersec Date: Thu, 11 Jul 2024 07:13:37 +0200 Subject: [PATCH 54/68] bump sepolia for new bootnodes (#6421) --- beacon_chain/networking/network_metadata.nim | 4 ++-- beacon_chain/networking/network_metadata_mainnet.S | 2 +- vendor/sepolia | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/beacon_chain/networking/network_metadata.nim b/beacon_chain/networking/network_metadata.nim index d49535a17..be4f41ce6 100644 --- a/beacon_chain/networking/network_metadata.nim +++ b/beacon_chain/networking/network_metadata.nim @@ -294,7 +294,7 @@ elif const_preset == "mainnet": vendorDir & "/mainnet/metadata/genesis.ssz") sepoliaGenesis* = slurp( - vendorDir & "/sepolia/bepolia/genesis.ssz") + vendorDir & "/sepolia/metadata/genesis.ssz") const mainnetMetadata = loadCompileTimeNetworkMetadata( @@ -310,7 +310,7 @@ elif const_preset == "mainnet": digest: Eth2Digest.fromHex "0x0ea3f6f9515823b59c863454675fefcd1d8b4f2dbe454db166206a41fda060a0")) sepoliaMetadata = loadCompileTimeNetworkMetadata( - vendorDir & "/sepolia/bepolia", + vendorDir & "/sepolia/metadata", Opt.some sepolia, useBakedInGenesis = Opt.some "sepolia") diff --git a/beacon_chain/networking/network_metadata_mainnet.S b/beacon_chain/networking/network_metadata_mainnet.S index aafa1dd8c..aaffdcc99 100644 --- a/beacon_chain/networking/network_metadata_mainnet.S +++ b/beacon_chain/networking/network_metadata_mainnet.S @@ -36,7 +36,7 @@ cdecl(eth2_mainnet_genesis_size): .quad eth2_mainnet_genesis_end - eth2_mainnet_genesis_data eth2_sepolia_genesis_data: - .incbin "sepolia/bepolia/genesis.ssz" + .incbin "sepolia/metadata/genesis.ssz" eth2_sepolia_genesis_end: .global cdecl(eth2_sepolia_genesis_size) .p2align 3 diff --git a/vendor/sepolia b/vendor/sepolia index ff09a161f..f53301cf3 160000 --- a/vendor/sepolia +++ b/vendor/sepolia @@ -1 +1 @@ -Subproject commit ff09a161f61959285c64b355d452cd25eae094bd +Subproject commit f53301cf3268363c36e22f0205111350276e41ac From 031033a6f91671521006bbf04003d5e175c86496 Mon Sep 17 00:00:00 2001 From: Eugene Kabanov Date: Thu, 11 Jul 2024 18:39:38 +0300 Subject: [PATCH 55/68] Fix REST /eth/v1/node/identity should return proper MultiAddresses (version 2). (#6422) * Initial commit. * Bump nim-libp2p with dualstack fixes. * Pass announcedAddresses to the `p2p_addresses` list. --- beacon_chain/networking/eth2_network.nim | 14 ++++- beacon_chain/rpc/rest_node_api.nim | 77 ++++++++++-------------- vendor/nim-libp2p | 2 +- 3 files changed, 44 insertions(+), 49 deletions(-) diff --git a/beacon_chain/networking/eth2_network.nim b/beacon_chain/networking/eth2_network.nim index a2e08871c..654548b03 100644 --- a/beacon_chain/networking/eth2_network.nim +++ b/beacon_chain/networking/eth2_network.nim @@ -23,13 +23,15 @@ import libp2p/protocols/pubsub/[ pubsub, gossipsub, rpc/message, rpc/messages, peertable, pubsubpeer], libp2p/stream/connection, + libp2p/services/wildcardresolverservice, eth/[keys, async_utils], eth/net/nat, eth/p2p/discoveryv5/[enr, node, random2], ".."/[version, conf, beacon_clock, conf_light_client], ../spec/datatypes/[phase0, altair, bellatrix], ../spec/[eth2_ssz_serialization, network, helpers, forks], ../validators/keystore_management, - "."/[eth2_discovery, eth2_protocol_dsl, libp2p_json_serialization, peer_pool, peer_scores] + "."/[eth2_discovery, eth2_protocol_dsl, libp2p_json_serialization, peer_pool, + peer_scores] export tables, chronos, ratelimit, version, multiaddress, peerinfo, p2pProtocol, @@ -81,6 +83,7 @@ type rng*: ref HmacDrbgContext peers*: Table[PeerId, Peer] directPeers*: DirectPeers + announcedAddresses*: seq[MultiAddress] validTopics: HashSet[string] peerPingerHeartbeatFut: Future[void].Raising([CancelledError]) peerTrimmerHeartbeatFut: Future[void].Raising([CancelledError]) @@ -1767,7 +1770,7 @@ proc new(T: type Eth2Node, switch: Switch, pubsub: GossipSub, ip: Opt[IpAddress], tcpPort, udpPort: Opt[Port], privKey: keys.PrivateKey, discovery: bool, - directPeers: DirectPeers, + directPeers: DirectPeers, announcedAddresses: openArray[MultiAddress], rng: ref HmacDrbgContext): T {.raises: [CatchableError].} = when not defined(local_testnet): let @@ -1811,6 +1814,7 @@ proc new(T: type Eth2Node, connectTimeout: connectTimeout, seenThreshold: seenThreshold, directPeers: directPeers, + announcedAddresses: @announcedAddresses, quota: TokenBucket.new(maxGlobalQuota, fullReplenishTime) ) @@ -2223,6 +2227,8 @@ func gossipId( proc newBeaconSwitch(config: BeaconNodeConf | LightClientConf, seckey: PrivateKey, address: MultiAddress, rng: ref HmacDrbgContext): Switch {.raises: [CatchableError].} = + let service: Service = WildcardAddressResolverService.new() + var sb = if config.enableYamux: SwitchBuilder.new().withYamux() @@ -2239,6 +2245,7 @@ proc newBeaconSwitch(config: BeaconNodeConf | LightClientConf, .withMaxConnections(config.maxPeers) .withAgentVersion(config.agentString) .withTcpTransport({ServerFlags.ReuseAddr}) + .withServices(@[service]) .build() proc createEth2Node*(rng: ref HmacDrbgContext, @@ -2359,7 +2366,8 @@ proc createEth2Node*(rng: ref HmacDrbgContext, let node = Eth2Node.new( config, cfg, enrForkId, discoveryForkId, forkDigests, getBeaconTime, switch, pubsub, extIp, extTcpPort, extUdpPort, netKeys.seckey.asEthKey, - discovery = config.discv5Enabled, directPeers, rng = rng) + discovery = config.discv5Enabled, directPeers, announcedAddresses, + rng = rng) node.pubsub.subscriptionValidator = proc(topic: string): bool {.gcsafe, raises: [].} = diff --git a/beacon_chain/rpc/rest_node_api.nim b/beacon_chain/rpc/rest_node_api.nim index 303a39e59..b6465b11f 100644 --- a/beacon_chain/rpc/rest_node_api.nim +++ b/beacon_chain/rpc/rest_node_api.nim @@ -106,35 +106,38 @@ proc getLastSeenAddress(node: BeaconNode, id: PeerId): string = $addrs[len(addrs) - 1] else: "" -proc getDiscoveryAddresses(node: BeaconNode): Option[seq[string]] = - let restr = node.network.enrRecord().toTypedRecord() - if restr.isErr(): - return none[seq[string]]() - let respa = restr.get().toPeerAddr(udpProtocol) - if respa.isErr(): - return none[seq[string]]() - let pa = respa.get() - let mpa = MultiAddress.init(multiCodec("p2p"), pa.peerId) - if mpa.isErr(): - return none[seq[string]]() - var addresses = newSeqOfCap[string](len(pa.addrs)) - for item in pa.addrs: - let resa = concat(item, mpa.get()) - if resa.isOk(): - addresses.add($(resa.get())) - return some(addresses) +proc getDiscoveryAddresses(node: BeaconNode): seq[string] = + let + typedRec = node.network.enrRecord().toTypedRecord().valueOr: + return default(seq[string]) + peerAddr = typedRec.toPeerAddr(udpProtocol).valueOr: + return default(seq[string]) + maddress = MultiAddress.init(multiCodec("p2p"), peerAddr.peerId).valueOr: + return default(seq[string]) -proc getP2PAddresses(node: BeaconNode): Option[seq[string]] = - let pinfo = node.network.switch.peerInfo - let mpa = MultiAddress.init(multiCodec("p2p"), pinfo.peerId) - if mpa.isErr(): - return none[seq[string]]() - var addresses = newSeqOfCap[string](len(pinfo.addrs)) + var addresses: seq[string] + for item in peerAddr.addrs: + let res = concat(item, maddress) + if res.isOk(): + addresses.add($(res.get())) + addresses + +proc getP2PAddresses(node: BeaconNode): seq[string] = + let + pinfo = node.network.switch.peerInfo + maddress = MultiAddress.init(multiCodec("p2p"), pinfo.peerId).valueOr: + return default(seq[string]) + + var addresses: seq[string] + for item in node.network.announcedAddresses: + let res = concat(item, maddress) + if res.isOk(): + addresses.add($(res.get())) for item in pinfo.addrs: - let resa = concat(item, mpa.get()) - if resa.isOk(): - addresses.add($(resa.get())) - return some(addresses) + let res = concat(item, maddress) + if res.isOk(): + addresses.add($(res.get())) + addresses proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) = let @@ -143,28 +146,12 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) = # https://ethereum.github.io/beacon-APIs/#/Node/getNetworkIdentity router.api2(MethodGet, "/eth/v1/node/identity") do () -> RestApiResponse: - let discoveryAddresses = - block: - let res = node.getDiscoveryAddresses() - if res.isSome(): - res.get() - else: - newSeq[string](0) - - let p2pAddresses = - block: - let res = node.getP2PAddresses() - if res.isSome(): - res.get() - else: - newSeq[string]() - RestApiResponse.jsonResponse( ( peer_id: $node.network.peerId(), enr: node.network.enrRecord().toURI(), - p2p_addresses: p2pAddresses, - discovery_addresses: discoveryAddresses, + p2p_addresses: node.getP2PAddresses(), + discovery_addresses: node.getDiscoveryAddresses(), metadata: ( seq_number: node.network.metadata.seq_number, syncnets: to0xHex(node.network.metadata.syncnets.bytes), diff --git a/vendor/nim-libp2p b/vendor/nim-libp2p index 8cb7dbb42..b5fb7b3a9 160000 --- a/vendor/nim-libp2p +++ b/vendor/nim-libp2p @@ -1 +1 @@ -Subproject commit 8cb7dbb425df1124b17c6b3142a19a380114a693 +Subproject commit b5fb7b3a97d8977d969d786633f70c4094cd0eaf From 738bc0e98f0de86f3cb44592a53f72c6279360a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jul 2024 03:05:55 +0000 Subject: [PATCH 56/68] Bump zipp from 3.8.1 to 3.19.1 in /docs (#6418) Bumps [zipp](https://github.com/jaraco/zipp) from 3.8.1 to 3.19.1. - [Release notes](https://github.com/jaraco/zipp/releases) - [Changelog](https://github.com/jaraco/zipp/blob/main/NEWS.rst) - [Commits](https://github.com/jaraco/zipp/compare/v3.8.1...v3.19.1) --- updated-dependencies: - dependency-name: zipp dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 535ccfebf..d750cf168 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -66,7 +66,7 @@ watchdog==2.1.9 # via mkdocs wheel==0.38.1 # via pip-tools -zipp==3.8.1 +zipp==3.19.1 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: From ca15c4e433a5d2551972dee8fb4abcd7c65dd148 Mon Sep 17 00:00:00 2001 From: Kim De Mey Date: Fri, 12 Jul 2024 17:18:24 +0200 Subject: [PATCH 57/68] Replace deprecated ENR functions (#6419) --- beacon_chain/conf.nim | 7 +++++-- beacon_chain/networking/eth2_discovery.nim | 10 +++++----- beacon_chain/networking/eth2_network.nim | 15 ++++++++------- beacon_chain/rpc/rest_node_api.nim | 3 +-- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/beacon_chain/conf.nim b/beacon_chain/conf.nim index 8ec54e6ea..ae3394879 100644 --- a/beacon_chain/conf.nim +++ b/beacon_chain/conf.nim @@ -1269,8 +1269,11 @@ func completeCmdArg*(T: type WalletName, input: string): seq[string] = return @[] proc parseCmdArg*(T: type enr.Record, p: string): T {.raises: [ValueError].} = - if not fromURI(result, p): - raise newException(ValueError, "Invalid ENR") + let res = enr.Record.fromURI(p) + if res.isErr: + raise newException(ValueError, "Invalid ENR:" & $res.error) + + res.value func completeCmdArg*(T: type enr.Record, val: string): seq[string] = return @[] diff --git a/beacon_chain/networking/eth2_discovery.nim b/beacon_chain/networking/eth2_discovery.nim index 7ead407f7..8bb648dba 100644 --- a/beacon_chain/networking/eth2_discovery.nim +++ b/beacon_chain/networking/eth2_discovery.nim @@ -25,13 +25,13 @@ type Eth2DiscoveryId* = NodeId func parseBootstrapAddress*(address: string): - Result[enr.Record, cstring] = + Result[enr.Record, string] = let lowerCaseAddress = toLowerAscii(address) if lowerCaseAddress.startsWith("enr:"): - var enrRec: enr.Record - if enrRec.fromURI(address): - return ok enrRec - return err "Invalid ENR bootstrap record" + let res = enr.Record.fromURI(address) + if res.isOk(): + return ok res.value + return err "Invalid bootstrap ENR: " & $res.error elif lowerCaseAddress.startsWith("enode:"): return err "ENode bootstrap addresses are not supported" else: diff --git a/beacon_chain/networking/eth2_network.nim b/beacon_chain/networking/eth2_network.nim index 654548b03..da37cd324 100644 --- a/beacon_chain/networking/eth2_network.nim +++ b/beacon_chain/networking/eth2_network.nim @@ -1391,7 +1391,7 @@ proc connectWorker(node: Eth2Node, index: int) {.async: (raises: [CancelledError node.connTable.excl(remotePeerAddr.peerId) proc toPeerAddr(node: Node): Result[PeerAddr, cstring] = - let nodeRecord = ? node.record.toTypedRecord() + let nodeRecord = TypedRecord.fromRecord(node.record) let peerAddr = ? nodeRecord.toPeerAddr(tcpProtocol) ok(peerAddr) @@ -1883,11 +1883,9 @@ proc start*(node: Eth2Node) {.async: (raises: [CancelledError]).} = notice "Discovery disabled; trying bootstrap nodes", nodes = node.discovery.bootstrapRecords.len for enr in node.discovery.bootstrapRecords: - let tr = enr.toTypedRecord() - if tr.isOk(): - let pa = tr.get().toPeerAddr(tcpProtocol) - if pa.isOk(): - await node.connQueue.addLast(pa.get()) + let pa = TypedRecord.fromRecord(enr).toPeerAddr(tcpProtocol) + if pa.isOk(): + await node.connQueue.addLast(pa.get()) node.peerPingerHeartbeatFut = node.peerPingerHeartbeat() node.peerTrimmerHeartbeatFut = node.peerTrimmerHeartbeat() @@ -2279,7 +2277,10 @@ proc createEth2Node*(rng: ref HmacDrbgContext, let (peerId, address) = if s.startsWith("enr:"): let - typedEnr = parseBootstrapAddress(s).get().toTypedRecord().get() + enr = parseBootstrapAddress(s).valueOr: + fatal "Failed to parse bootstrap address", enr=s + quit 1 + typedEnr = TypedRecord.fromRecord(enr) peerAddress = toPeerAddr(typedEnr, tcpProtocol).get() (peerAddress.peerId, peerAddress.addrs[0]) elif s.startsWith("/"): diff --git a/beacon_chain/rpc/rest_node_api.nim b/beacon_chain/rpc/rest_node_api.nim index b6465b11f..a9a5a114e 100644 --- a/beacon_chain/rpc/rest_node_api.nim +++ b/beacon_chain/rpc/rest_node_api.nim @@ -108,8 +108,7 @@ proc getLastSeenAddress(node: BeaconNode, id: PeerId): string = "" proc getDiscoveryAddresses(node: BeaconNode): seq[string] = let - typedRec = node.network.enrRecord().toTypedRecord().valueOr: - return default(seq[string]) + typedRec = TypedRecord.fromRecord(node.network.enrRecord()) peerAddr = typedRec.toPeerAddr(udpProtocol).valueOr: return default(seq[string]) maddress = MultiAddress.init(multiCodec("p2p"), peerAddr.peerId).valueOr: From baa085e8b1955f5ca022a4e394c25fd678b5d173 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Mon, 15 Jul 2024 04:26:14 +0200 Subject: [PATCH 58/68] bump geth to `v1.14.7` (#6423) - https://github.com/ethereum/go-ethereum/releases/tag/v1.14.7 --- scripts/geth_binaries.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/geth_binaries.sh b/scripts/geth_binaries.sh index c8d406f14..349427b37 100644 --- a/scripts/geth_binaries.sh +++ b/scripts/geth_binaries.sh @@ -21,7 +21,7 @@ source "${SCRIPTS_DIR}/bash_utils.sh" download_geth_stable() { if [[ ! -e "${STABLE_GETH_BINARY}" ]]; then - GETH_VERSION="1.14.6-aadddf3a" # https://geth.ethereum.org/downloads + GETH_VERSION="1.14.7-aa55f5ea" # https://geth.ethereum.org/downloads GETH_URL="https://gethstore.blob.core.windows.net/builds/" case "${OS}-${ARCH}" in From f751fde417860ba62ba14e795032c45942aad7d2 Mon Sep 17 00:00:00 2001 From: Eugene Kabanov Date: Mon, 15 Jul 2024 05:27:23 +0300 Subject: [PATCH 59/68] Use Nimbus specific agent string instead of nim-presto defaults. (#6424) * Use Nimbus specific agent string instead of nim-presto defaults. Use response(code) overload. * Fix REST API test. --- beacon_chain/nimbus_beacon_node.nim | 1 + beacon_chain/nimbus_binary_common.nim | 4 ++++ beacon_chain/rpc/rest_node_api.nim | 4 ++-- beacon_chain/rpc/rest_validator_api.nim | 4 ++-- beacon_chain/version.nim | 2 ++ ncli/resttest-rules.json | 3 +-- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/beacon_chain/nimbus_beacon_node.nim b/beacon_chain/nimbus_beacon_node.nim index 6fc2187e8..c78489c7a 100644 --- a/beacon_chain/nimbus_beacon_node.nim +++ b/beacon_chain/nimbus_beacon_node.nim @@ -826,6 +826,7 @@ proc init*(T: type BeaconNode, RestServerRef.init(config.restAddress, config.restPort, config.restAllowedOrigin, validateBeaconApiQueries, + nimbusAgentStr, config) else: nil diff --git a/beacon_chain/nimbus_binary_common.nim b/beacon_chain/nimbus_binary_common.nim index 51d6a3d35..6c896118b 100644 --- a/beacon_chain/nimbus_binary_common.nim +++ b/beacon_chain/nimbus_binary_common.nim @@ -357,6 +357,7 @@ proc init*(T: type RestServerRef, port: Port, allowedOrigin: Option[string], validateFn: PatternCallback, + ident: string, config: AnyConf): T = let address = initTAddress(ip, port) @@ -375,6 +376,7 @@ proc init*(T: type RestServerRef, let res = RestServerRef.new(RestRouter.init(validateFn, allowedOrigin), address, serverFlags = serverFlags, + serverIdent = ident, httpHeadersTimeout = headersTimeout, maxHeadersSize = maxHeadersSize, maxRequestBodySize = maxRequestBodySize, @@ -428,11 +430,13 @@ proc initKeymanagerServer*( RestServerRef.init(config.keymanagerAddress, config.keymanagerPort, config.keymanagerAllowedOrigin, validateKeymanagerApiQueries, + nimbusAgentStr, config) else: RestServerRef.init(config.keymanagerAddress, config.keymanagerPort, config.keymanagerAllowedOrigin, validateKeymanagerApiQueries, + nimbusAgentStr, config) else: nil diff --git a/beacon_chain/rpc/rest_node_api.nim b/beacon_chain/rpc/rest_node_api.nim index a9a5a114e..b96e0724b 100644 --- a/beacon_chain/rpc/rest_node_api.nim +++ b/beacon_chain/rpc/rest_node_api.nim @@ -141,7 +141,7 @@ proc getP2PAddresses(node: BeaconNode): seq[string] = proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) = let cachedVersion = - RestApiResponse.prepareJsonResponse((version: "Nimbus/" & fullVersionStr)) + RestApiResponse.prepareJsonResponse((version: nimbusAgentStr)) # https://ethereum.github.io/beacon-APIs/#/Node/getNetworkIdentity router.api2(MethodGet, "/eth/v1/node/identity") do () -> RestApiResponse: @@ -283,4 +283,4 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) = Http206 else: Http200 - RestApiResponse.response("", status, contentType = "") + RestApiResponse.response(status) diff --git a/beacon_chain/rpc/rest_validator_api.nim b/beacon_chain/rpc/rest_validator_api.nim index 81429df51..6e477f238 100644 --- a/beacon_chain/rpc/rest_validator_api.nim +++ b/beacon_chain/rpc/rest_validator_api.nim @@ -1102,7 +1102,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) = numUpdatedFeeRecipients = numUpdated, numRefreshedFeeRecipients = numRefreshed - RestApiResponse.response("", Http200, "text/plain") + RestApiResponse.response(Http200) # https://ethereum.github.io/beacon-APIs/#/Validator/registerValidator # https://github.com/ethereum/beacon-APIs/blob/v2.3.0/apis/validator/register_validator.yaml @@ -1129,7 +1129,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) = node.externalBuilderRegistrations[signedValidatorRegistration.message.pubkey] = signedValidatorRegistration - RestApiResponse.response("", Http200, "text/plain") + RestApiResponse.response(Http200) # https://ethereum.github.io/beacon-APIs/#/Validator/getLiveness router.api2(MethodPost, "/eth/v1/validator/liveness/{epoch}") do ( diff --git a/beacon_chain/version.nim b/beacon_chain/version.nim index 7d199a5e7..99d2a5c47 100644 --- a/beacon_chain/version.nim +++ b/beacon_chain/version.nim @@ -51,6 +51,8 @@ const fullVersionStr* = "v" & versionAsStr & "-" & gitRevision & "-" & versionBlob + nimbusAgentStr* = "Nimbus/" & fullVersionStr + func getNimGitHash*(): string = const gitPrefix = "git hash: " let tmp = splitLines(nimFullBanner) diff --git a/ncli/resttest-rules.json b/ncli/resttest-rules.json index 42c1b375d..7650f66ca 100644 --- a/ncli/resttest-rules.json +++ b/ncli/resttest-rules.json @@ -4748,8 +4748,7 @@ "body": {"content-type": "application/json", "data": "[{\"message\":{\"fee_recipient\":\"0xb943c2c22b1b186a34f47c4dbe2fe367de9ec180\",\"gas_limit\":\"40000000\",\"timestamp\":\"1661879190\",\"pubkey\":\"0xa37b7bb9c412b8cc318fabf7b1fec33eb9634680687f07b977393180ce99889dbcfda81900f3afb9f2281930cf49f5d8\"},\"signature\":\"0xa493085fab365d13bea2376434abc3dbfba00a576276c853acabd7b9cb2f2b4b0a90738dd9baeaef75d0f42fa94119a70a09b0ed38fbebb6dde92c9ca062447018821f36c19d6fe34eb8c357d62e5d33e5c1d35035472ef7dd22a7425cdba0c5\"}]"} }, "response": { - "status": {"operator": "equals", "value": "200"}, - "headers": [{"key": "Content-Type", "value": "text/plain", "operator": "equals"}] + "status": {"operator": "equals", "value": "200"} } }, { From 7853bd28789c4fc18abf5a2bbeeb606450aa8ab4 Mon Sep 17 00:00:00 2001 From: Eugene Kabanov Date: Mon, 15 Jul 2024 17:53:41 +0300 Subject: [PATCH 60/68] BN: User agent recognition and error codes decoding. (#6414) * Initial commit. * Force update remote agent right before disconnect. * Add handling errors from unknown remote agents. * Address review comments. --- beacon_chain/networking/eth2_agents.nim | 142 ++++++++++++++++++++++ beacon_chain/networking/eth2_network.nim | 32 ++++- beacon_chain/networking/peer_protocol.nim | 29 ++--- 3 files changed, 186 insertions(+), 17 deletions(-) create mode 100644 beacon_chain/networking/eth2_agents.nim diff --git a/beacon_chain/networking/eth2_agents.nim b/beacon_chain/networking/eth2_agents.nim new file mode 100644 index 000000000..cda2dc8d0 --- /dev/null +++ b/beacon_chain/networking/eth2_agents.nim @@ -0,0 +1,142 @@ +# beacon_chain +# Copyright (c) 2024 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. + +{.push raises: [].} + +import stew/base10 +import std/tables +import libp2p/[multiaddress, multicodec, peerstore] + +type + Eth2Agent* {.pure.} = enum + Unknown, + Nimbus, + Lighthouse, + Prysm, + Teku, + Lodestar, + Grandine + +func `$`*(a: Eth2Agent): string = + case a + of Eth2Agent.Unknown: + "pending/unknown" + of Eth2Agent.Nimbus: + "nimbus" + of Eth2Agent.Lighthouse: + "lighthouse" + of Eth2Agent.Prysm: + "prysm" + of Eth2Agent.Teku: + "teku" + of Eth2Agent.Lodestar: + "lodestar" + of Eth2Agent.Grandine: + "grandine" + +const + # Lighthouse errors could be found here + # https://github.com/sigp/lighthouse/blob/5fdd3b39bb8150d1ea8622e42e0166ed46af7693/beacon_node/lighthouse_network/src/rpc/methods.rs#L171 + LighthouseErrors = [ + (128'u64, "Unable to verify network"), + (129'u64, "The node has too many connected peers"), + (250'u64, "Peer score is too low"), + (251'u64, "The peer is banned"), + (252'u64, "The IP address the peer is using is banned"), + ].toTable() + + # Prysm errors could be found here + # https://github.com/prysmaticlabs/prysm/blob/7a394062e1054d73014e793819cb9cf0d20ff2e3/beacon-chain/p2p/types/rpc_goodbye_codes.go#L12 + PrysmErrors = [ + (128'u64, "Unable to verify network"), + (129'u64, "The node has too many connected peers"), + (250'u64, "Peer score is too low"), + (251'u64, "The peer is banned") + ].toTable() + + # Lodestar errors could be found here + # https://github.com/ChainSafe/lodestar/blob/7280234bea66b49da3900b916a1b54c4666e4173/packages/beacon-node/src/constants/network.ts#L20 + LodestarErrors = [ + (128'u64, "Unable to verify network"), + (129'u64, "The node has too many connected peers"), + (250'u64, "Peer score is too low"), + (251'u64, "The peer is banned") + ].toTable() + + # Teku errors could be found here + # https://github.com/Consensys/teku/blob/a3f7ebc75f24ec942286b0c1ae192e411f84aa7e/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/networking/libp2p/rpc/GoodbyeMessage.java#L42 + TekuErrors = [ + (128'u64, "Unable to verify network"), + (129'u64, "The node has too many connected peers"), + (130'u64, "Too many requests from the peer") + ].toTable() + + # Nimbus errors could be found here + # https://github.com/status-im/nimbus-eth2/blob/9b6b42c8f9792e657397bb3669a80b57da470c04/beacon_chain/networking/eth2_network.nim#L176 + NimbusErrors = [ + (237'u64, "Peer score is too low") + ].toTable() + + # Grandine errors could be found here + # https://github.com/grandinetech/eth2_libp2p/blob/63a0c5e662847b86b1d5617478e39bccd39df0a9/src/rpc/methods.rs#L246 + GrandineErrors = [ + (128'u64, "Unable to verify network"), + (129'u64, "The node has too many connected peers"), + (250'u64, "Peer score is too low"), + (251'u64, "The peer is banned"), + (252'u64, "The IP address the peer is using is banned"), + ].toTable() + + # This is combination of all the errors, we need it when remote agent is not + # identified yet. + UnknownErrors = [ + (128'u64, "Unable to verify network"), + (129'u64, "The node has too many connected peers"), + (130'u64, "Too many requests from the peer"), + (237'u64, "Peer score is too low"), + (250'u64, "Peer score is too low"), + (251'u64, "The peer is banned"), + (252'u64, "The IP address the peer is using is banned"), + ].toTable() + +func disconnectReasonName*(agent: Eth2Agent, code: uint64): string = + if code < 128'u64: + case code + of 0'u64: + "Unknown error (0)" + of 1'u64: + "Client shutdown (1)" + of 2'u64: + "Irrelevant network (2)" + of 3'u64: + "Fault or error (3)" + else: + let + scode = " (" & Base10.toString(code) & ")" + defaultMessage = "Disconnected" + + defaultMessage & scode + else: + let + scode = " (" & Base10.toString(code) & ")" + defaultMessage = "Disconnected" + + case agent + of Eth2Agent.Unknown: + UnknownErrors.getOrDefault(code, defaultMessage) & scode + of Eth2Agent.Nimbus: + NimbusErrors.getOrDefault(code, defaultMessage) & scode + of Eth2Agent.Lighthouse: + LighthouseErrors.getOrDefault(code, defaultMessage) & scode + of Eth2Agent.Prysm: + PrysmErrors.getOrDefault(code, defaultMessage) & scode + of Eth2Agent.Teku: + TekuErrors.getOrDefault(code, defaultMessage) & scode + of Eth2Agent.Lodestar: + LodestarErrors.getOrDefault(code, defaultMessage) & scode + of Eth2Agent.Grandine: + GrandineErrors.getOrDefault(code, defaultMessage) & scode diff --git a/beacon_chain/networking/eth2_network.nim b/beacon_chain/networking/eth2_network.nim index da37cd324..2955f4255 100644 --- a/beacon_chain/networking/eth2_network.nim +++ b/beacon_chain/networking/eth2_network.nim @@ -30,13 +30,13 @@ import ../spec/datatypes/[phase0, altair, bellatrix], ../spec/[eth2_ssz_serialization, network, helpers, forks], ../validators/keystore_management, - "."/[eth2_discovery, eth2_protocol_dsl, libp2p_json_serialization, peer_pool, - peer_scores] + "."/[eth2_discovery, eth2_protocol_dsl, eth2_agents, + libp2p_json_serialization, peer_pool, peer_scores] export tables, chronos, ratelimit, version, multiaddress, peerinfo, p2pProtocol, connection, libp2p_json_serialization, eth2_ssz_serialization, results, - eth2_discovery, peer_pool, peer_scores + eth2_discovery, peer_pool, peer_scores, eth2_agents logScope: topics = "networking" @@ -99,6 +99,7 @@ type Peer* = ref object network*: Eth2Node peerId*: PeerId + remoteAgent*: Eth2Agent discoveryId*: Eth2DiscoveryId connectionState*: ConnectionState protocolStates*: seq[RootRef] @@ -339,6 +340,31 @@ func shortProtocolId(protocolId: string): string = protocolId.high protocolId[start..ends] +proc updateAgent*(peer: Peer) = + let + agent = toLowerAscii(peer.network.switch.peerStore[AgentBook][peer.peerId]) + # proto = peer.network.switch.peerStore[ProtoVersionBook][peer.peerId] + + if "nimbus" in agent: + peer.remoteAgent = Eth2Agent.Nimbus + elif "lighthouse" in agent: + peer.remoteAgent = Eth2Agent.Lighthouse + elif "teku" in agent: + peer.remoteAgent = Eth2Agent.Teku + elif "lodestar" in agent: + peer.remoteAgent = Eth2Agent.Lodestar + elif "prysm" in agent: + peer.remoteAgent = Eth2Agent.Prysm + elif "grandine" in agent: + peer.remoteAgent = Eth2Agent.Grandine + else: + peer.remoteAgent = Eth2Agent.Unknown + +proc getRemoteAgent*(peer: Peer): Eth2Agent = + if peer.remoteAgent == Eth2Agent.Unknown: + peer.updateAgent() + peer.remoteAgent + proc openStream(node: Eth2Node, peer: Peer, protocolId: string): Future[NetRes[Connection]] diff --git a/beacon_chain/networking/peer_protocol.nim b/beacon_chain/networking/peer_protocol.nim index ff47b17dd..d2c6d68ef 100644 --- a/beacon_chain/networking/peer_protocol.nim +++ b/beacon_chain/networking/peer_protocol.nim @@ -8,7 +8,7 @@ {.push raises: [].} import - chronicles, + chronicles, stew/base10, metrics, ../spec/network, ".."/[beacon_clock], ../networking/eth2_network, @@ -37,6 +37,9 @@ type statusLastTime: chronos.Moment statusMsg: StatusMsg +declareCounter nbc_disconnects_count, + "Number disconnected peers", labels = ["agent", "reason"] + func shortLog*(s: StatusMsg): auto = ( forkDigest: s.forkDigest, @@ -47,13 +50,6 @@ func shortLog*(s: StatusMsg): auto = ) chronicles.formatIt(StatusMsg): shortLog(it) -func disconnectReasonName(reason: uint64): string = - # haha, nim doesn't support uint64 in `case`! - if reason == uint64(ClientShutDown): "Client shutdown" - elif reason == uint64(IrrelevantNetwork): "Irrelevant network" - elif reason == uint64(FaultOrError): "Fault or error" - else: "Disconnected (" & $reason & ")" - func forkDigestAtEpoch(state: PeerSyncNetworkState, epoch: Epoch): ForkDigest = state.forkDigests[].atEpoch(epoch, state.cfg) @@ -131,9 +127,9 @@ p2pProtocol PeerSync(version = 1, networkState = PeerSyncNetworkState, peerState = PeerSyncPeerState): - onPeerConnected do (peer: Peer, incoming: bool) {.async: (raises: [CancelledError]).}: - debug "Peer connected", - peer, peerId = shortLog(peer.peerId), incoming + onPeerConnected do (peer: Peer, incoming: bool) {. + async: (raises: [CancelledError]).}: + debug "Peer connected", peer, peerId = shortLog(peer.peerId), incoming # Per the eth2 protocol, whoever dials must send a status message when # connected for the first time, but because of how libp2p works, there may # be a race between incoming and outgoing connections and disconnects that @@ -152,6 +148,7 @@ p2pProtocol PeerSync(version = 1, if theirStatus.isOk: discard await peer.handleStatus(peer.networkState, theirStatus.get()) + peer.updateAgent() else: debug "Status response not received in time", peer, errorKind = theirStatus.error.kind @@ -179,9 +176,13 @@ p2pProtocol PeerSync(version = 1, {.libp2pProtocol("metadata", 2).} = peer.network.metadata - proc goodbye(peer: Peer, reason: uint64) - {.async, libp2pProtocol("goodbye", 1).} = - debug "Received Goodbye message", reason = disconnectReasonName(reason), peer + proc goodbye(peer: Peer, reason: uint64) {. + async, libp2pProtocol("goodbye", 1).} = + let remoteAgent = peer.getRemoteAgent() + nbc_disconnects_count.inc(1, [$remoteAgent, Base10.toString(reason)]) + debug "Received Goodbye message", + reason = disconnectReasonName(remoteAgent, reason), + remote_agent = $remoteAgent, peer proc setStatusMsg(peer: Peer, statusMsg: StatusMsg) = debug "Peer status", peer, statusMsg From ebd0217a10ff8d529307157f476385c4d82d8b14 Mon Sep 17 00:00:00 2001 From: tersec Date: Mon, 15 Jul 2024 19:08:20 +0000 Subject: [PATCH 61/68] fix is_eligible_for_activation_queue for electra (#6427) --- beacon_chain/spec/beaconstate.nim | 13 ++++++++++--- beacon_chain/spec/state_transition_epoch.nim | 5 +++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/beacon_chain/spec/beaconstate.nim b/beacon_chain/spec/beaconstate.nim index 6a93204fb..e6773f55b 100644 --- a/beacon_chain/spec/beaconstate.nim +++ b/beacon_chain/spec/beaconstate.nim @@ -515,10 +515,17 @@ template get_total_balance( max(EFFECTIVE_BALANCE_INCREMENT.Gwei, res) # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#is_eligible_for_activation_queue -func is_eligible_for_activation_queue*(validator: Validator): bool = +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#updated-is_eligible_for_activation_queue +func is_eligible_for_activation_queue*( + fork: static ConsensusFork, validator: Validator): bool = ## Check if ``validator`` is eligible to be placed into the activation queue. - validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH and - validator.effective_balance == MAX_EFFECTIVE_BALANCE.Gwei + when fork <= ConsensusFork.Deneb: + validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH and + validator.effective_balance == MAX_EFFECTIVE_BALANCE.Gwei + else: + # [Modified in Electra:EIP7251] + validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH and + validator.effective_balance >= MIN_ACTIVATION_BALANCE.Gwei # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#is_eligible_for_activation func is_eligible_for_activation*( diff --git a/beacon_chain/spec/state_transition_epoch.nim b/beacon_chain/spec/state_transition_epoch.nim index 9efc7b09e..c8e2c2b5a 100644 --- a/beacon_chain/spec/state_transition_epoch.nim +++ b/beacon_chain/spec/state_transition_epoch.nim @@ -932,7 +932,8 @@ func process_registry_updates*( var maybe_exit_queue_info: Opt[ExitQueueInfo] for vidx in state.validators.vindices: - if is_eligible_for_activation_queue(state.validators.item(vidx)): + if is_eligible_for_activation_queue( + typeof(state).kind, state.validators.item(vidx)): state.validators.mitem(vidx).activation_eligibility_epoch = get_current_epoch(state) + 1 @@ -977,7 +978,7 @@ func process_registry_updates*( # Process activation eligibility and ejections for index in 0 ..< state.validators.len: let validator = state.validators.item(index) - if is_eligible_for_activation_queue(validator): + if is_eligible_for_activation_queue(typeof(state).kind, validator): # Usually not too many at once, so do this individually state.validators.mitem(index).activation_eligibility_epoch = get_current_epoch(state) + 1 From 8aab04404eb5aa2ff55f4b5f0a34d521d0c30429 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 17 Jul 2024 21:21:27 +0200 Subject: [PATCH 62/68] bump nim-libbacktrace to `da32d6efe6804b021c0943f2dd22924052345e6d` (#6429) - bump libbacktrace to `1dd5c408fe6f5d9bccf870ec4e0e4bcabeb0664e` --- vendor/nim-libbacktrace | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/nim-libbacktrace b/vendor/nim-libbacktrace index 4db9cae5a..da32d6efe 160000 --- a/vendor/nim-libbacktrace +++ b/vendor/nim-libbacktrace @@ -1 +1 @@ -Subproject commit 4db9cae5ac0225e3439f577f5c5cd67086232b3f +Subproject commit da32d6efe6804b021c0943f2dd22924052345e6d From cd008ba7ef56ee8337bb8c7000a510c318cdf004 Mon Sep 17 00:00:00 2001 From: Kim De Mey Date: Wed, 17 Jul 2024 21:50:29 +0200 Subject: [PATCH 63/68] Bump NimYAML + bump related changes (#6431) --- tests/consensus_spec/test_fixture_fork_choice.nim | 4 ++-- tests/consensus_spec/test_fixture_kzg.nim | 14 +++++++------- .../test_fixture_light_client_data_collection.nim | 4 ++-- .../test_fixture_light_client_sync.nim | 4 ++-- tests/test_deposit_snapshots.nim | 4 ++-- vendor/NimYAML | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/consensus_spec/test_fixture_fork_choice.nim b/tests/consensus_spec/test_fixture_fork_choice.nim index 163996b8f..4e1ab0066 100644 --- a/tests/consensus_spec/test_fixture_fork_choice.nim +++ b/tests/consensus_spec/test_fixture_fork_choice.nim @@ -19,7 +19,7 @@ import ../../beacon_chain/consensus_object_pools/[ blockchain_dag, block_clearance, block_quarantine, spec_cache], # Third-party - yaml, + yaml/tojson, # Test ../testutil, ../testdbutil, ./fixtures_utils, ./os_ops @@ -102,7 +102,7 @@ proc loadOps( IOError, KeyError, UnconsumedInput, ValueError, YamlConstructionError, YamlParserError].} = let stepsYAML = os_ops.readFile(path/"steps.yaml") - let steps = yaml.loadToJson(stepsYAML) + let steps = loadToJson(stepsYAML) result = @[] for step in steps[0]: diff --git a/tests/consensus_spec/test_fixture_kzg.nim b/tests/consensus_spec/test_fixture_kzg.nim index 8ce41b25c..238e27195 100644 --- a/tests/consensus_spec/test_fixture_kzg.nim +++ b/tests/consensus_spec/test_fixture_kzg.nim @@ -10,7 +10,7 @@ import std/json, - yaml, + yaml/tojson, kzg4844/kzg_ex, stew/byteutils, ../testutil, @@ -39,7 +39,7 @@ proc runBlobToKzgCommitmentTest(suiteName, suitePath, path: string) = let relativePathComponent = path.relativeTestPathComponent(suitePath) test "KZG - Blob to KZG commitment - " & relativePathComponent: let - data = yaml.loadToJson(os_ops.readFile(path/"data.yaml"))[0] + data = loadToJson(os_ops.readFile(path/"data.yaml"))[0] output = data["output"] blob = fromHex[131072](data["input"]["blob"].getStr) @@ -61,7 +61,7 @@ proc runVerifyKzgProofTest(suiteName, suitePath, path: string) = let relativePathComponent = path.relativeTestPathComponent(suitePath) test "KZG - Verify KZG proof - " & relativePathComponent: let - data = yaml.loadToJson(os_ops.readFile(path/"data.yaml"))[0] + data = loadToJson(os_ops.readFile(path/"data.yaml"))[0] output = data["output"] commitment = fromHex[48](data["input"]["commitment"].getStr) z = fromHex[32](data["input"]["z"].getStr) @@ -89,7 +89,7 @@ proc runVerifyBlobKzgProofTest(suiteName, suitePath, path: string) = let relativePathComponent = path.relativeTestPathComponent(suitePath) test "KZG - Verify blob KZG proof - " & relativePathComponent: let - data = yaml.loadToJson(os_ops.readFile(path/"data.yaml"))[0] + data = loadToJson(os_ops.readFile(path/"data.yaml"))[0] output = data["output"] blob = fromHex[131072](data["input"]["blob"].getStr) commitment = fromHex[48](data["input"]["commitment"].getStr) @@ -117,7 +117,7 @@ proc runVerifyBlobKzgProofBatchTest(suiteName, suitePath, path: string) = let relativePathComponent = path.relativeTestPathComponent(suitePath) test "KZG - Verify blob KZG proof batch - " & relativePathComponent: let - data = yaml.loadToJson(os_ops.readFile(path/"data.yaml"))[0] + data = loadToJson(os_ops.readFile(path/"data.yaml"))[0] output = data["output"] blobs = data["input"]["blobs"].mapIt(fromHex[131072](it.getStr)) commitments = data["input"]["commitments"].mapIt(fromHex[48](it.getStr)) @@ -146,7 +146,7 @@ proc runComputeKzgProofTest(suiteName, suitePath, path: string) = let relativePathComponent = path.relativeTestPathComponent(suitePath) test "KZG - Compute KZG proof - " & relativePathComponent: let - data = yaml.loadToJson(os_ops.readFile(path/"data.yaml"))[0] + data = loadToJson(os_ops.readFile(path/"data.yaml"))[0] output = data["output"] blob = fromHex[131072](data["input"]["blob"].getStr) z = fromHex[32](data["input"]["z"].getStr) @@ -174,7 +174,7 @@ proc runComputeBlobKzgProofTest(suiteName, suitePath, path: string) = let relativePathComponent = path.relativeTestPathComponent(suitePath) test "KZG - Compute blob KZG proof - " & relativePathComponent: let - data = yaml.loadToJson(os_ops.readFile(path/"data.yaml"))[0] + data = loadToJson(os_ops.readFile(path/"data.yaml"))[0] output = data["output"] blob = fromHex[131072](data["input"]["blob"].getStr) commitment = fromHex[48](data["input"]["commitment"].getStr) diff --git a/tests/consensus_spec/test_fixture_light_client_data_collection.nim b/tests/consensus_spec/test_fixture_light_client_data_collection.nim index 55e6271d1..e53ed7fe3 100644 --- a/tests/consensus_spec/test_fixture_light_client_data_collection.nim +++ b/tests/consensus_spec/test_fixture_light_client_data_collection.nim @@ -16,7 +16,7 @@ import chronicles, taskpools, # Third-party - yaml, + yaml/tojson, # Beacon chain internals ../../beacon_chain/beacon_chain_db, ../../beacon_chain/consensus_object_pools/[block_clearance, block_quarantine], @@ -88,7 +88,7 @@ proc loadSteps( loadForked(t, s, path, fork_digests) let stepsYAML = os_ops.readFile(path/"steps.yaml") - let steps = yaml.loadToJson(stepsYAML) + let steps = loadToJson(stepsYAML) result = @[] for step in steps[0]: diff --git a/tests/consensus_spec/test_fixture_light_client_sync.nim b/tests/consensus_spec/test_fixture_light_client_sync.nim index 6338bf08a..068d749e4 100644 --- a/tests/consensus_spec/test_fixture_light_client_sync.nim +++ b/tests/consensus_spec/test_fixture_light_client_sync.nim @@ -14,7 +14,7 @@ import # Status libraries stew/byteutils, # Third-party - yaml, + yaml, yaml/tojson, # Beacon chain internals ../../beacon_chain/spec/[forks, light_client_sync], # Test utilities @@ -59,7 +59,7 @@ proc loadSteps( ): seq[TestStep] {.raises: [ KeyError, ValueError, YamlConstructionError, YamlParserError].} = let stepsYAML = os_ops.readFile(path/"steps.yaml") - let steps = yaml.loadToJson(stepsYAML) + let steps = loadToJson(stepsYAML) result = @[] for step in steps[0]: diff --git a/tests/test_deposit_snapshots.nim b/tests/test_deposit_snapshots.nim index 350fa407d..d7b1df40f 100644 --- a/tests/test_deposit_snapshots.nim +++ b/tests/test_deposit_snapshots.nim @@ -12,7 +12,7 @@ import std/[json, os, random, sequtils, strutils, times], chronos, stew/base10, chronicles, unittest2, - yaml, + yaml/tojson, ../beacon_chain/beacon_chain_db, ../beacon_chain/spec/deposit_snapshots, ./consensus_spec/os_ops @@ -208,7 +208,7 @@ suite "EIP-4881": path: string ): seq[DepositTestCase] {.raises: [ IOError, KeyError, ValueError, YamlConstructionError, YamlParserError].} = - yaml.loadToJson(os_ops.readFile(path))[0].mapIt: + loadToJson(os_ops.readFile(path))[0].mapIt: DepositTestCase( deposit_data: DepositData( pubkey: ValidatorPubKey.fromHex( diff --git a/vendor/NimYAML b/vendor/NimYAML index ab3ff9fad..7721c955b 160000 --- a/vendor/NimYAML +++ b/vendor/NimYAML @@ -1 +1 @@ -Subproject commit ab3ff9fad45fa7e20d749d0a03a7567225f5dd4a +Subproject commit 7721c955b522f4893265bb36a6de4f8edef8b54b From f36fb8e757b7a9b55bf47596baa029c3c517e3e2 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 17 Jul 2024 21:51:14 +0200 Subject: [PATCH 64/68] bump gnosis-chain-configs to `0e085cb606e78a495ce8014f9350931bc360e663` (#6432) - Bump spec --- vendor/gnosis-chain-configs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/gnosis-chain-configs b/vendor/gnosis-chain-configs index 9ed6c6331..0e085cb60 160000 --- a/vendor/gnosis-chain-configs +++ b/vendor/gnosis-chain-configs @@ -1 +1 @@ -Subproject commit 9ed6c63314899d17e2c3f669adbe2bc915610982 +Subproject commit 0e085cb606e78a495ce8014f9350931bc360e663 From 377698d65abe0802a4520440c93d431a09ac60ab Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Thu, 18 Jul 2024 19:59:49 +0200 Subject: [PATCH 65/68] bump nim-libbacktrace to `55780313446b618cd226025cd0383c4c9da4a18a` (#6435) - Pass length explicitly instead of relying on NULL terminators --- vendor/nim-libbacktrace | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/nim-libbacktrace b/vendor/nim-libbacktrace index da32d6efe..557803134 160000 --- a/vendor/nim-libbacktrace +++ b/vendor/nim-libbacktrace @@ -1 +1 @@ -Subproject commit da32d6efe6804b021c0943f2dd22924052345e6d +Subproject commit 55780313446b618cd226025cd0383c4c9da4a18a From 6fa852400d689a4b4fc0e493ba5f7e5b221b4f32 Mon Sep 17 00:00:00 2001 From: tersec Date: Sun, 21 Jul 2024 05:10:26 +0000 Subject: [PATCH 66/68] pause deployment of long-range sync option default (#6436) --- beacon_chain/conf.nim | 5 +++-- docs/the_nimbus_book/src/options.md | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/beacon_chain/conf.nim b/beacon_chain/conf.nim index ae3394879..405448862 100644 --- a/beacon_chain/conf.nim +++ b/beacon_chain/conf.nim @@ -562,9 +562,10 @@ type name: "light-client-data-max-periods" .}: Option[uint64] longRangeSync* {. + hidden desc: "Enable long-range syncing (genesis sync)", - defaultValue: LongRangeSyncMode.Light, - name: "long-range-sync".}: LongRangeSyncMode + defaultValue: LongRangeSyncMode.Lenient, + name: "debug-long-range-sync".}: LongRangeSyncMode inProcessValidators* {. desc: "Disable the push model (the beacon node tells a signing process with the private keys of the validators what to sign and when) and load the validators in the beacon node itself" diff --git a/docs/the_nimbus_book/src/options.md b/docs/the_nimbus_book/src/options.md index 16242d407..670bf7955 100644 --- a/docs/the_nimbus_book/src/options.md +++ b/docs/the_nimbus_book/src/options.md @@ -112,7 +112,6 @@ The following options are available: --light-client-data-import-mode Which classes of light client data to import. Must be one of: none, only-new, full (slow startup), on-demand (may miss validator duties) [=only-new]. --light-client-data-max-periods Maximum number of sync committee periods to retain light client data. - --long-range-sync Enable long-range syncing (genesis sync) [=LongRangeSyncMode.Light]. --in-process-validators Disable the push model (the beacon node tells a signing process with the private keys of the validators what to sign and when) and load the validators in the beacon node itself [=true]. From 0a4d3ac9c3aab071965b4ff62b45181d46aac78d Mon Sep 17 00:00:00 2001 From: tersec Date: Mon, 29 Jul 2024 00:45:51 +0000 Subject: [PATCH 67/68] version v24.7.0 --- CHANGELOG.md | 30 ++++++++++++++++++++++++++++++ beacon_chain/version.nim | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9664ff4c..8f19be546 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,33 @@ +2024-07-29 v24.7.0 +================== + +Nimbus `v24.7.0` is a `low-urgency` release with beacon API improvements and fixes. + +### Improvements + +* Add support for publishBlindedBlockV2 beacon API endpoint: + https://github.com/status-im/nimbus-eth2/pull/6413 + +* Improve block proposal rewards in the absence of pre-aggregated sync contributions: + https://github.com/status-im/nimbus-eth2/pull/6384 + +### Fixes + +* Fix SSZ decoding for beacon API publishBlock and publishBlockV2 endpoints + https://github.com/status-im/nimbus-eth2/pull/6408 + +* Fix `statuses` parameter handling in postStateValidators beacon API endpoint: + https://github.com/status-im/nimbus-eth2/pull/6391 + +* Restore functioning Sepolia bootnodes, as previous bootnodes had gradually vanished: + https://github.com/status-im/nimbus-eth2/pull/6421 + +* Fix IP addresses returned by getNetworkIdentity beacon API endpoint: + https://github.com/status-im/nimbus-eth2/pull/6422 + +* Ensure Keymanager API fee recipient changes propagate to builder API relays: + https://github.com/status-im/nimbus-eth2/pull/6412 + 2024-06-24 v24.6.0 ================== diff --git a/beacon_chain/version.nim b/beacon_chain/version.nim index 99d2a5c47..51c33eded 100644 --- a/beacon_chain/version.nim +++ b/beacon_chain/version.nim @@ -18,7 +18,7 @@ const "Copyright (c) 2019-" & compileYear & " Status Research & Development GmbH" versionMajor* = 24 - versionMinor* = 6 + versionMinor* = 7 versionBuild* = 0 versionBlob* = "stateofus" # Single word - ends up in the default graffiti From 99f657e548162767e354b3be00c336116d69a97b Mon Sep 17 00:00:00 2001 From: tersec Date: Mon, 29 Jul 2024 02:17:37 +0000 Subject: [PATCH 68/68] add missing colon at end of changelog line --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f19be546..f99bc24d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ Nimbus `v24.7.0` is a `low-urgency` release with beacon API improvements and fix ### Fixes -* Fix SSZ decoding for beacon API publishBlock and publishBlockV2 endpoints +* Fix SSZ decoding for beacon API publishBlock and publishBlockV2 endpoints: https://github.com/status-im/nimbus-eth2/pull/6408 * Fix `statuses` parameter handling in postStateValidators beacon API endpoint: