diff --git a/crates/apollo_batcher/src/cende_client_types.rs b/crates/apollo_batcher/src/cende_client_types.rs index ef511ce5437..2211e8a535e 100644 --- a/crates/apollo_batcher/src/cende_client_types.rs +++ b/crates/apollo_batcher/src/cende_client_types.rs @@ -255,7 +255,8 @@ fn get_l2_to_l1_messages(execution_info: &TransactionExecutionInfo) -> Vec CallInfo { l2_to_l1_messages: vec![OrderedL2ToL1Message { order: 1, message: MessageToL1 { - to_address: EthAddress::try_from(felt!(1_u8)).unwrap(), + to_address: L1Address::from(felt!(1_u8)), payload: L2ToL1Payload(felt_vector()), }, }], diff --git a/crates/apollo_rpc_execution/src/objects.rs b/crates/apollo_rpc_execution/src/objects.rs index dd94d6c6501..a90c6db8fa4 100644 --- a/crates/apollo_rpc_execution/src/objects.rs +++ b/crates/apollo_rpc_execution/src/objects.rs @@ -29,6 +29,7 @@ use starknet_api::core::{ ClassHash, ContractAddress, EntryPointSelector, + EthAddress, Nonce, SequencerContractAddress, }; @@ -463,7 +464,8 @@ impl OrderedL2ToL1Message { order: blockifier_message.order, message: MessageToL1 { from_address, - to_address: blockifier_message.message.to_address, + to_address: EthAddress::try_from(blockifier_message.message.to_address) + .expect("Failed to convert L1Address to EthAddress"), payload: blockifier_message.message.payload, }, } diff --git a/crates/blockifier/src/execution/call_info.rs b/crates/blockifier/src/execution/call_info.rs index 124549634bb..33a82b304dc 100644 --- a/crates/blockifier/src/execution/call_info.rs +++ b/crates/blockifier/src/execution/call_info.rs @@ -6,7 +6,7 @@ use cairo_vm::types::builtin_name::BuiltinName; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use serde::Serialize; use starknet_api::block::{BlockHash, BlockNumber}; -use starknet_api::core::{ClassHash, ContractAddress, EthAddress}; +use starknet_api::core::{ClassHash, ContractAddress, L1Address}; use starknet_api::execution_resources::{GasAmount, GasVector}; use starknet_api::state::StorageKey; use starknet_api::transaction::fields::GasVectorComputationMode; @@ -43,7 +43,7 @@ pub struct OrderedEvent { #[cfg_attr(feature = "transaction_serde", derive(serde::Deserialize))] #[derive(Debug, Default, Eq, PartialEq, Serialize)] pub struct MessageToL1 { - pub to_address: EthAddress, + pub to_address: L1Address, pub payload: L2ToL1Payload, } diff --git a/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs b/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs index 7eed2870bfb..a2b1cef15d0 100644 --- a/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs +++ b/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs @@ -23,6 +23,7 @@ use starknet_api::core::{ ClassHash, ContractAddress, EntryPointSelector, + EthAddress, }; use starknet_api::state::StorageKey; use starknet_api::transaction::constants::EXECUTE_ENTRY_POINT_NAME; @@ -757,6 +758,9 @@ impl DeprecatedSyscallExecutor for DeprecatedSyscallHintProcessor<'_> { syscall_handler: &mut Self, ) -> DeprecatedSyscallResult { let execution_context = &mut syscall_handler.context; + if !execution_context.tx_context.block_context.chain_info.is_l3 { + EthAddress::try_from(request.message.to_address)?; + } let ordered_message_to_l1 = OrderedL2ToL1Message { order: execution_context.n_sent_messages_to_l1, message: request.message, diff --git a/crates/blockifier/src/execution/deprecated_syscalls/mod.rs b/crates/blockifier/src/execution/deprecated_syscalls/mod.rs index 700ae0da402..9648e7421e5 100644 --- a/crates/blockifier/src/execution/deprecated_syscalls/mod.rs +++ b/crates/blockifier/src/execution/deprecated_syscalls/mod.rs @@ -6,7 +6,7 @@ use deprecated_syscall_executor::{ }; use serde::Deserialize; use starknet_api::block::{BlockNumber, BlockTimestamp}; -use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector, EthAddress}; +use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector}; use starknet_api::state::StorageKey; use starknet_api::transaction::fields::{Calldata, ContractAddressSalt}; use starknet_api::transaction::{EventContent, EventData, EventKey, L2ToL1Payload}; @@ -424,7 +424,8 @@ impl SyscallRequest for SendMessageToL1Request { vm: &VirtualMachine, ptr: &mut Relocatable, ) -> DeprecatedSyscallExecutorBaseResult { - let to_address = EthAddress::try_from(felt_from_ptr(vm, ptr)?)?; + let to_address_felt = felt_from_ptr(vm, ptr)?; + let to_address = to_address_felt.into(); let payload = L2ToL1Payload(read_felt_array::(vm, ptr)?); diff --git a/crates/blockifier/src/execution/native/syscall_handler.rs b/crates/blockifier/src/execution/native/syscall_handler.rs index 426fda21862..3c4233658ad 100644 --- a/crates/blockifier/src/execution/native/syscall_handler.rs +++ b/crates/blockifier/src/execution/native/syscall_handler.rs @@ -18,7 +18,7 @@ use cairo_native::starknet::{ }; use num_bigint::BigUint; use starknet_api::contract_class::EntryPointType; -use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector, EthAddress}; +use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector, L1Address}; use starknet_api::execution_resources::GasAmount; use starknet_api::state::StorageKey; use starknet_api::transaction::fields::{Calldata, ContractAddressSalt, TransactionSignature}; @@ -568,8 +568,7 @@ impl StarknetSyscallHandler for &mut NativeSyscallHandler<'_> { self.gas_costs().syscalls.send_message_to_l1.base_syscall_cost(), )?; - let to_address = EthAddress::try_from(to_address) - .map_err(|err| self.handle_error(remaining_gas, err.into()))?; + let to_address = L1Address::from(to_address); let message = MessageToL1 { to_address, payload: L2ToL1Payload(payload.to_vec()) }; self.base.send_message_to_l1(message).map_err(|err| self.handle_error(remaining_gas, err)) diff --git a/crates/blockifier/src/execution/syscalls/syscall_base.rs b/crates/blockifier/src/execution/syscalls/syscall_base.rs index 2f2f22fde3e..3469344e7a1 100644 --- a/crates/blockifier/src/execution/syscalls/syscall_base.rs +++ b/crates/blockifier/src/execution/syscalls/syscall_base.rs @@ -11,6 +11,7 @@ use starknet_api::core::{ ClassHash, ContractAddress, EntryPointSelector, + EthAddress, Nonce, }; use starknet_api::state::StorageKey; @@ -391,6 +392,9 @@ impl<'state> SyscallHandlerBase<'state> { } pub fn send_message_to_l1(&mut self, message: MessageToL1) -> SyscallResult<()> { + if !self.context.tx_context.block_context.chain_info.is_l3 { + EthAddress::try_from(message.to_address)?; + } let ordered_message_to_l1 = OrderedL2ToL1Message { order: self.context.n_sent_messages_to_l1, message }; self.l2_to_l1_messages.push(ordered_message_to_l1); diff --git a/crates/blockifier/src/execution/syscalls/syscall_tests/send_message_to_l1.rs b/crates/blockifier/src/execution/syscalls/syscall_tests/send_message_to_l1.rs index b2bf68509bd..e4e4a80a8aa 100644 --- a/crates/blockifier/src/execution/syscalls/syscall_tests/send_message_to_l1.rs +++ b/crates/blockifier/src/execution/syscalls/syscall_tests/send_message_to_l1.rs @@ -42,7 +42,8 @@ fn test_send_message_to_l1(runnable_version: RunnableCairo1) { ..trivial_external_entry_point_new(test_contract) }; - let to_address = EthAddress::try_from(to_address).unwrap(); + let to_address = + EthAddress::try_from(to_address).expect("Failed to convert Felt to EthAddress").into(); let message = MessageToL1 { to_address, payload: L2ToL1Payload(payload) }; let mut execution = entry_point_call.execute_directly(&mut state).unwrap().execution; @@ -58,8 +59,8 @@ fn test_send_message_to_l1(runnable_version: RunnableCairo1) { OrderedL2ToL1Message { order: 0, message: MessageToL1 { - to_address: EthAddress( - 0x00000000000000000000000000000000000004d2, + to_address: L1Address( + 0x4d2, ), payload: L2ToL1Payload( [ diff --git a/crates/blockifier/src/execution/syscalls/vm_syscall_utils.rs b/crates/blockifier/src/execution/syscalls/vm_syscall_utils.rs index f0196b3af99..07410131ac0 100644 --- a/crates/blockifier/src/execution/syscalls/vm_syscall_utils.rs +++ b/crates/blockifier/src/execution/syscalls/vm_syscall_utils.rs @@ -10,7 +10,7 @@ use cairo_vm::vm::vm_core::VirtualMachine; use num_traits::ToPrimitive; use serde::Serialize; use starknet_api::block::{BlockHash, BlockNumber}; -use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector, EthAddress}; +use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector}; use starknet_api::execution_resources::GasAmount; use starknet_api::state::StorageKey; use starknet_api::transaction::fields::{Calldata, ContractAddressSalt, TransactionSignature}; @@ -405,7 +405,8 @@ impl SyscallRequest for SendMessageToL1Request { vm: &VirtualMachine, ptr: &mut Relocatable, ) -> SyscallBaseResult { - let to_address = EthAddress::try_from(felt_from_ptr(vm, ptr)?)?; + let to_address_felt = felt_from_ptr(vm, ptr)?; + let to_address = to_address_felt.into(); let payload = L2ToL1Payload(read_felt_array::(vm, ptr)?); Ok(SendMessageToL1Request { message: MessageToL1 { to_address, payload } }) diff --git a/crates/blockifier/src/transaction/objects_test.rs b/crates/blockifier/src/transaction/objects_test.rs index 4a0c7382d1a..22a3c61eef5 100644 --- a/crates/blockifier/src/transaction/objects_test.rs +++ b/crates/blockifier/src/transaction/objects_test.rs @@ -1,6 +1,6 @@ use cairo_vm::types::builtin_name::BuiltinName; use rstest::rstest; -use starknet_api::core::{ClassHash, ContractAddress, EthAddress}; +use starknet_api::core::{ClassHash, ContractAddress, L1Address}; use starknet_api::execution_resources::GasAmount; use starknet_api::state::StorageKey; use starknet_api::transaction::L2ToL1Payload; @@ -77,7 +77,7 @@ impl TestExecutionSummary { .map(|i| OrderedL2ToL1Message { order: i, message: MessageToL1 { - to_address: EthAddress::default(), + to_address: L1Address::default(), payload: L2ToL1Payload(vec![Felt::default()]), }, }) diff --git a/crates/blockifier/src/transaction/transactions_test.rs b/crates/blockifier/src/transaction/transactions_test.rs index 7e0bc28685d..84860a72a74 100644 --- a/crates/blockifier/src/transaction/transactions_test.rs +++ b/crates/blockifier/src/transaction/transactions_test.rs @@ -20,7 +20,7 @@ use starknet_api::abi::abi_utils::{ use starknet_api::abi::constants::CONSTRUCTOR_ENTRY_POINT_NAME; use starknet_api::block::{FeeType, GasPriceVector}; use starknet_api::contract_class::EntryPointType; -use starknet_api::core::{ascii_as_felt, ClassHash, ContractAddress, EthAddress, Nonce}; +use starknet_api::core::{ascii_as_felt, ClassHash, ContractAddress, Nonce}; use starknet_api::executable_transaction::{ AccountTransaction as ApiExecutableTransaction, DeployAccountTransaction, @@ -951,7 +951,7 @@ fn test_invoke_tx_advanced_operations( let expected_msg = OrderedL2ToL1Message { order: 0, message: MessageToL1 { - to_address: EthAddress::try_from(to_address).unwrap(), + to_address: to_address.into(), payload: L2ToL1Payload(vec![felt!(12_u32), felt!(34_u32)]), }, }; diff --git a/crates/starknet_api/src/core.rs b/crates/starknet_api/src/core.rs index 75b87f35fa7..41b7898e16e 100644 --- a/crates/starknet_api/src/core.rs +++ b/crates/starknet_api/src/core.rs @@ -459,6 +459,51 @@ macro_rules! contract_address { #[serde(try_from = "PrefixedBytesAsHex<20_usize>", into = "PrefixedBytesAsHex<20_usize>")] pub struct EthAddress(pub H160); +#[derive( + Debug, Copy, Clone, Default, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord, +)] +pub struct L1Address(pub Felt); + +impl From for L1Address { + fn from(address: ContractAddress) -> Self { + L1Address(address.0.0) + } +} + +impl TryFrom for ContractAddress { + type Error = StarknetApiError; + + fn try_from(address: L1Address) -> Result { + Ok(ContractAddress(PatriciaKey::try_from(address.0)?)) + } +} + +impl From for L1Address { + fn from(address: EthAddress) -> Self { + L1Address(address.into()) + } +} + +impl TryFrom for EthAddress { + type Error = StarknetApiError; + + fn try_from(address: L1Address) -> Result { + EthAddress::try_from(address.0) + } +} + +impl From for L1Address { + fn from(felt: Felt) -> Self { + L1Address(felt) + } +} + +impl From for Felt { + fn from(address: L1Address) -> Self { + address.0 + } +} + impl TryFrom for EthAddress { type Error = StarknetApiError; fn try_from(felt: Felt) -> Result {