diff --git a/ethereum-consensus/src/capella/block_processing.rs b/ethereum-consensus/src/capella/block_processing.rs index 744bcc2fe..07cc1be94 100644 --- a/ethereum-consensus/src/capella/block_processing.rs +++ b/ethereum-consensus/src/capella/block_processing.rs @@ -1,11 +1,15 @@ use crate::{ capella::{ - compute_timestamp_at_slot, get_current_epoch, get_randao_mix, process_attestation, - process_attester_slashing, process_block_header, process_deposit, process_eth1_data, - process_proposer_slashing, process_randao, process_sync_aggregate, process_voluntary_exit, - BeaconBlock, BeaconBlockBody, BeaconState, ExecutionEngine, ExecutionPayload, + compute_domain, compute_signing_root, compute_timestamp_at_slot, get_current_epoch, + get_randao_mix, process_attestation, process_attester_slashing, process_block_header, + process_deposit, process_eth1_data, process_proposer_slashing, process_randao, + process_sync_aggregate, process_voluntary_exit, BeaconBlock, BeaconBlockBody, BeaconState, + BlsPublicKey, DomainType::BlsToExecutionChange, ExecutionEngine, ExecutionPayload, ExecutionPayloadHeader, NewPayloadRequest, SignedBlsToExecutionChange, }, + crypto::{hash, verify_signature}, + primitives::{BLS_WITHDRAWAL_PREFIX, ETH1_ADDRESS_WITHDRAWAL_PREFIX}, + ssz::ByteVector, state_transition::{ invalid_operation_error, Context, InvalidDeposit, InvalidExecutionPayload, InvalidOperation, Result, @@ -25,7 +29,7 @@ pub fn process_bls_to_execution_change< const BYTES_PER_LOGS_BLOOM: usize, const MAX_EXTRA_DATA_BYTES: usize, >( - _state: &mut BeaconState< + state: &mut BeaconState< SLOTS_PER_HISTORICAL_ROOT, HISTORICAL_ROOTS_LIMIT, ETH1_DATA_VOTES_BOUND, @@ -37,10 +41,33 @@ pub fn process_bls_to_execution_change< BYTES_PER_LOGS_BLOOM, MAX_EXTRA_DATA_BYTES, >, - _signed_address_change: &mut SignedBlsToExecutionChange, - _context: &Context, + signed_address_change: &mut SignedBlsToExecutionChange, + context: &Context, ) -> Result<()> { - unimplemented!() + let address_change = signed_address_change; + + assert!(address_change.message.validator_index < state.validators.len()); + + let validator = &mut state.validators[address_change.message.validator_index]; + + assert!(validator.withdrawal_credentials.starts_with(&[BLS_WITHDRAWAL_PREFIX])); + assert!( + validator.withdrawal_credentials[1..] + == hash(address_change.message.from_bls_public_key.as_ref())[1..] + ); + + let domain = + compute_domain(BlsToExecutionChange, None, Some(state.genesis_validators_root), context)?; + let signing_root = compute_signing_root(address_change, domain)?; + let pk: &BlsPublicKey = &address_change.message.from_bls_public_key; + assert!(verify_signature(&pk, signing_root.as_ref(), &address_change.signature,).is_ok()); + let withdrawal_credentials = vec![ETH1_ADDRESS_WITHDRAWAL_PREFIX]; + + let withdrawal_credentials_array: [u8; 32] = + withdrawal_credentials.try_into().expect("Wrong size"); + validator.withdrawal_credentials = ByteVector::try_from(withdrawal_credentials_array.as_ref()) + .expect("Failed to convert array to ByteVector"); + Ok(()) } pub fn process_operations< @@ -103,7 +130,7 @@ pub fn process_operations< expected: expected_deposit_count, count: body.deposits.len(), }, - ))) + ))); } body.proposer_slashings .iter_mut() @@ -175,7 +202,7 @@ pub fn process_execution_payload< expected: state.latest_execution_payload_header.block_hash.clone(), } .into(), - )) + )); } let current_epoch = get_current_epoch(state, context); @@ -187,7 +214,7 @@ pub fn process_execution_payload< expected: randao_mix.clone(), } .into(), - )) + )); } let timestamp = compute_timestamp_at_slot(state, state.slot, context)?; @@ -198,7 +225,7 @@ pub fn process_execution_payload< expected: timestamp, } .into(), - )) + )); } let new_payload_request = NewPayloadRequest(payload); diff --git a/ethereum-consensus/src/capella/bls_to_execution_change.rs b/ethereum-consensus/src/capella/bls_to_execution_change.rs index 10f094ab8..1304ef2b6 100644 --- a/ethereum-consensus/src/capella/bls_to_execution_change.rs +++ b/ethereum-consensus/src/capella/bls_to_execution_change.rs @@ -14,6 +14,6 @@ pub struct BlsToExecutionChange { #[derive(Default, Debug, Clone, SimpleSerialize, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct SignedBlsToExecutionChange { - message: BlsToExecutionChange, - signature: BlsSignature, + pub message: BlsToExecutionChange, + pub signature: BlsSignature, }