Skip to content

Commit 40527ef

Browse files
feat(apollo_starknet_os_program): add test util to compile and dump specific module
1 parent cdcd9a9 commit 40527ef

File tree

8 files changed

+61
-9
lines changed

8 files changed

+61
-9
lines changed

crates/apollo_infra_utils/src/cairo0_compiler.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,15 @@ pub fn cairo0_compilers_correct_version() -> Result<(), Cairo0CompilerVersionErr
6767

6868
/// Compile a Cairo0 program.
6969
pub fn compile_cairo0_program(
70-
path_to_main: PathBuf,
71-
cairo_root_path: PathBuf,
70+
path_to_main: &PathBuf,
71+
cairo_root_path: &PathBuf,
7272
) -> Result<Vec<u8>, Cairo0CompilerError> {
7373
cairo0_compilers_correct_version()?;
7474
if !path_to_main.exists() {
75-
return Err(Cairo0CompilerError::SourceFileNotFound(path_to_main));
75+
return Err(Cairo0CompilerError::SourceFileNotFound(path_to_main.clone()));
7676
}
7777
if !cairo_root_path.exists() {
78-
return Err(Cairo0CompilerError::CairoRootNotFound(cairo_root_path));
78+
return Err(Cairo0CompilerError::CairoRootNotFound(cairo_root_path.clone()));
7979
}
8080
let mut compile_command = Command::new(CAIRO0_COMPILE);
8181
compile_command.args([

crates/apollo_starknet_os_program/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ description = "The source (Cairo) code of the Starknet OS."
99
[lints]
1010
workspace = true
1111

12+
[features]
13+
testing = []
14+
1215
[dependencies]
1316
apollo_infra_utils.workspace = true
1417
cairo-vm.workspace = true

crates/apollo_starknet_os_program/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn main() {
2424
}
2525

2626
fn compile_program(path_to_main_file: PathBuf) -> Vec<u8> {
27-
match compile_cairo0_program(path_to_main_file, cairo_root_path()) {
27+
match compile_cairo0_program(&path_to_main_file, &cairo_root_path()) {
2828
Ok(bytes) => bytes,
2929
Err(Cairo0CompilerError::Cairo0CompilerVersion(error)) => {
3030
panic!(

crates/apollo_starknet_os_program/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use cairo_vm::types::program::Program;
66
use crate::program_hash::{ProgramHash, PROGRAM_HASH_PATH};
77

88
pub mod program_hash;
9+
#[cfg(any(test, feature = "testing"))]
10+
pub mod test_utils;
911

1012
pub const OS_PROGRAM_BYTES: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/starknet_os_bytes"));
1113
pub const AGGREGATOR_PROGRAM_BYTES: &[u8] =
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use std::path::PathBuf;
2+
3+
use apollo_infra_utils::cairo0_compiler::compile_cairo0_program;
4+
use apollo_infra_utils::compile_time_cargo_manifest_dir;
5+
use cairo_vm::types::program::Program;
6+
7+
// TODO(Dori): Consider sharing this with the same function in this crate's build.rs.
8+
fn cairo_root_path() -> PathBuf {
9+
PathBuf::from(compile_time_cargo_manifest_dir!()).join("src/cairo")
10+
}
11+
12+
pub fn compile_os_module(path_to_module: &PathBuf) -> Vec<u8> {
13+
compile_cairo0_program(&path_to_module, &cairo_root_path())
14+
.unwrap_or_else(|error| panic!("Failed to compile module {path_to_module:?}: {error}."))
15+
}
16+
17+
/// Compiles and deserializes a specific module from the OS, for unit testing.
18+
pub fn compile_os_module_as_program(
19+
path_to_module: &PathBuf,
20+
main_entry_point: Option<&str>,
21+
) -> Program {
22+
Program::from_bytes(&compile_os_module(path_to_module), main_entry_point).unwrap()
23+
}

crates/starknet_committer_and_os_cli/Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ tempfile.workspace = true
1818

1919
# TODO(Amos): Add `testing` feature and move Python test dependencies under it.
2020
[dependencies]
21-
apollo_starknet_os_program.workspace = true
21+
# Activate `testing` feature when the feature exists in this crate.
22+
apollo_starknet_os_program = { workspace = true, features = ["testing"] }
2223
cairo-lang-starknet-classes.workspace = true
23-
cairo-vm.workspace = true # Should be moved under `testing` feature, when it exists.
24+
cairo-vm.workspace = true
2425
clap = { workspace = true, features = ["cargo", "derive"] }
2526
derive_more.workspace = true
2627
ethnum.workspace = true
@@ -33,7 +34,7 @@ serde_repr.workspace = true
3334
starknet-types-core.workspace = true
3435
starknet_api.workspace = true
3536
starknet_committer.workspace = true
36-
# Should be moved under `testing` feature, when it exists.
37+
# Activate `testing` feature when the feature exists in this crate.
3738
starknet_os = { workspace = true, features = ["deserialize", "testing"] }
3839
starknet_patricia = { workspace = true, features = ["testing"] }
3940
starknet_patricia_storage.workspace = true

crates/starknet_committer_and_os_cli/src/os_cli/commands.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::fs;
2-
use std::path::Path;
2+
use std::path::{Path, PathBuf};
33

4+
use apollo_starknet_os_program::test_utils::compile_os_module;
45
use apollo_starknet_os_program::{AGGREGATOR_PROGRAM_BYTES, OS_PROGRAM_BYTES, PROGRAM_HASH};
56
use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass;
67
use cairo_vm::types::layout_name::LayoutName;
@@ -75,6 +76,15 @@ pub fn parse_and_run_os(input_path: String, output_path: String) {
7576
info!("OS program ran successfully.");
7677
}
7778

79+
pub(crate) fn compile_and_dump_module(path_to_module: String, output_path: String) {
80+
// Dumping the `Program` struct won't work - it is not deserializable via cairo-lang's Program
81+
// class. JSONify the raw bytes instead.
82+
let module_bytes = compile_os_module(&PathBuf::from(path_to_module));
83+
let module_json = serde_json::from_slice::<serde_json::Value>(&module_bytes)
84+
.expect("Module bytes are JSON-serializable.");
85+
write_to_file(&output_path, &module_json);
86+
}
87+
7888
pub(crate) fn dump_os_program(output_path: String) {
7989
// Dumping the `Program` struct won't work - it is not deserializable via cairo-lang's Program
8090
// class. JSONify the raw bytes instead.

crates/starknet_committer_and_os_cli/src/os_cli/run_os_cli.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use tracing_subscriber::reload::Handle;
55
use tracing_subscriber::Registry;
66

77
use crate::os_cli::commands::{
8+
compile_and_dump_module,
89
dump_aggregator_program,
910
dump_os_program,
1011
dump_program_hash,
@@ -21,6 +22,15 @@ pub struct OsCliCommand {
2122

2223
#[derive(Debug, Subcommand)]
2324
enum Command {
25+
CompileAndDumpModule {
26+
/// Path to module in the OS program crate.
27+
#[clap(long, short = 'm')]
28+
path_to_module: String,
29+
30+
/// File path to output.
31+
#[clap(long, short = 'o', default_value = "stdout")]
32+
output_path: String,
33+
},
2434
DumpAggregatorProgram {
2535
/// File path to output.
2636
#[clap(long, short = 'o', default_value = "stdout")]
@@ -49,6 +59,9 @@ pub async fn run_os_cli(
4959
) {
5060
info!("Starting starknet-os-cli with command: \n{:?}", os_command);
5161
match os_command.command {
62+
Command::CompileAndDumpModule { path_to_module, output_path } => {
63+
compile_and_dump_module(path_to_module, output_path)
64+
}
5265
Command::DumpAggregatorProgram { output_path } => dump_aggregator_program(output_path),
5366
Command::DumpOsProgram { output_path } => dump_os_program(output_path),
5467
Command::DumpProgramHash { output_path } => dump_program_hash(output_path),

0 commit comments

Comments
 (0)