-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add util starknet-sierra-compile
- Loading branch information
1 parent
f39ef95
commit 535a9fc
Showing
8 changed files
with
1,416 additions
and
1 deletion.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[package] | ||
name = "starknet_sierra_compile" | ||
version.workspace = true | ||
edition.workspace = true | ||
repository.workspace = true | ||
license.workspace = true | ||
|
||
[lints] | ||
workspace = true | ||
|
||
[dependencies] | ||
cairo-lang-sierra.workspace = true | ||
cairo-lang-starknet-classes.workspace = true | ||
cairo-lang-utils.workspace = true | ||
serde_json.workspace = true | ||
serde.workspace = true | ||
thiserror.workspace = true | ||
tokio.workspace = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
use cairo_lang_starknet_classes::allowed_libfuncs::{AllowedLibfuncsError, ListSelector}; | ||
use cairo_lang_starknet_classes::casm_contract_class::{ | ||
CasmContractClass, StarknetSierraCompilationError, | ||
}; | ||
use cairo_lang_starknet_classes::contract_class::ContractClass; | ||
use thiserror::Error; | ||
use tokio::task::JoinError; | ||
|
||
#[cfg(test)] | ||
#[path = "compile_test.rs"] | ||
pub mod compile_test; | ||
|
||
pub struct SierraToCasmCompliationArgs { | ||
allowed_libfuncs_list_name: Option<String>, | ||
allowed_libfuncs_list_file: Option<String>, | ||
add_pythonic_hints: bool, | ||
max_bytecode_size: usize, | ||
} | ||
|
||
#[derive(Debug, Error)] | ||
pub enum CompilationUtilError { | ||
#[error(transparent)] | ||
AllowedLibfuncsError(#[from] AllowedLibfuncsError), | ||
#[error("Both allowed libfuncs list name and file were supplied.")] | ||
AllowedLibfuncsListSource, | ||
#[error(transparent)] | ||
JoinError(#[from] JoinError), | ||
#[error(transparent)] | ||
StarknetSierraCompilationError(#[from] StarknetSierraCompilationError), | ||
} | ||
|
||
pub async fn compile_sierra_to_casm( | ||
contract_class: ContractClass, | ||
) -> Result<CasmContractClass, CompilationUtilError> { | ||
let compilation_args = SierraToCasmCompliationArgs { | ||
allowed_libfuncs_list_name: None, | ||
allowed_libfuncs_list_file: None, | ||
add_pythonic_hints: true, | ||
max_bytecode_size: 1000000, | ||
}; | ||
|
||
// TODO(task_executor). | ||
tokio::task::spawn_blocking(move || starknet_sierra_compile(compilation_args, contract_class)) | ||
.await? | ||
} | ||
|
||
fn starknet_sierra_compile( | ||
compilation_args: SierraToCasmCompliationArgs, | ||
contract_class: ContractClass, | ||
) -> Result<CasmContractClass, CompilationUtilError> { | ||
let list_selector = ListSelector::new( | ||
compilation_args.allowed_libfuncs_list_name, | ||
compilation_args.allowed_libfuncs_list_file, | ||
) | ||
.ok_or(CompilationUtilError::AllowedLibfuncsListSource)?; | ||
contract_class.validate_version_compatible(list_selector)?; | ||
|
||
Ok(CasmContractClass::from_contract_class( | ||
contract_class, | ||
compilation_args.add_pythonic_hints, | ||
compilation_args.max_bytecode_size, | ||
)?) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
use std::path::Path; | ||
|
||
use cairo_lang_starknet_classes::allowed_libfuncs::AllowedLibfuncsError; | ||
use cairo_lang_starknet_classes::contract_class::ContractClass; | ||
|
||
use crate::compile::{compile_sierra_to_casm, CompilationUtilError}; | ||
use crate::test_utils::contract_class_from_file; | ||
|
||
const FAULTY_ACCOUNT_SIERRA_FILE: &str = "account_faulty.sierra.json"; | ||
const TEST_FILES_FOLDER: &str = "./tests/fixtures"; | ||
|
||
#[tokio::test] | ||
async fn test_compile_sierra_to_casm() { | ||
let sierra_path = &Path::new(TEST_FILES_FOLDER).join(FAULTY_ACCOUNT_SIERRA_FILE); | ||
let expected_casm_contract_length = 72304; | ||
|
||
let contract_class = contract_class_from_file(sierra_path); | ||
let casm_contract = compile_sierra_to_casm(contract_class).await.unwrap(); | ||
let serialized_casm = serde_json::to_string_pretty(&casm_contract).unwrap().into_bytes(); | ||
|
||
assert_eq!(serialized_casm.len(), expected_casm_contract_length); | ||
} | ||
|
||
// TODO(Arni, 1/5/2024): Add a test for panic result test. | ||
#[tokio::test] | ||
async fn test_negative_flow_compile_sierra_to_casm() { | ||
let sierra_path = &Path::new(TEST_FILES_FOLDER).join(FAULTY_ACCOUNT_SIERRA_FILE); | ||
|
||
let contract_class = contract_class_from_file(sierra_path); | ||
let ContractClass { | ||
sierra_program, | ||
sierra_program_debug_info, | ||
contract_class_version, | ||
entry_points_by_type, | ||
abi, | ||
} = contract_class; | ||
|
||
let faulty_sierra_program = sierra_program[..100].to_vec(); | ||
let faulty_contract_class = ContractClass { | ||
sierra_program: faulty_sierra_program, | ||
sierra_program_debug_info, | ||
contract_class_version, | ||
entry_points_by_type, | ||
abi, | ||
}; | ||
let result = compile_sierra_to_casm(faulty_contract_class).await; | ||
if let CompilationUtilError::AllowedLibfuncsError(AllowedLibfuncsError::SierraProgramError) = | ||
result.unwrap_err() | ||
{ | ||
return; | ||
} else { | ||
panic!("Unexpected error.") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
pub mod compile; | ||
|
||
#[cfg(any(feature = "testing", test))] | ||
pub mod test_utils; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use std::fs; | ||
use std::path::Path; | ||
|
||
use cairo_lang_starknet_classes::contract_class::{ContractClass, ContractEntryPoints}; | ||
use cairo_lang_utils::bigint::BigUintAsHex; | ||
use serde::Deserialize; | ||
|
||
/// See: https://github.com/starkware-libs/cairo/blob/d0c0f175a8855242d8c6265c55d3f97f8dfdce40/crates/bin/starknet-sierra-compile/src/main.rs#L34-L43 | ||
/// Same as `ContractClass` - but ignores `abi` in deserialization. | ||
/// Enables loading old contract classes. | ||
#[derive(Deserialize)] | ||
struct ContractClassIgnoreAbi { | ||
pub sierra_program: Vec<BigUintAsHex>, | ||
pub sierra_program_debug_info: Option<cairo_lang_sierra::debug_info::DebugInfo>, | ||
pub contract_class_version: String, | ||
pub entry_points_by_type: ContractEntryPoints, | ||
pub _abi: Option<serde_json::Value>, | ||
} | ||
|
||
pub(crate) fn contract_class_from_file(file: &Path) -> ContractClass { | ||
let ContractClassIgnoreAbi { | ||
sierra_program, | ||
sierra_program_debug_info, | ||
contract_class_version, | ||
entry_points_by_type, | ||
_abi, | ||
} = serde_json::from_str(&fs::read_to_string(file).expect("Failed to read input file.")) | ||
.expect("deserialization Failed."); | ||
|
||
ContractClass { | ||
sierra_program, | ||
sierra_program_debug_info, | ||
contract_class_version, | ||
entry_points_by_type, | ||
abi: None, | ||
} | ||
} |
Oops, something went wrong.