Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix syscall handler glue code array conversions. #502

Merged
merged 4 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 94 additions & 52 deletions src/starknet.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
//! Starknet related code for `cairo_native`

#![allow(clippy::type_complexity)]
#![allow(dead_code)]

use starknet_types_core::felt::Felt;

pub type SyscallResult<T> = std::result::Result<T, Vec<Felt>>;

#[repr(C)]
#[derive(Debug)]
pub struct ArrayAbi<T> {
pub ptr: *mut T,
pub since: u32,
pub until: u32,
pub capacity: u32,
}

/// Binary representation of a `Felt` (in MLIR).
#[derive(Debug, Clone)]
#[cfg_attr(target_arch = "x86_64", repr(C, align(8)))]
Expand Down Expand Up @@ -486,7 +492,7 @@ pub(crate) mod handler {
alloc::Layout,
fmt::Debug,
mem::{size_of, ManuallyDrop, MaybeUninit},
ptr::NonNull,
ptr::{null_mut, NonNull},
};

macro_rules! field_offset {
Expand Down Expand Up @@ -516,7 +522,7 @@ pub(crate) mod handler {
#[derive(Debug)]
pub(crate) struct SyscallResultAbiErr {
pub tag: u8,
pub payload: (NonNull<Felt252Abi>, u32, u32),
pub payload: ArrayAbi<Felt252Abi>,
}

#[repr(C)]
Expand All @@ -542,16 +548,16 @@ pub(crate) mod handler {
version: Felt252Abi,
account_contract_address: Felt252Abi,
max_fee: u128,
signature: (NonNull<Felt252Abi>, u32, u32),
signature: ArrayAbi<Felt252Abi>,
transaction_hash: Felt252Abi,
chain_id: Felt252Abi,
nonce: Felt252Abi,
resource_bounds: (NonNull<ResourceBoundsAbi>, u32, u32),
resource_bounds: ArrayAbi<ResourceBoundsAbi>,
tip: u128,
paymaster_data: (NonNull<Felt252Abi>, u32, u32),
paymaster_data: ArrayAbi<Felt252Abi>,
nonce_data_availability_mode: u32,
fee_data_availability_mode: u32,
account_deployment_data: (NonNull<Felt252Abi>, u32, u32),
account_deployment_data: ArrayAbi<Felt252Abi>,
}

#[repr(C)]
Expand All @@ -574,7 +580,7 @@ pub(crate) mod handler {
version: Felt252Abi,
account_contract_address: Felt252Abi,
max_fee: u128,
signature: (NonNull<Felt252Abi>, u32, u32),
signature: ArrayAbi<Felt252Abi>,
transaction_hash: Felt252Abi,
chain_id: Felt252Abi,
nonce: Felt252Abi,
Expand Down Expand Up @@ -602,12 +608,12 @@ pub(crate) mod handler {
gas: &mut u128,
),
deploy: extern "C" fn(
result_ptr: &mut SyscallResultAbi<(Felt252Abi, (NonNull<Felt252Abi>, u32, u32))>,
result_ptr: &mut SyscallResultAbi<(Felt252Abi, ArrayAbi<Felt252Abi>)>,
ptr: &mut T,
gas: &mut u128,
class_hash: &Felt252Abi,
contract_address_salt: &Felt252Abi,
calldata: *const (*const Felt252Abi, u32, u32),
calldata: &ArrayAbi<Felt252Abi>,
deploy_from_zero: bool,
),
replace_class: extern "C" fn(
Expand All @@ -617,20 +623,20 @@ pub(crate) mod handler {
class_hash: &Felt252Abi,
),
library_call: extern "C" fn(
result_ptr: &mut SyscallResultAbi<(NonNull<Felt252Abi>, u32, u32)>,
result_ptr: &mut SyscallResultAbi<ArrayAbi<Felt252Abi>>,
ptr: &mut T,
gas: &mut u128,
class_hash: &Felt252Abi,
function_selector: &Felt252Abi,
calldata: *const (*const Felt252Abi, u32, u32),
calldata: &ArrayAbi<Felt252Abi>,
),
call_contract: extern "C" fn(
result_ptr: &mut SyscallResultAbi<(NonNull<Felt252Abi>, u32, u32)>,
result_ptr: &mut SyscallResultAbi<ArrayAbi<Felt252Abi>>,
ptr: &mut T,
gas: &mut u128,
address: &Felt252Abi,
entry_point_selector: &Felt252Abi,
calldata: *const (*const Felt252Abi, u32, u32),
calldata: &ArrayAbi<Felt252Abi>,
),
storage_read: extern "C" fn(
result_ptr: &mut SyscallResultAbi<Felt252Abi>,
Expand All @@ -651,21 +657,21 @@ pub(crate) mod handler {
result_ptr: &mut SyscallResultAbi<()>,
ptr: &mut T,
gas: &mut u128,
keys: *const (*const Felt252Abi, u32, u32),
data: *const (*const Felt252Abi, u32, u32),
keys: &ArrayAbi<Felt252Abi>,
data: &ArrayAbi<Felt252Abi>,
),
send_message_to_l1: extern "C" fn(
result_ptr: &mut SyscallResultAbi<()>,
ptr: &mut T,
gas: &mut u128,
to_address: &Felt252Abi,
data: *const (*const Felt252Abi, u32, u32),
data: &ArrayAbi<Felt252Abi>,
),
keccak: extern "C" fn(
result_ptr: &mut SyscallResultAbi<U256>,
ptr: &mut T,
gas: &mut u128,
input: *const (*const u64, u32, u32),
input: &ArrayAbi<u64>,
),

secp256k1_new: extern "C" fn(
Expand Down Expand Up @@ -804,15 +810,31 @@ pub(crate) mod handler {
}
}

unsafe fn alloc_mlir_array<E: Clone>(data: &[E]) -> (NonNull<E>, u32, u32) {
let ptr = libc::malloc(Layout::array::<E>(data.len()).unwrap().size()) as *mut E;
unsafe fn alloc_mlir_array<E: Clone>(data: &[E]) -> ArrayAbi<E> {
match data.len() {
0 => ArrayAbi {
ptr: null_mut(),
since: 0,
until: 0,
capacity: 0,
},
_ => {
let ptr =
libc::malloc(Layout::array::<E>(data.len()).unwrap().size()) as *mut E;

let len: u32 = data.len().try_into().unwrap();
for (i, val) in data.iter().enumerate() {
ptr.add(i).write(val.clone());
}
let len: u32 = data.len().try_into().unwrap();
for (i, val) in data.iter().enumerate() {
ptr.add(i).write(val.clone());
}

(NonNull::new(ptr).unwrap(), len, len)
ArrayAbi {
ptr,
since: len,
until: len,
capacity: len,
}
}
}
}

fn wrap_error<E>(e: &[Felt]) -> SyscallResultAbi<E> {
Expand Down Expand Up @@ -1008,12 +1030,12 @@ pub(crate) mod handler {
// TODO: change all from_bytes_be to from_bytes_ne when added and undo byte swapping.

extern "C" fn wrap_deploy(
result_ptr: &mut SyscallResultAbi<(Felt252Abi, (NonNull<Felt252Abi>, u32, u32))>,
result_ptr: &mut SyscallResultAbi<(Felt252Abi, ArrayAbi<Felt252Abi>)>,
ptr: &mut T,
gas: &mut u128,
class_hash: &Felt252Abi,
contract_address_salt: &Felt252Abi,
calldata: *const (*const Felt252Abi, u32, u32),
calldata: &ArrayAbi<Felt252Abi>,
deploy_from_zero: bool,
) {
let class_hash = Felt::from_bytes_be(&{
Expand All @@ -1028,8 +1050,11 @@ pub(crate) mod handler {
});

let calldata: Vec<_> = unsafe {
let len = (*calldata).1 as usize;
std::slice::from_raw_parts((*calldata).0, len)
let since_offset = calldata.since as usize;
let until_offset = calldata.until as usize;
debug_assert!(since_offset <= until_offset);
let len = until_offset - since_offset;
std::slice::from_raw_parts(calldata.ptr.add(since_offset), len)
}
.iter()
.map(|x| {
Expand Down Expand Up @@ -1089,12 +1114,12 @@ pub(crate) mod handler {
}

extern "C" fn wrap_library_call(
result_ptr: &mut SyscallResultAbi<(NonNull<Felt252Abi>, u32, u32)>,
result_ptr: &mut SyscallResultAbi<ArrayAbi<Felt252Abi>>,
ptr: &mut T,
gas: &mut u128,
class_hash: &Felt252Abi,
function_selector: &Felt252Abi,
calldata: *const (*const Felt252Abi, u32, u32),
calldata: &ArrayAbi<Felt252Abi>,
) {
let class_hash = Felt::from_bytes_be(&{
let mut data = class_hash.0;
Expand All @@ -1108,8 +1133,11 @@ pub(crate) mod handler {
});

let calldata: Vec<_> = unsafe {
let len = (*calldata).1 as usize;
std::slice::from_raw_parts((*calldata).0, len)
let since_offset = calldata.since as usize;
let until_offset = calldata.until as usize;
debug_assert!(since_offset <= until_offset);
let len = until_offset - since_offset;
std::slice::from_raw_parts(calldata.ptr.add(since_offset), len)
}
.iter()
.map(|x| {
Expand Down Expand Up @@ -1139,12 +1167,12 @@ pub(crate) mod handler {
}

extern "C" fn wrap_call_contract(
result_ptr: &mut SyscallResultAbi<(NonNull<Felt252Abi>, u32, u32)>,
result_ptr: &mut SyscallResultAbi<ArrayAbi<Felt252Abi>>,
ptr: &mut T,
gas: &mut u128,
address: &Felt252Abi,
entry_point_selector: &Felt252Abi,
calldata: *const (*const Felt252Abi, u32, u32),
calldata: &ArrayAbi<Felt252Abi>,
) {
let address = Felt::from_bytes_be(&{
let mut data = address.0;
Expand All @@ -1158,8 +1186,11 @@ pub(crate) mod handler {
});

let calldata: Vec<_> = unsafe {
let len = (*calldata).1 as usize;
std::slice::from_raw_parts((*calldata).0, len)
let since_offset = calldata.since as usize;
let until_offset = calldata.until as usize;
debug_assert!(since_offset <= until_offset);
let len = until_offset - since_offset;
std::slice::from_raw_parts(calldata.ptr.add(since_offset), len)
}
.iter()
.map(|x| {
Expand Down Expand Up @@ -1248,12 +1279,15 @@ pub(crate) mod handler {
result_ptr: &mut SyscallResultAbi<()>,
ptr: &mut T,
gas: &mut u128,
keys: *const (*const Felt252Abi, u32, u32),
data: *const (*const Felt252Abi, u32, u32),
keys: &ArrayAbi<Felt252Abi>,
data: &ArrayAbi<Felt252Abi>,
) {
let keys: Vec<_> = unsafe {
let len = (*keys).1 as usize;
std::slice::from_raw_parts((*keys).0, len)
let since_offset = keys.since as usize;
let until_offset = keys.until as usize;
debug_assert!(since_offset <= until_offset);
let len = until_offset - since_offset;
std::slice::from_raw_parts(keys.ptr.add(since_offset), len)
}
.iter()
.map(|x| {
Expand All @@ -1266,8 +1300,11 @@ pub(crate) mod handler {
.collect();

let data: Vec<_> = unsafe {
let len = (*data).1 as usize;
std::slice::from_raw_parts((*data).0, len)
let since_offset = data.since as usize;
let until_offset = data.until as usize;
debug_assert!(since_offset <= until_offset);
let len = until_offset - since_offset;
std::slice::from_raw_parts(data.ptr.add(since_offset), len)
}
.iter()
.map(|x| {
Expand Down Expand Up @@ -1297,16 +1334,19 @@ pub(crate) mod handler {
ptr: &mut T,
gas: &mut u128,
to_address: &Felt252Abi,
payload: *const (*const Felt252Abi, u32, u32),
payload: &ArrayAbi<Felt252Abi>,
) {
let to_address = Felt::from_bytes_be(&{
let mut data = to_address.0;
data.reverse();
data
});
let payload: Vec<_> = unsafe {
let len = (*payload).1 as usize;
std::slice::from_raw_parts((*payload).0, len)
let since_offset = payload.since as usize;
let until_offset = payload.until as usize;
debug_assert!(since_offset <= until_offset);
let len = until_offset - since_offset;
std::slice::from_raw_parts(payload.ptr.add(since_offset), len)
}
.iter()
.map(|x| {
Expand Down Expand Up @@ -1335,12 +1375,14 @@ pub(crate) mod handler {
result_ptr: &mut SyscallResultAbi<U256>,
ptr: &mut T,
gas: &mut u128,
input: *const (*const u64, u32, u32),
input: &ArrayAbi<u64>,
) {
let input = unsafe {
let len = (*input).1 as usize;

std::slice::from_raw_parts((*input).0, len)
let since_offset = input.since as usize;
let until_offset = input.until as usize;
debug_assert!(since_offset <= until_offset);
let len = until_offset - since_offset;
std::slice::from_raw_parts(input.ptr.add(since_offset), len)
};

let result = ptr.keccak(input, gas);
Expand Down
1 change: 1 addition & 0 deletions tests/tests/starknet/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
mod keccak;
mod secp256;
mod syscalls;
Loading
Loading