Skip to content

Commit

Permalink
working syscall handler
Browse files Browse the repository at this point in the history
  • Loading branch information
Okm165 committed Nov 28, 2024
1 parent 431a3ed commit 5146915
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 17 deletions.
58 changes: 51 additions & 7 deletions cairo_vm_hints/src/cairo_types/new_syscalls.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,70 @@
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},
Felt252,
};

#[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<Self, MemoryError> {
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<Self, MemoryError> {
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
}
}
36 changes: 31 additions & 5 deletions cairo_vm_hints/src/syscall_handler/call_contract.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -17,10 +21,32 @@ impl SyscallHandler for CallContractHandler {
Ok(ret)
}

fn execute(_request: Self::Request, _vm: &mut VirtualMachine) -> SyscallResult<Self::Response> {
fn execute(request: Self::Request, vm: &mut VirtualMachine) -> SyscallResult<Self::Response> {
let _calldata: Vec<Felt252> = vm
.get_range(
request.calldata_start,
(request.calldata_end - request.calldata_start)?,
)
.into_iter()
.map(|f| f.and_then(|f| f.get_int()))
.collect::<Option<Vec<Felt252>>>()
.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())?,
})
}

Expand Down
8 changes: 3 additions & 5 deletions cairo_vm_hints/src/syscall_handler/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand All @@ -224,17 +222,17 @@ pub fn run_handler<SH>(
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()),
};
Expand Down

0 comments on commit 5146915

Please sign in to comment.