diff --git a/cairo_vm_hints/src/cairo_types/new_syscalls.rs b/cairo_vm_hints/src/cairo_types/new_syscalls.rs index a60d7637..866abf88 100644 --- a/cairo_vm_hints/src/cairo_types/new_syscalls.rs +++ b/cairo_vm_hints/src/cairo_types/new_syscalls.rs @@ -1,5 +1,5 @@ use crate::cairo_types::traits::CairoType; -use cairo_type_derive::{CairoType, FieldOffsetGetters}; +use cairo_type_derive::FieldOffsetGetters; use cairo_vm::{ types::relocatable::Relocatable, vm::{errors::memory_errors::MemoryError, vm_core::VirtualMachine}, @@ -7,20 +7,64 @@ use cairo_vm::{ }; #[allow(unused)] -#[derive(FieldOffsetGetters, CairoType)] +#[derive(FieldOffsetGetters, Debug)] pub struct CallContractRequest { // The address of the L2 contract to call. pub contract_address: Felt252, // The selector of the function to call. pub selector: Felt252, // The calldata. - pub calldata_start: Felt252, - pub calldata_end: Felt252, + pub calldata_start: Relocatable, + pub calldata_end: Relocatable, +} + +impl CairoType for CallContractRequest { + fn from_memory(vm: &VirtualMachine, address: Relocatable) -> Result { + let contract_address = *vm.get_integer((address + 0)?)?; + let selector = *vm.get_integer((address + 1)?)?; + let calldata_start = vm.get_relocatable((address + 2)?)?; + let calldata_end = vm.get_relocatable((address + 3)?)?; + Ok(Self { + contract_address, + selector, + calldata_start, + calldata_end, + }) + } + fn to_memory(&self, vm: &mut VirtualMachine, address: Relocatable) -> Result<(), MemoryError> { + vm.insert_value((address + 0)?, self.contract_address)?; + vm.insert_value((address + 1)?, self.selector)?; + vm.insert_value((address + 2)?, self.calldata_start)?; + vm.insert_value((address + 3)?, self.calldata_end)?; + Ok(()) + } + fn n_fields() -> usize { + 4 + } } #[allow(unused)] -#[derive(FieldOffsetGetters, CairoType)] +#[derive(FieldOffsetGetters, Debug)] pub struct CallContractResponse { - pub retdata_start: Felt252, - pub retdata_end: Felt252, + pub retdata_start: Relocatable, + pub retdata_end: Relocatable, +} + +impl CairoType for CallContractResponse { + fn from_memory(vm: &VirtualMachine, address: Relocatable) -> Result { + let retdata_start = vm.get_relocatable((address + 0)?)?; + let retdata_end = vm.get_relocatable((address + 1)?)?; + Ok(Self { + retdata_start, + retdata_end, + }) + } + fn to_memory(&self, vm: &mut VirtualMachine, address: Relocatable) -> Result<(), MemoryError> { + vm.insert_value((address + 0)?, self.retdata_start)?; + vm.insert_value((address + 1)?, self.retdata_end)?; + Ok(()) + } + fn n_fields() -> usize { + 2 + } } diff --git a/cairo_vm_hints/src/syscall_handler/call_contract.rs b/cairo_vm_hints/src/syscall_handler/call_contract.rs index fb49115d..f767105e 100644 --- a/cairo_vm_hints/src/syscall_handler/call_contract.rs +++ b/cairo_vm_hints/src/syscall_handler/call_contract.rs @@ -1,9 +1,13 @@ -use super::utils::{SyscallHandler, SyscallResult, WriteResponseResult}; +use super::utils::{SyscallExecutionError, SyscallHandler, SyscallResult, WriteResponseResult}; use crate::cairo_types::{ new_syscalls::{CallContractRequest, CallContractResponse}, traits::CairoType, }; -use cairo_vm::{types::relocatable::Relocatable, vm::vm_core::VirtualMachine, Felt252}; +use cairo_vm::{ + types::relocatable::{MaybeRelocatable, Relocatable}, + vm::vm_core::VirtualMachine, + Felt252, +}; pub struct CallContractHandler; @@ -17,10 +21,32 @@ impl SyscallHandler for CallContractHandler { Ok(ret) } - fn execute(_request: Self::Request, _vm: &mut VirtualMachine) -> SyscallResult { + fn execute(request: Self::Request, vm: &mut VirtualMachine) -> SyscallResult { + let _calldata: Vec = vm + .get_range( + request.calldata_start, + (request.calldata_end - request.calldata_start)?, + ) + .into_iter() + .map(|f| f.and_then(|f| f.get_int())) + .collect::>>() + .ok_or(SyscallExecutionError::InternalError( + "Memory error: failed to read full calldata" + .to_string() + .into(), + ))?; + + // SYSCALL HANDLER LOGIC HERE! + + let retdata = vm.add_temporary_segment(); + let data = vec![ + MaybeRelocatable::from(Felt252::TWO), + MaybeRelocatable::from(Felt252::THREE), + ]; + vm.load_data(retdata, &data)?; Ok(Self::Response { - retdata_start: Felt252::from(0_u32), - retdata_end: Felt252::from(1_u32), + retdata_start: retdata, + retdata_end: (retdata + data.len())?, }) } diff --git a/cairo_vm_hints/src/syscall_handler/utils.rs b/cairo_vm_hints/src/syscall_handler/utils.rs index 611ee905..c09f7791 100644 --- a/cairo_vm_hints/src/syscall_handler/utils.rs +++ b/cairo_vm_hints/src/syscall_handler/utils.rs @@ -212,8 +212,6 @@ fn write_failure( Ok(()) } -// Dummy value we dont use gas in HDP runtime -pub const REMAINING_GAS: Felt252 = Felt252::from_hex_unchecked("0xffffff"); pub const OUT_OF_GAS_ERROR: &str = "0x000000000000000000000000000000000000000000004f7574206f6620676173"; @@ -224,17 +222,17 @@ pub fn run_handler( where SH: SyscallHandler, { + let remaining_gas = felt_from_ptr(vm, syscall_ptr)?; let request = SH::read_request(vm, syscall_ptr)?; let syscall_result = SH::execute(request, vm); match syscall_result { Ok(response) => { - write_felt(vm, syscall_ptr, REMAINING_GAS)?; - // 0 to indicate success. + write_felt(vm, syscall_ptr, remaining_gas)?; write_felt(vm, syscall_ptr, Felt252::ZERO)?; SH::write_response(response, vm, syscall_ptr)? } Err(SyscallExecutionError::SyscallError { error_data: data }) => { - write_failure(REMAINING_GAS, data, vm, syscall_ptr)?; + write_failure(Felt252::ZERO, data, vm, syscall_ptr)?; } Err(error) => return Err(error.into()), };