Skip to content

Commit

Permalink
Daniil/rust-linter-issues-fix (#2030)
Browse files Browse the repository at this point in the history
* slices, for loop copy, min/max update

* append revert

* typo fixed

* linker fixed

* Update versioned constants for Starknet

* Refactor class_hash assignment in cairoVMCall function

* Remove unused code in JunoStateReader

* chore: Refactor class_info_from_json_str function in JunoStateReader.rs

* Refactor extern "C" functions in lib.rs

* Update std::ffi import in versioned_constants.rs

* Refactor extern "C" functions in lib.rs

* Refactor extern "C" functions in lib.rs

* Refactor extern "C" functions in lib.rs

* Refactor error handling in compileSierraToCasm function

* Add err handling

* Refactor error handling in compileSierraToCasm function

* Refactor get_versioned_constants function in lib.rs

* Refactor error handling in compileSierraToCasm function

* Revert diff
  • Loading branch information
AnkushinDaniil authored Aug 13, 2024
1 parent fe8a518 commit 15e4323
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 52 deletions.
7 changes: 6 additions & 1 deletion core/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ use std::{
};

#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn Cairo0ClassHash(class_json_str: *const c_char, hash: *mut c_uchar) {
let class_json = unsafe { CStr::from_ptr(class_json_str) }.to_str().unwrap();
let class_json = unsafe { CStr::from_ptr(class_json_str) };
let class_json = match class_json.to_str() {
Ok(s) => s,
Err(_) => return,
};
let class: Result<LegacyContractClass, serde_json::Error> = serde_json::from_str(class_json);

let class = match class {
Expand Down
44 changes: 25 additions & 19 deletions starknet/compiler.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package starknet

//#include <stdint.h>
//#include <stdlib.h>
//#include <stddef.h>
// extern char* compileSierraToCasm(char* sierra_json);
// extern void freeCstr(char* ptr);
//
// #cgo vm_debug LDFLAGS: -L./rust/target/debug -ljuno_starknet_compiler_rs
// #cgo !vm_debug LDFLAGS: -L./rust/target/release -ljuno_starknet_compiler_rs
/*
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
// Extern function declarations from Rust
extern char compileSierraToCasm(char* sierra_json, char** result);
extern void freeCstr(char* ptr);
// Linker flags for Rust shared library
#cgo vm_debug LDFLAGS: -L./rust/target/debug -ljuno_starknet_compiler_rs
#cgo !vm_debug LDFLAGS: -L./rust/target/release -ljuno_starknet_compiler_rs
*/
import "C"

import (
Expand All @@ -27,20 +32,21 @@ func Compile(sierra *SierraDefinition) (*CompiledClass, error) {
}

sierraJSONCstr := C.CString(string(sierraJSON))
defer func() {
C.free(unsafe.Pointer(sierraJSONCstr))
}()
defer C.free(unsafe.Pointer(sierraJSONCstr))

var result *C.char

success := C.compileSierraToCasm(sierraJSONCstr, &result) == 1 //nolint:gocritic
defer C.freeCstr(result)

if !success {
return nil, errors.New(C.GoString(result))
}

casmJSONOrErrorCstr := C.compileSierraToCasm(sierraJSONCstr)
casmJSONOrError := C.GoString(casmJSONOrErrorCstr)
C.freeCstr(casmJSONOrErrorCstr)
casmJSON := C.GoString(result)

var casmClass CompiledClass
if err = json.Unmarshal([]byte(casmJSONOrError), &casmClass); err != nil {
var syntaxErr *json.SyntaxError
if errors.As(err, &syntaxErr) {
return nil, errors.New(casmJSONOrError)
}
if err := json.Unmarshal([]byte(casmJSON), &casmClass); err != nil {
return nil, err
}

Expand Down
61 changes: 44 additions & 17 deletions starknet/rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,61 @@
use std::ffi::{c_char, CStr, CString};
use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass;
use std::ffi::{c_char, CStr, CString};

#[no_mangle]
pub extern "C" fn compileSierraToCasm(sierra_json: *const c_char) -> *mut c_char {
let sierra_json_str = unsafe { CStr::from_ptr(sierra_json) }.to_str().unwrap();
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn compileSierraToCasm(sierra_json: *const c_char, result: *mut *mut c_char) -> u8 {
let sierra_json_str = match unsafe { CStr::from_ptr(sierra_json) }.to_str() {
Ok(value) => value,
Err(e) => {
unsafe {
*result = raw_cstr(e.to_string());
}
return 0;
}
};

let sierra_class =
serde_json::from_str(sierra_json_str).map_err(|err| err.to_string());
if let Err(e) = sierra_class {
return raw_cstr(e)
}
let sierra_class = match serde_json::from_str(sierra_json_str) {
Ok(value) => value,
Err(e) => {
unsafe {
*result = raw_cstr(e.to_string());
}
return 0;
}
};

let casm_class = CasmContractClass::from_contract_class(sierra_class.unwrap(), true, usize::MAX)
.map_err(|err| err.to_string());
if let Err(e) = casm_class {
return raw_cstr(e)
}
let casm_class = match CasmContractClass::from_contract_class(sierra_class, true, usize::MAX) {
Ok(value) => value,
Err(e) => {
unsafe {
*result = raw_cstr(e.to_string());
}
return 0;
}
};

let casm_json = serde_json::to_string(&casm_class.unwrap());
if let Err(e) = casm_json {
return raw_cstr(e.to_string())
let casm_json = match serde_json::to_string(&casm_class) {
Ok(value) => value,
Err(e) => {
unsafe {
*result = raw_cstr(e.to_string());
}
return 0;
}
};

unsafe {
*result = raw_cstr(casm_json);
}
return raw_cstr(casm_json.unwrap())
1
}

fn raw_cstr(str: String) -> *mut c_char {
CString::new(str).unwrap().into_raw()
}

#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn freeCstr(ptr: *mut c_char) {
unsafe {
if ptr.is_null() {
Expand Down
8 changes: 3 additions & 5 deletions vm/rust/src/juno_state_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,6 @@ impl UpdatableState for JunoStateReader {

pub fn felt_to_byte_array(felt: &StarkFelt) -> [u8; 32] {
felt.to_bytes_be()
.try_into()
.expect("StarkFelt not [u8; 32]")
}

pub fn ptr_to_felt(bytes: *const c_uchar) -> StarkFelt {
Expand Down Expand Up @@ -218,10 +216,10 @@ pub fn class_info_from_json_str(raw_json: &str) -> Result<BlockifierClassInfo, S
} else {
return Err("not a valid contract class".to_string());
};
return Ok(BlockifierClassInfo::new(
&class.into(),
Ok(BlockifierClassInfo::new(
&class,
class_info.sierra_program_length,
class_info.abi_length,
)
.unwrap());
.unwrap())
}
23 changes: 16 additions & 7 deletions vm/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ pub struct BlockInfo {
}

#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn cairoVMCall(
call_info_ptr: *const CallInfo,
block_info_ptr: *const BlockInfo,
Expand Down Expand Up @@ -126,7 +127,7 @@ pub extern "C" fn cairoVMCall(
calldata: Calldata(calldata_vec.into()),
storage_address: contract_addr_felt.try_into().unwrap(),
call_type: CallType::Call,
class_hash: class_hash,
class_hash,
code_address: None,
caller_address: ContractAddress::default(),
initial_gas: get_versioned_constants(block_info.version).tx_initial_gas(),
Expand Down Expand Up @@ -172,6 +173,7 @@ pub struct TxnAndQueryBit {
}

#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn cairoVMExecute(
txns_json: *const c_char,
classes_json: *const c_char,
Expand Down Expand Up @@ -527,17 +529,22 @@ lazy_static! {

#[allow(static_mut_refs)]
fn get_versioned_constants(version: *const c_char) -> VersionedConstants {
let version_str = unsafe { CStr::from_ptr(version) }.to_str().unwrap();
let version = StarknetVersion::from_str(&version_str)
.unwrap_or(StarknetVersion::from_str(&"0.0.0").unwrap());
let version_str = unsafe { CStr::from_ptr(version) }
.to_str()
.unwrap_or("0.0.0");

let version = match StarknetVersion::from_str(version_str) {
Ok(v) => v,
Err(_) => StarknetVersion::from_str("0.0.0").unwrap(),
};

if let Some(constants) = unsafe { &CUSTOM_VERSIONED_CONSTANTS } {
constants.clone()
} else if version < StarknetVersion::from_str(&"0.13.1").unwrap() {
} else if version < StarknetVersion::from_str("0.13.1").unwrap() {
CONSTANTS.get(&"0.13.0".to_string()).unwrap().to_owned()
} else if version < StarknetVersion::from_str(&"0.13.1.1").unwrap() {
} else if version < StarknetVersion::from_str("0.13.1.1").unwrap() {
CONSTANTS.get(&"0.13.1".to_string()).unwrap().to_owned()
} else if version < StarknetVersion::from_str(&"0.13.2").unwrap() {
} else if version < StarknetVersion::from_str("0.13.2").unwrap() {
CONSTANTS.get(&"0.13.1.1".to_string()).unwrap().to_owned()
} else {
VersionedConstants::latest_constants().to_owned()
Expand Down Expand Up @@ -580,6 +587,7 @@ impl FromStr for StarknetVersion {
static mut CUSTOM_VERSIONED_CONSTANTS: Option<VersionedConstants> = None;

#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn setVersionedConstants(json_bytes: *const c_char) -> *const c_char {
let json_str = unsafe {
match CStr::from_ptr(json_bytes).to_str() {
Expand All @@ -602,6 +610,7 @@ pub extern "C" fn setVersionedConstants(json_bytes: *const c_char) -> *const c_c
}

#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn freeString(s: *mut c_char) {
if !s.is_null() {
unsafe {
Expand Down
4 changes: 1 addition & 3 deletions vm/rust/src/versioned_constants.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use blockifier::versioned_constants::VersionedConstants;
use std::{
ffi::{c_char, c_uchar, c_void, CStr}
}
use std::ffi::{c_char, c_uchar, c_void, CStr}

0 comments on commit 15e4323

Please sign in to comment.