7070 - [ New ` process_pending_consolidations ` ] ( #new-process_pending_consolidations )
7171 - [ Updated ` process_effective_balance_updates ` ] ( #updated-process_effective_balance_updates )
7272 - [ Block processing] ( #block-processing )
73- - [ Updated ` get_expected_withdrawals ` ] ( #updated-get_expected_withdrawals )
74- - [ Updated ` process_withdrawals ` ] ( #updated-process_withdrawals )
75- - [ Modified ` process_operations ` ] ( #modified-process_operations )
76- - [ Modified ` process_attestation ` ] ( #modified-process_attestation )
73+ - [ Withdrawals] ( #withdrawals )
74+ - [ Updated ` get_expected_withdrawals ` ] ( #updated-get_expected_withdrawals )
75+ - [ Updated ` process_withdrawals ` ] ( #updated-process_withdrawals )
76+ - [ Execution payload] ( #execution-payload )
77+ - [ Modified ` process_execution_payload ` ] ( #modified-process_execution_payload )
78+ - [ Operations] ( #operations )
79+ - [ Modified ` process_operations ` ] ( #modified-process_operations )
80+ - [ Attestations] ( #attestations )
81+ - [ Modified ` process_attestation ` ] ( #modified-process_attestation )
7782 - [ Deposits] ( #deposits )
78- - [ Updated ` apply_deposit ` ] ( #updated--apply_deposit )
79- - [ New ` is_valid_deposit_signature ` ] ( #new-is_valid_deposit_signature )
80- - [ Modified ` add_validator_to_registry ` ] ( #modified-add_validator_to_registry )
81- - [ Updated ` get_validator_from_deposit ` ] ( #updated-get_validator_from_deposit )
82- - [ New ` process_deposit_receipt ` ] ( #new-process_deposit_receipt )
83- - [ New ` process_execution_layer_withdrawal_request ` ] ( #new-process_execution_layer_withdrawal_request )
84- - [ Modified ` process_execution_payload ` ] ( #modified-process_execution_payload )
85- - [ New ` process_consolidation ` ] ( #new-process_consolidation )
86- - [ Updated ` process_voluntary_exit ` ] ( #updated-process_voluntary_exit )
83+ - [ Updated ` apply_deposit ` ] ( #updated--apply_deposit )
84+ - [ New ` is_valid_deposit_signature ` ] ( #new-is_valid_deposit_signature )
85+ - [ Modified ` add_validator_to_registry ` ] ( #modified-add_validator_to_registry )
86+ - [ Updated ` get_validator_from_deposit ` ] ( #updated-get_validator_from_deposit )
87+ - [ Voluntary exits] ( #voluntary-exits )
88+ - [ Updated ` process_voluntary_exit ` ] ( #updated-process_voluntary_exit )
89+ - [ Execution layer withdrawal requests] ( #execution-layer-withdrawal-requests )
90+ - [ New ` process_execution_layer_withdrawal_request ` ] ( #new-process_execution_layer_withdrawal_request )
91+ - [ Deposit receipts] ( #deposit-receipts )
92+ - [ New ` process_deposit_receipt ` ] ( #new-process_deposit_receipt )
93+ - [ Consolidations] ( #consolidations )
94+ - [ New ` process_consolidation ` ] ( #new-process_consolidation )
8795- [ Testing] ( #testing )
8896
8997<!-- END doctoc generated TOC please keep comment here to allow auto update -->
@@ -815,7 +823,9 @@ def process_block(state: BeaconState, block: BeaconBlock) -> None:
815823 process_sync_aggregate(state, block.body.sync_aggregate)
816824```
817825
818- #### Updated ` get_expected_withdrawals `
826+ #### Withdrawals
827+
828+ ##### Updated ` get_expected_withdrawals `
819829
820830``` python
821831def get_expected_withdrawals (state : BeaconState) -> Tuple[Sequence[Withdrawal], uint64]:
@@ -871,7 +881,7 @@ def get_expected_withdrawals(state: BeaconState) -> Tuple[Sequence[Withdrawal],
871881 return withdrawals, partial_withdrawals_count
872882```
873883
874- #### Updated ` process_withdrawals `
884+ ##### Updated ` process_withdrawals `
875885
876886``` python
877887def process_withdrawals (state : BeaconState, payload : ExecutionPayload) -> None :
@@ -903,8 +913,60 @@ def process_withdrawals(state: BeaconState, payload: ExecutionPayload) -> None:
903913 state.next_withdrawal_validator_index = next_validator_index
904914```
905915
916+ #### Execution payload
917+
918+ ##### Modified ` process_execution_payload `
906919
907- #### Modified ` process_operations `
920+ * Note* : The function ` process_execution_payload ` is modified to use the new ` ExecutionPayloadHeader ` type.
921+
922+ ``` python
923+ def process_execution_payload (state : BeaconState, body : BeaconBlockBody, execution_engine : ExecutionEngine) -> None :
924+ payload = body.execution_payload
925+
926+ # Verify consistency of the parent hash with respect to the previous execution payload header
927+ assert payload.parent_hash == state.latest_execution_payload_header.block_hash
928+ # Verify prev_randao
929+ assert payload.prev_randao == get_randao_mix(state, get_current_epoch(state))
930+ # Verify timestamp
931+ assert payload.timestamp == compute_timestamp_at_slot(state, state.slot)
932+ # Verify commitments are under limit
933+ assert len (body.blob_kzg_commitments) <= MAX_BLOBS_PER_BLOCK
934+ # Verify the execution payload is valid
935+ versioned_hashes = [kzg_commitment_to_versioned_hash(commitment) for commitment in body.blob_kzg_commitments]
936+ assert execution_engine.verify_and_notify_new_payload(
937+ NewPayloadRequest(
938+ execution_payload = payload,
939+ versioned_hashes = versioned_hashes,
940+ parent_beacon_block_root = state.latest_block_header.parent_root,
941+ )
942+ )
943+ # Cache execution payload header
944+ state.latest_execution_payload_header = ExecutionPayloadHeader(
945+ parent_hash = payload.parent_hash,
946+ fee_recipient = payload.fee_recipient,
947+ state_root = payload.state_root,
948+ receipts_root = payload.receipts_root,
949+ logs_bloom = payload.logs_bloom,
950+ prev_randao = payload.prev_randao,
951+ block_number = payload.block_number,
952+ gas_limit = payload.gas_limit,
953+ gas_used = payload.gas_used,
954+ timestamp = payload.timestamp,
955+ extra_data = payload.extra_data,
956+ base_fee_per_gas = payload.base_fee_per_gas,
957+ block_hash = payload.block_hash,
958+ transactions_root = hash_tree_root(payload.transactions),
959+ withdrawals_root = hash_tree_root(payload.withdrawals),
960+ blob_gas_used = payload.blob_gas_used,
961+ excess_blob_gas = payload.excess_blob_gas,
962+ deposit_receipts_root = hash_tree_root(payload.deposit_receipts), # [New in Electra:EIP6110]
963+ withdrawal_requests_root = hash_tree_root(payload.withdrawal_requests), # [New in Electra:EIP7002:EIP7251]
964+ )
965+ ```
966+
967+ #### Operations
968+
969+ ##### Modified ` process_operations `
908970
909971* Note* : The function ` process_operations ` is modified to support all of the new functionality in Electra.
910972
@@ -934,7 +996,9 @@ def process_operations(state: BeaconState, body: BeaconBlockBody) -> None:
934996 for_ops(body.consolidations, process_consolidation) # [New in Electra:EIP7251]
935997```
936998
937- #### Modified ` process_attestation `
999+ ##### Attestations
1000+
1001+ ###### Modified ` process_attestation `
9381002
9391003``` python
9401004def process_attestation (state : BeaconState, attestation : Attestation) -> None :
@@ -981,7 +1045,7 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None:
9811045
9821046##### Deposits
9831047
984- ##### Updated ` apply_deposit `
1048+ ###### Updated ` apply_deposit `
9851049
9861050* NOTE* : ` process_deposit ` is updated with a new definition of ` apply_deposit ` .
9871051
@@ -1012,7 +1076,7 @@ def apply_deposit(state: BeaconState,
10121076
10131077```
10141078
1015- ##### New ` is_valid_deposit_signature `
1079+ ###### New ` is_valid_deposit_signature `
10161080
10171081``` python
10181082def is_valid_deposit_signature (pubkey : BLSPubkey,
@@ -1029,7 +1093,7 @@ def is_valid_deposit_signature(pubkey: BLSPubkey,
10291093 return bls.Verify(pubkey, signing_root, signature)
10301094```
10311095
1032- ##### Modified ` add_validator_to_registry `
1096+ ###### Modified ` add_validator_to_registry `
10331097
10341098``` python
10351099def add_validator_to_registry (state : BeaconState,
@@ -1046,7 +1110,7 @@ def add_validator_to_registry(state: BeaconState,
10461110 state.pending_balance_deposits.append(PendingBalanceDeposit(index = index, amount = amount)) # [New in Electra:EIP7251]
10471111```
10481112
1049- ##### Updated ` get_validator_from_deposit `
1113+ ###### Updated ` get_validator_from_deposit `
10501114
10511115``` python
10521116def get_validator_from_deposit (pubkey : BLSPubkey, withdrawal_credentials : Bytes32) -> Validator:
@@ -1061,26 +1125,34 @@ def get_validator_from_deposit(pubkey: BLSPubkey, withdrawal_credentials: Bytes3
10611125 )
10621126```
10631127
1064- ##### New ` process_deposit_receipt `
1065-
1066- * Note* : This function is new in Electra: EIP6110 .
1128+ ##### Voluntary exits
1129+ ###### Updated ` process_voluntary_exit `
10671130
10681131``` python
1069- def process_deposit_receipt (state : BeaconState, deposit_receipt : DepositReceipt) -> None :
1070- # Set deposit receipt start index
1071- if state.deposit_receipts_start_index == UNSET_DEPOSIT_RECEIPTS_START_INDEX :
1072- state.deposit_receipts_start_index = deposit_receipt.index
1073-
1074- apply_deposit(
1075- state = state,
1076- pubkey = deposit_receipt.pubkey,
1077- withdrawal_credentials = deposit_receipt.withdrawal_credentials,
1078- amount = deposit_receipt.amount,
1079- signature = deposit_receipt.signature,
1080- )
1132+ def process_voluntary_exit (state : BeaconState, signed_voluntary_exit : SignedVoluntaryExit) -> None :
1133+ voluntary_exit = signed_voluntary_exit.message
1134+ validator = state.validators[voluntary_exit.validator_index]
1135+ # Verify the validator is active
1136+ assert is_active_validator(validator, get_current_epoch(state))
1137+ # Verify exit has not been initiated
1138+ assert validator.exit_epoch == FAR_FUTURE_EPOCH
1139+ # Exits must specify an epoch when they become valid; they are not valid before then
1140+ assert get_current_epoch(state) >= voluntary_exit.epoch
1141+ # Verify the validator has been active long enough
1142+ assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
1143+ # Only exit validator if it has no pending withdrawals in the queue
1144+ assert get_pending_balance_to_withdraw(state, voluntary_exit.validator_index) == 0 # [New in Electra:EIP7251]
1145+ # Verify signature
1146+ domain = compute_domain(DOMAIN_VOLUNTARY_EXIT , CAPELLA_FORK_VERSION , state.genesis_validators_root)
1147+ signing_root = compute_signing_root(voluntary_exit, domain)
1148+ assert bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature)
1149+ # Initiate exit
1150+ initiate_validator_exit(state, voluntary_exit.validator_index)
10811151```
10821152
1083- #### New ` process_execution_layer_withdrawal_request `
1153+ ##### Execution layer withdrawal requests
1154+
1155+ ###### New ` process_execution_layer_withdrawal_request `
10841156
10851157* Note* : This function is new in Electra following EIP-7002 and EIP-7251.
10861158
@@ -1147,56 +1219,30 @@ def process_execution_layer_withdrawal_request(
11471219 ))
11481220```
11491221
1150- #### Modified ` process_execution_payload `
1222+ ##### Deposit receipts
11511223
1152- * Note* : The function ` process_execution_payload ` is modified to use the new ` ExecutionPayloadHeader ` type.
1224+ ###### New ` process_deposit_receipt `
1225+
1226+ * Note* : This function is new in Electra: EIP6110 .
11531227
11541228``` python
1155- def process_execution_payload (state : BeaconState, body : BeaconBlockBody, execution_engine : ExecutionEngine) -> None :
1156- payload = body.execution_payload
1229+ def process_deposit_receipt (state : BeaconState, deposit_receipt : DepositReceipt) -> None :
1230+ # Set deposit receipt start index
1231+ if state.deposit_receipts_start_index == UNSET_DEPOSIT_RECEIPTS_START_INDEX :
1232+ state.deposit_receipts_start_index = deposit_receipt.index
11571233
1158- # Verify consistency of the parent hash with respect to the previous execution payload header
1159- assert payload.parent_hash == state.latest_execution_payload_header.block_hash
1160- # Verify prev_randao
1161- assert payload.prev_randao == get_randao_mix(state, get_current_epoch(state))
1162- # Verify timestamp
1163- assert payload.timestamp == compute_timestamp_at_slot(state, state.slot)
1164- # Verify commitments are under limit
1165- assert len (body.blob_kzg_commitments) <= MAX_BLOBS_PER_BLOCK
1166- # Verify the execution payload is valid
1167- versioned_hashes = [kzg_commitment_to_versioned_hash(commitment) for commitment in body.blob_kzg_commitments]
1168- assert execution_engine.verify_and_notify_new_payload(
1169- NewPayloadRequest(
1170- execution_payload = payload,
1171- versioned_hashes = versioned_hashes,
1172- parent_beacon_block_root = state.latest_block_header.parent_root,
1173- )
1174- )
1175- # Cache execution payload header
1176- state.latest_execution_payload_header = ExecutionPayloadHeader(
1177- parent_hash = payload.parent_hash,
1178- fee_recipient = payload.fee_recipient,
1179- state_root = payload.state_root,
1180- receipts_root = payload.receipts_root,
1181- logs_bloom = payload.logs_bloom,
1182- prev_randao = payload.prev_randao,
1183- block_number = payload.block_number,
1184- gas_limit = payload.gas_limit,
1185- gas_used = payload.gas_used,
1186- timestamp = payload.timestamp,
1187- extra_data = payload.extra_data,
1188- base_fee_per_gas = payload.base_fee_per_gas,
1189- block_hash = payload.block_hash,
1190- transactions_root = hash_tree_root(payload.transactions),
1191- withdrawals_root = hash_tree_root(payload.withdrawals),
1192- blob_gas_used = payload.blob_gas_used,
1193- excess_blob_gas = payload.excess_blob_gas,
1194- deposit_receipts_root = hash_tree_root(payload.deposit_receipts), # [New in Electra:EIP6110]
1195- withdrawal_requests_root = hash_tree_root(payload.withdrawal_requests), # [New in Electra:EIP7002:EIP7251]
1234+ apply_deposit(
1235+ state = state,
1236+ pubkey = deposit_receipt.pubkey,
1237+ withdrawal_credentials = deposit_receipt.withdrawal_credentials,
1238+ amount = deposit_receipt.amount,
1239+ signature = deposit_receipt.signature,
11961240 )
11971241```
11981242
1199- #### New ` process_consolidation `
1243+ ##### Consolidations
1244+
1245+ ###### New ` process_consolidation `
12001246
12011247``` python
12021248def process_consolidation (state : BeaconState, signed_consolidation : SignedConsolidation) -> None :
@@ -1245,30 +1291,6 @@ def process_consolidation(state: BeaconState, signed_consolidation: SignedConsol
12451291 ))
12461292```
12471293
1248- #### Updated ` process_voluntary_exit `
1249-
1250- ``` python
1251- def process_voluntary_exit (state : BeaconState, signed_voluntary_exit : SignedVoluntaryExit) -> None :
1252- voluntary_exit = signed_voluntary_exit.message
1253- validator = state.validators[voluntary_exit.validator_index]
1254- # Verify the validator is active
1255- assert is_active_validator(validator, get_current_epoch(state))
1256- # Verify exit has not been initiated
1257- assert validator.exit_epoch == FAR_FUTURE_EPOCH
1258- # Exits must specify an epoch when they become valid; they are not valid before then
1259- assert get_current_epoch(state) >= voluntary_exit.epoch
1260- # Verify the validator has been active long enough
1261- assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
1262- # Only exit validator if it has no pending withdrawals in the queue
1263- assert get_pending_balance_to_withdraw(state, voluntary_exit.validator_index) == 0 # [New in Electra:EIP7251]
1264- # Verify signature
1265- domain = compute_domain(DOMAIN_VOLUNTARY_EXIT , CAPELLA_FORK_VERSION , state.genesis_validators_root)
1266- signing_root = compute_signing_root(voluntary_exit, domain)
1267- assert bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature)
1268- # Initiate exit
1269- initiate_validator_exit(state, voluntary_exit.validator_index)
1270- ```
1271-
12721294## Testing
12731295
12741296* Note* : The function ` initialize_beacon_state_from_eth1 ` is modified for pure Electra testing only.
0 commit comments